home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************\
- * PC2.c *
- * Copyright (C) by Stangl Roman, 1993, 1994, 1995 *
- * This Code may be freely distributed, provided the Copyright isn't *
- * removed, under the conditions indicated in the documentation. *
- * *
- * Utility.c General functions that are not window procedures. *
- * *
- \***********************************************************************/
-
- static char RCSID[]="@(#) $Header: Utility.c Version 1.90 05,1995 $ (LBL)";
-
- #define _FILE_ "PC/2 - Utility.c V1.90"
-
- #define INCL_DOSDEVICES
-
- #include "PC2.h" /* User include files */
- #include "Error.h"
- #ifndef __EMX__
- #include <bsedev.h>
- #endif /* __EMX__ */
-
- #ifdef __EMX__ /* For compiling with EMX C/C++ Rolf Knebel suggested
- to define constants not defined by the EMX package */
- #define IOCTL_DISK 0x08
- #define DSK_BLOCKREMOVABLE 0x20
- /* Thanks to Roland Emmerich for testing EMX and GCC
- compatibility */
- define DosSetPrty DosSetPriority
- #endif /* __EMX__ */
- /* IOCTL constants missing in BSEDEV.H ? */
- #define IOCTL_DRIVEANDDISK 0x80
- #define IOCTL_CHARDEVICE 0x82
- #define DSK_DEVICESTATUS 0x60
-
- typedef struct _SESSIONTYPE SESSIONTYPE;
- typedef struct _PGMCONTROL PGMCONTROL;
-
- struct _SESSIONTYPE /* Structure to convert binary SessionTypes to ASCII and
- vice versa */
- {
- USHORT usSessionType; /* Binary PROG_* values */
- UCHAR *pucSessionType; /* ASCII PROG_* strings */
- };
-
- SESSIONTYPE SessionType[]= /* Map 1.80 session types to 1.90 when reading PC2.CFG */
- {
- { 1, "PROG_FULLSCREEN"},
- { 2, "PROG_WINDOWABLEVIO"},
- { 3, "PROG_PM"},
- { 4, "PROG_VDM"},
- { 7, "PROG_WINDOWEDVDM"},
- {10, "PROG_WINDOW_REAL"},
- {11, "PROG_WINDOW_PROT"},
- {16, "PROG_31_STDSEAMLESSCOMMON"},
- {18, "PROG_31_ENHSEAMLESSCOMMON"},
- {19, "PROG_31_ENH"},
- {21, "PROG_WPSOBJECT"}
- };
-
- #define SESSIONTYPESIZE (sizeof(SessionType)/sizeof(SessionType[0]))
-
- struct _PGMCONTROL /* Structure to convert bitmapped PgmControl style to ASCII and
- vice versa */
- {
- USHORT usPgmControl; /* Bitmapped SSF_* values */
- UCHAR *pucPgmControl; /* ASCII SSF_* strings */
- };
-
- PGMCONTROL PgmControl[]=
- {
- {0x0000, "SSF_CONTROL_VISIBLE"},
- {0x0001, "SSF_CONTROL_INVISIBLE"},
- {0x0002, "SSF_CONTROL_MAXIMIZE"},
- {0x0004, "SSF_CONTROL_MINIMIZE"},
- {0x0008, "SSF_CONTROL_NOAUTOCLOSE"},
- {0x4000, "SSF_CONTROL_AUTOSTART"},
- {0x8000, "SSF_CONTROL_SETPOS"}
- };
-
- #define PGMCONTROLSIZE (sizeof(PgmControl)/sizeof(PgmControl[0]))
-
- /*--------------------------------------------------------------------------------------*\
- * Procedure to initialize a window and its message queue. *
- * Req: *
- * pHab .......... A pointer to be filled with the anchor block of the window *
- * pHmq .......... A pointer to be filled with the message queue of the window *
- * Returns: *
- * TRUE/FALSE .... If called sucessfully/unsucessfully *
- \*--------------------------------------------------------------------------------------*/
- BOOL WinStartUp(HAB *pHab, HMQ *pHmq)
- {
- /* Initialize handle of anchor block */
- if((*pHab=WinInitialize(0))==NULLHANDLE)
- return(FALSE);
- /* Initialize handle of message queue */
- if((*pHmq=WinCreateMsgQueue(*pHab, 50))==NULLHANDLE)
- return(FALSE);
- return(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * Procedure to initialize HELP. *
- * Req: *
- * hab ........... Anchor block handle *
- * pHelpFile ..... A pointer to helppanel filename, located in PC/2's directory *
- * pHwndHelp ..... A pointer to a HWND structure *
- * pHwndFrame .... Frame window handle to associate help with *
- * Returns: *
- * pHwndHelp ..... If called sucessfully/unsucessfully hwnd/NULL *
- \*--------------------------------------------------------------------------------------*/
- BOOL WinStartHelp(HAB hab, UCHAR *pHelpFile, HWND *pHwndHelp, HWND HwndFrame)
- {
- HELPINIT HelpInit;
-
- HelpInit.cb=sizeof(HELPINIT); /* Size of HELPINIT structure */
- HelpInit.ulReturnCode=0; /* Returnvalue from HelpManager */
- HelpInit.pszTutorialName=NULL; /* No tutorial */
- /* Ressource of Helptable */
- HelpInit.phtHelpTable=(PHELPTABLE)MAKEULONG(MAIN_HELP_TABLE, 0xffff);
- /* Ressource in .EXE */
- HelpInit.hmodHelpTableModule=NULLHANDLE;
- /* No handle */
- HelpInit.hmodAccelActionBarModule=NULLHANDLE;
- HelpInit.idAccelTable=0; /* None */
- HelpInit.idActionBar=0; /* None */
- /* Window title of help window */
- HelpInit.pszHelpWindowTitle="PC/2 - Program Commander/2 Help";
- HelpInit.pszHelpLibraryName=pHelpFile; /* Library name of help panel via PC/2 directory */
- HelpInit.fShowPanelId=0; /* Panel ID not displayed */
- /* *\
- * First assume PC2.HLP where the fully qualified path passed here points to, which is *
- * the directory PC/2 started from. *
- \* */
- *pHwndHelp=WinCreateHelpInstance( /* Create help */
- hab, /* Anchor block */
- &HelpInit);
- /* Test for successful help creation */
- if((*pHwndHelp) && (!HelpInit.ulReturnCode))
- /* Associate HELP with frame window */
- if(WinAssociateHelpInstance(*pHwndHelp, HwndFrame)!=FALSE)
- return(TRUE);
- /* *\
- * Second assume PC2.HLP in a directory pointed to by the HELP environment variable, *
- * and try to create it from there. *
- \* */
- HelpInit.ulReturnCode=0; /* Returnvalue from HelpManager */
- HelpInit.pszHelpLibraryName="PC2.HLP"; /* Library name of help panel via HELP path */
- *pHwndHelp=WinCreateHelpInstance(hab, &HelpInit);
- if((*pHwndHelp) && (!HelpInit.ulReturnCode))
- if(WinAssociateHelpInstance(*pHwndHelp, HwndFrame)!=FALSE)
- return(TRUE);
- *pHwndHelp=NULLHANDLE;
- return(FALSE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * Procedure to close a window and its message queue. *
- * Req: *
- * pHwndHelp ..... A pointer to HELP window handle *
- * pHab .......... A pointer to extract the anchor block of the window *
- * pHmq .......... A pointer to extract message queue of the window *
- * Returns: *
- * TRUE/FALSE .... If called sucessfully/unsucessfully *
- \*--------------------------------------------------------------------------------------*/
- BOOL WinCloseDown(HWND *pHwndHelp, HAB *pHab, HMQ *pHmq)
- {
- if(!*pHwndHelp) /* Release HELP */
- WinDestroyHelpInstance(*pHwndHelp);
- if(*pHmq!=NULLHANDLE) /* Release handle of message queue */
- WinDestroyMsgQueue(*pHmq);
- if(*pHab!=NULLHANDLE) /* Release handle of anchor block */
- WinTerminate(*pHab);
- /* Any error during WinStartUp */
- if((*pHab==NULLHANDLE) || (*pHmq==NULLHANDLE)) return(FALSE);
- else return(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * Allocate a storage area that contains the environment of PC/2 inclusive additions/ *
- * replacements made from the data entered in the Envrionment notebook page. *
- * Req: *
- * PgmEnvironment A pointer to the user entered Environment in the form of: *
- * EnvVar1=Value1\r\nEnvVar2=Value2\r\n...\0 *
- * pib_pchenv The entry from PC/2's process information block, which has the *
- * same form as the returned composite environment pucEnvironment. *
- * Returns: *
- * pucEnvironment A pointer to the Environment to inherit from PC/2, which must *
- * be freed after the session was started, in the form of: *
- * EnvVar1=Value1\0EnvVar2=Value2\0...EnvVarn=Valuen\0\0 *
- \*--------------------------------------------------------------------------------------*/
- UCHAR *CreateEnvironment(PSZ PgmEnvironment)
- {
- UCHAR *pucEnvironment; /* Merge of PC/2's and user added/replaced environment */
- UCHAR *pucEnvironmentEntry; /* Pointer within pucEnvironment to add next entry */
- UCHAR **ppucEnvironment; /* Temporary table containing all EnvironmentVariable=Value */
- UCHAR **ppucEnvironmentEntry; /* Pointer within ppucEnvironment to add next entry
- entry pointers */
- ULONG ulEnvironmentSize; /* Number of bytes required for all EnvironmentVariable=Value
- strings that get inherited by PC/2 */
- ULONG ulEnvironmentEntries; /* Number of EnvironmentVariable=Value entries that are
- to be returned in pucEnvironment at maximum */
- UCHAR *pucPC2EnvironmentEntry; /* Pointer to an entry in PC/2's environment */
- UCHAR *pucUserEnvironmentEntry; /* Pointer to an EnvironmentVariable in user's environment
- additions/replacements */
- UCHAR *pucUserEnvironmentEntryValue; /* Pointer to an Value in user's environment additions/replacements */
- UCHAR *pucTemp;
-
-
- /* PC/2's environment in the process information block
- is separated by \0, and terminated by \0\0 */
- /* Note: During testing the condition of the for-loop, we
- assume that when pucPC2EnvironmentEntry is not true,
- *pucPC2EnvironmentEntry is not evaluated, which would
- be typically for modern compilers */
- for(ulEnvironmentEntries=0, ulEnvironmentSize=sizeof('\0'), pucPC2EnvironmentEntry=(UCHAR *)pHP->pPib->pib_pchenv;
- (pucPC2EnvironmentEntry && *pucPC2EnvironmentEntry);
- ulEnvironmentEntries++, pucPC2EnvironmentEntry=strchr(pucPC2EnvironmentEntry, '\0'),
- (pucPC2EnvironmentEntry ? pucPC2EnvironmentEntry++ : pucPC2EnvironmentEntry))
- {
- ulEnvironmentSize+=strlen(pucPC2EnvironmentEntry);
- }
- /* Count entries of user's environment additions/replacements */
- for(pucUserEnvironmentEntry=PgmEnvironment;
- pucUserEnvironmentEntry;
- ulEnvironmentEntries++, pucUserEnvironmentEntry=strstr(pucUserEnvironmentEntry, "\r\n"),
- (pucUserEnvironmentEntry ? pucUserEnvironmentEntry+=2 : pucUserEnvironmentEntry))
- {
- pucTemp=strstr(pucUserEnvironmentEntry, "\r\n");
- if(pucTemp) ulEnvironmentSize+=(pucTemp-pucUserEnvironmentEntry+1);
- }
- /* Allocate the temporary table to merge PC/2's and
- user entered environment entries */
- ppucEnvironment=ppucEnvironmentEntry=(UCHAR **)malloc(ulEnvironmentEntries*sizeof(UCHAR *));
- /* Copy PC/2's environment into temporary table, from which
- additional user environment entries will be added or
- existing one will be replaced */
- for(pucPC2EnvironmentEntry=pHP->pPib->pib_pchenv;
- (pucPC2EnvironmentEntry && *pucPC2EnvironmentEntry);
- pucPC2EnvironmentEntry=strchr(pucPC2EnvironmentEntry, '\0'),
- (pucPC2EnvironmentEntry ? pucPC2EnvironmentEntry++ : pucPC2EnvironmentEntry))
- {
- *ppucEnvironmentEntry=strdup(pucPC2EnvironmentEntry);
- *(++ppucEnvironmentEntry)=NULL;
- }
- /* Now add user environment entries which can't be found
- in PC/2's environment at the bottom of the temporary table
- or replace matching entries */
- for(pucUserEnvironmentEntry=PgmEnvironment;
- (pucUserEnvironmentEntry && *pucUserEnvironmentEntry);
- pucUserEnvironmentEntry=strstr(pucUserEnvironmentEntry, "\r\n"),
- (pucUserEnvironmentEntry ? pucUserEnvironmentEntry+=2 : pucUserEnvironmentEntry))
- {
- ULONG ulUserEnvironmentEntrySize;
- ULONG ulUserEnvironmentVariableSize;
-
- ulUserEnvironmentEntrySize=ulUserEnvironmentVariableSize=0;
- /* Get the length of current EnvironmentVariable=Value
- entry in user environment */
- pucTemp=strstr(pucUserEnvironmentEntry, "\r\n");
- if(pucTemp) ulUserEnvironmentEntrySize=pucTemp-pucUserEnvironmentEntry;
- /* Get the length of current EnvironmentVariable in user
- environment */
- pucTemp=strstr(pucUserEnvironmentEntry, "=");
- if(pucTemp) ulUserEnvironmentVariableSize=pucTemp-pucUserEnvironmentEntry;
- pucUserEnvironmentEntryValue=pucTemp+1;
- /* Now test for EnvironmentVariables named BEGINLIBPATH and
- ENDLIBPATH. It these are found, than they are not added
- to the environment, but DosSetExtLIBPATH are called
- to write them into PC/2's process information block
- to inherit them. Both are not environment variables, CMD.EXE
- and PC/2 just treat them this way because the user
- should set them consistent with environment variables for
- simplicity */
- if((strstr(pucUserEnvironmentEntry, "BEGINLIBPATH=")) ||
- (strstr(pucUserEnvironmentEntry, "ENDLIBPATH=")))
- {
- UCHAR ucDynamicLibPath[LENENVENTRY];
-
-
- memset(ucDynamicLibPath, '\0', sizeof(ucDynamicLibPath));
- strncpy(ucDynamicLibPath, pucUserEnvironmentEntryValue,
- ulUserEnvironmentEntrySize-ulUserEnvironmentVariableSize-1);
- if(strstr(pucUserEnvironmentEntry, "BEGINLIBPATH="))
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH(ucDynamicLibPath, BEGINLIBPATH);
- if(strstr(pucUserEnvironmentEntry, "ENDLIBPATH="))
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH(ucDynamicLibPath, ENDLIBPATH);
- continue; /* We don't set them into the environment */
- }
- /* Now try to locate the EnvironmentVariable just found
- in PC/2's environment. If it is found replace it, otherwise
- add it at the bottom of the temporary table */
- for(ppucEnvironmentEntry=ppucEnvironment; *ppucEnvironmentEntry; ppucEnvironmentEntry++)
- {
- /* Is the current user EnvironmentVariable the current
- EnvironmentVariable of PC/2's environment iterated.
- We compare the strings EnvironmentVariable= including
- "=", because otherwise we could match substrings too */
- if(strncmp(*ppucEnvironmentEntry, pucUserEnvironmentEntry, ulUserEnvironmentVariableSize+1)==0)
- {
- /* We also accept %EnvironmentVariable% in the value of the
- current user EnvironmentVariable */
- UCHAR ucCompositeEnvironmentEntry[LENENVENTRY];
-
- /* Create a temporary %EnvrionmentVariable% string to search
- the Value string of the user EnvironmentVariable */
- memset(ucCompositeEnvironmentEntry, '\0', sizeof(ucCompositeEnvironmentEntry));
- strcpy(ucCompositeEnvironmentEntry, "%");
- strncpy(&ucCompositeEnvironmentEntry[1], pucUserEnvironmentEntry, ulUserEnvironmentVariableSize);
- strcat(ucCompositeEnvironmentEntry, "%");
- if((pucTemp=strstr(pucUserEnvironmentEntryValue, ucCompositeEnvironmentEntry))!=NULL)
- { /* We found a %EnvironmentVariable% so concatenate it */
- UCHAR *pucRealloc;
-
- memset(ucCompositeEnvironmentEntry, '\0', sizeof(ucCompositeEnvironmentEntry));
- /* First add all up to %EnvironmentVariable% from user entry */
- strncpy(ucCompositeEnvironmentEntry, pucUserEnvironmentEntry, pucTemp-pucUserEnvironmentEntry);
- pucRealloc=strchr(*ppucEnvironmentEntry, '=');
- if(pucRealloc)
- strcat(ucCompositeEnvironmentEntry, ++pucRealloc);
- /* Add all after %EnvironmentVariable% from user entry (but
- subtract out both "%" signs */
- strncat(ucCompositeEnvironmentEntry, pucTemp+ulUserEnvironmentVariableSize+2,
- ulUserEnvironmentEntrySize-(pucTemp-pucUserEnvironmentEntry)-ulUserEnvironmentVariableSize-2);
- free(*ppucEnvironmentEntry);
- *ppucEnvironmentEntry=(UCHAR *)malloc(strlen(ucCompositeEnvironmentEntry+1));
- strcpy(*ppucEnvironmentEntry, ucCompositeEnvironmentEntry);
- }
- else
- {
- /* We found the environment variable in PC/2's environment,
- so replace it */
- free(*ppucEnvironmentEntry);
- *ppucEnvironmentEntry=(UCHAR *)malloc(ulUserEnvironmentEntrySize+1);
- memset(*ppucEnvironmentEntry, '\0', ulUserEnvironmentEntrySize+1);
- strncpy(*ppucEnvironmentEntry, pucUserEnvironmentEntry, ulUserEnvironmentEntrySize);
- }
- break;
- }
- }
- /* We didn't find the environment variable in PC/2's environment,
- so add it at the bottom of the temporary table */
- if(!*ppucEnvironmentEntry)
- {
- *ppucEnvironmentEntry=(UCHAR *)malloc(ulUserEnvironmentEntrySize+1);
- memset(*ppucEnvironmentEntry, '\0', ulUserEnvironmentEntrySize+1);
- strncpy(*ppucEnvironmentEntry, pucUserEnvironmentEntry, ulUserEnvironmentEntrySize);
- *(++ppucEnvironmentEntry)=NULL;
- }
- }
-
- /* Allocate environment to inherit to session being
- started and reserve for terminating \0\0 */
- pucEnvironment=pucEnvironmentEntry=(UCHAR *)malloc(ulEnvironmentSize+2);
- memset(pucEnvironment, '\x5a', ulEnvironmentSize);
- /* Now copy new Environment from table into a flat
- strings terminating an entry with \0 and all entries
- with \0\0 and free the table entries */
- for(ppucEnvironmentEntry=ppucEnvironment; *ppucEnvironmentEntry; ppucEnvironmentEntry++)
- {
- ULONG ulLength;
-
- ulLength=strlen(*ppucEnvironmentEntry)+1;
- strcpy(pucEnvironmentEntry, *ppucEnvironmentEntry);
- pucEnvironmentEntry+=ulLength;
- /* Free table entry */
- free(*ppucEnvironmentEntry);
- }
- /* Add \0\0 because this terminates the whole Environment */
- *pucEnvironmentEntry='\0';
- *(pucEnvironmentEntry+1)='\0';
- /* Free table of entries */
- free(ppucEnvironment);
- /* Return the Environment which comsists of PC/2's with
- additions/replacement from the user */
- return(pucEnvironment);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * A SESSIONDATA data structure is used to extract the parameters to start a new *
- * session. If sucessfull, additional parameters are extracted to set the priority of *
- * the new session. *
- * Req: A SessionData structure to start session from *
- \*--------------------------------------------------------------------------------------*/
- void StartSession(SESSIONDATA *pSessionData)
- {
- UCHAR ucMessageBuffer[513];
- UCHAR ucPgmTitle[EF_SIZE255+1];
- UCHAR *pucDestination, *pucSource;
- UCHAR ucPgmInputs[EF_SIZE255+1];
- /* If DosStartSession() fails, display current directory */
- ULONG ulCurrentDrive; /* Current drive (1=A, 2=B, ...) */
- ULONG ulLogicalDriveMap; /* Bitmap of available drives (Bit 0=A, 1=B, ...) */
- UCHAR ucCurrentDirectory[CCHMAXPATH];
- ULONG ulCurrentDirectoryLen=sizeof(ucCurrentDirectory);
- STARTDATA StartData; /* Control structure for DosStartSession() */
- PROGDETAILS ProgDetails; /* Control structure for WinStartApp() */
- ULONG SessID;
- PID Pid;
- APIRET rc;
-
- /* *\
- * Change to the root directory of all non-removable drives when a drive was added or *
- * removed since last change to all drives root directory. *
- \* */
-
- /* Query drive bit map */
- DosQueryCurrentDisk(&ulCurrentDrive, &ulLogicalDriveMap);
- /* If drive map changed query drives and change to root
- directories */
- if(pHP->ulLogicalDriveMap!=ulLogicalDriveMap)
- SetDriveRoot();
- /* *\
- * Test for x:(...] where x is a drive and set the current working directory to this *
- * drive. *
- \* */
- if((strlen(pSessionData->PgmDirectory)>=2)
- && (pSessionData->PgmDirectory[1]==':'))
- {
- UCHAR ucDrive;
- /* Then get drive letter (only if one's there */
- ucDrive=tolower(pSessionData->PgmDirectory[0]);
- /* 1=A, 2=B, 3=C,... */
- rc=DosSetDefaultDisk(++ucDrive-'a');
- if(rc!=NO_ERROR)
- {
- sprintf(ucMessageBuffer, "Can't change into the directory %s to invoke %s - continuing...",
- pSessionData->PgmDirectory, pSessionData->PgmTitle);
- DOS_ERR(rc, pHP->hwndFrame, HELP_SETPATH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- /* *\
- * Test for a directory and set the current working directory to it, if one exists, *
- * set to root directory. *
- \* */
- if(strlen(pSessionData->PgmDirectory)>2)
- { /* Only if there's one */
- rc=DosSetCurrentDir(pSessionData->PgmDirectory);
- if(rc!=NO_ERROR)
- {
- sprintf(ucMessageBuffer, "Can't change into the directory %s to invoke %s - continuing...",
- pSessionData->PgmDirectory, pSessionData->PgmTitle);
- DOS_ERR(rc, pHP->hwndFrame, HELP_SETPATH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- else
- { /* Set to root directory */
- rc=DosSetCurrentDir("\\");
- if(rc!=NO_ERROR)
- {
- sprintf(ucMessageBuffer, "Can't change into the directory %s to invoke %s - continuing...",
- "\\", pSessionData->PgmTitle);
- DOS_ERR(rc, pHP->hwndFrame, HELP_SETPATH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- memset(&StartData, 0, sizeof(StartData));
- StartData.Length=sizeof(StartData); /* Length of StartData */
- /* Buffer containing the module contributed to
- an error that the session could not be started */
- StartData.ObjectBuffer=malloc(CCHMAXPATH);
- memset(StartData.ObjectBuffer, 0, CCHMAXPATH);
- StartData.ObjectBuffLen=CCHMAXPATH;
- /* Independent session */
- StartData.Related=SSF_RELATED_INDEPENDENT;
- StartData.FgBg=pSessionData->FgBg; /* Foreground application */
- /* No trace */
- StartData.TraceOpt=SSF_TRACEOPT_NONE;
- /* Session title string */
- for(pucSource=pSessionData->PgmTitle, pucDestination=ucPgmTitle; *pucSource; pucSource++)
- /* Remove ~ (tilde) */
- if(*pucSource!='~') *pucDestination++=*pucSource;
- *pucDestination='\0'; /* Add 0-termination */
- StartData.PgmTitle=ucPgmTitle;
- /* Program path-name string */
- StartData.PgmName=pSessionData->PgmName;
- /* Input arguments */
- if(*pSessionData->PgmInputs=='\0')
- StartData.PgmInputs=0;
- else
- StartData.PgmInputs=pSessionData->PgmInputs;
- StartData.TermQ=0; /* No termination queue */
- if(*pSessionData->PgmEnvironment=='\0') /* Has the user overwritten the environment? */
- StartData.Environment=0; /* Inherit environment from PC/2 */
- else
- /* Create a modified environment to inherit */
- StartData.Environment=CreateEnvironment(pSessionData->PgmEnvironment);
- /* Inherit from PC/2's environment to change to
- requested drive & directory */
- StartData.InheritOpt=SSF_INHERTOPT_PARENT;
- /* Session type */
- StartData.SessionType=pSessionData->SessionType;
- StartData.IconFile=0; /* No icon, use default */
- StartData.PgmHandle=0; /* Don't use installation file */
- /* Session initial state */
- StartData.PgmControl=(pSessionData->PgmControl & ~SSF_CONTROL_AUTOSTART);
- /* Initial window size */
- if(StartData.PgmControl & SSF_CONTROL_SETPOS)
- { /* Position relative to (0|0) of virtual Desktop */
- StartData.InitXPos=0-pHP->VirtualDesktopPos.x+pSessionData->InitXPos;
- StartData.InitYPos=0-pHP->VirtualDesktopPos.y+pSessionData->InitYPos;
- StartData.InitXSize=pSessionData->InitXSize;
- StartData.InitYSize=pSessionData->InitYSize;
- }
- /* *\
- * Search for user-addable commandline parameter. If one found, display dialog and get *
- * it. It will be added to the current arguments. *
- \* */
- while(TRUE)
- {
- COMMANDLINEPARAMS CLPParams;
- ULONG ulResult; /* Value returned by WinDismissDlg() */
- INT iTemp;
- UCHAR *pucTemp;
-
- /* Copy application to add CLPs for */
- strcpy(CLPParams.ucPgmTitle, StartData.PgmTitle);
- strcpy(ucPgmInputs, pSessionData->PgmInputs);
- /* Search for [, break if not found */
- if((pucTemp=strchr(ucPgmInputs, '['))==NULL) break;
- /* Search for ], break if not found */
- if(strchr(pucTemp, ']')==NULL) break;
- /* Break commandline parameters into three parts */
- for(iTemp=0, pucTemp=StartData.PgmInputs; *pucTemp!='['; iTemp++, pucTemp++)
- CLPParams.ucPBefore[iTemp]=*pucTemp;
- CLPParams.ucPBefore[iTemp]='\0';
- pucTemp++; /* Skip [ */
- for(iTemp=0; *pucTemp!=']'; iTemp++, pucTemp++)
- CLPParams.ucPUser[iTemp]=*pucTemp;
- CLPParams.ucPUser[iTemp]='\0';
- pucTemp++; /* Skip ] */
- for(iTemp=0; *pucTemp!='\0'; iTemp++, pucTemp++)
- CLPParams.ucPAfter[iTemp]=*pucTemp;
- CLPParams.ucPAfter[iTemp]='\0';
- if(!(ulResult=WinDlgBox( /* Start Startup Parameters dialog box */
- HWND_DESKTOP, HWND_DESKTOP, SU_DialogProcedure, 0, SUID_STARTUPDIALOG,
- &CLPParams))) /* Initialization data */
- {
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_CREATEDIALOG, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Creation of a dialog box failed - continuing...");
- break;
- }
- /* Replace existing commandline parameters with
- user-edited ones if OK was pressed */
- if(ulResult==DID_OK)
- {
- sprintf(ucPgmInputs, "%s%s %s",CLPParams.ucPBefore, CLPParams.ucPUser, CLPParams.ucPAfter);
- StartData.PgmInputs=ucPgmInputs;
- }
- /* If Cancel was pressed, leave empty string */
- break; /* Break out ! */
- }
- /* *\
- * If we're to start a DOS session, then set the DOS-Settings via the Environment. This *
- * is an undocumented feature (the toolkit says that the Environment is reserved and *
- * must be 0 for a DOS session. To use the DOS Settings each Setting must be followed *
- * by \0 and the last Setting must be followed by two \0s. It seems that the settings *
- * must replace OFF by 0 and ON by 1. *
- * Any WIN-OS2 session is hereto equivalent to a DOS session. *
- \* */
- switch(StartData.SessionType)
- {
- case PROG_VDM:
- case PROG_WINDOWEDVDM:
- case PROG_WINDOW_REAL:
- case PROG_WINDOW_PROT:
- case PROG_31_ENH:
- case PROG_31_STDSEAMLESSCOMMON:
- case PROG_31_ENHSEAMLESSCOMMON:
- {
- ULONG ulLength=strlen(pSessionData->PgmDosSettings)+1;
- UCHAR *pucDosSettings;
-
- /* Convert to format used by OS/2 in environment of session
- to start (same as used for WINDOWS32PROPERTYDIALOG) */
- pucDosSettings=ImportDosSettings(pSessionData->PgmDosSettings, &ulLength, FALSE);
- StartData.Environment=pucDosSettings;
- }
- break;
- }
- switch(StartData.SessionType)
- {
- case PROG_WINDOW_REAL:
- case PROG_WINDOW_PROT:
- case PROG_31_ENH:
- {
- UCHAR ucTemp[EF_SIZE255+1];
-
- strcpy(ucTemp, ucPgmInputs);
- if(StartData.SessionType==PROG_WINDOW_REAL)
- strcpy(ucPgmInputs, "/r "); /* WIN-OS2 real mode */
- if(StartData.SessionType==PROG_WINDOW_PROT)
- strcpy(ucPgmInputs, "/s "); /* WIN-OS2 standard mode */
- if(StartData.SessionType==PROG_31_ENH)
- strcpy(ucPgmInputs, "/3 "); /* WIN-OS2 386 enhanced mode */
- /* Now add the WIN application to invoke */
- strcat(ucPgmInputs, StartData.PgmName);
- strcat(ucPgmInputs, " ");
- strcat(ucPgmInputs, ucTemp); /* Copy optional commandline parameters as
- parameters to the WIN application to be
- invoked */
- StartData.PgmName="WIN.COM"; /* For WIN-OS2 sessions we use WIH.COM to start
- the WIN-application */
- StartData.PgmInputs=ucPgmInputs; /* Pass the WIN application to be invoked */
- /* Now invoke a WIN-OS2 session. Although it is named
- common, it will invoke a seperate VDM */
- StartData.SessionType=PROG_SEAMLESSCOMMON;
- } /* Fall through, cause the Dos Settings are the same */
- break;
-
- case PROG_31_STDSEAMLESSCOMMON:
- case PROG_31_ENHSEAMLESSCOMMON:
- {
- memset(&ProgDetails, 0, sizeof(ProgDetails));
- /* Start a common VDM */
- ProgDetails.Length=sizeof(PROGDETAILS);
- ProgDetails.progt.progc=StartData.SessionType;
- ProgDetails.progt.fbVisible=SHE_VISIBLE;
- ProgDetails.pszTitle=StartData.PgmTitle;
- ProgDetails.pszExecutable=StartData.PgmName;
- ProgDetails.pszParameters=StartData.PgmInputs;
- ProgDetails.pszStartupDir=pSessionData->PgmDirectory;
- ProgDetails.pszEnvironment=StartData.Environment;
- }
- break;
- }
- /* *\
- * Now set the requested priority, the started session will inherit these settings (at *
- * least non-WPS-object sessions. Afterwards reset to default priority. For DOS *
- * sessions changing priority will hang the system, so DOS sessions have the default *
- * priority only. *
- \* */
- if((pSessionData->PriorityClass!=PRTYC_NOCHANGE) || (pSessionData->PriorityDelta!=PRTYC_NOCHANGE))
- {
- rc=DosSetPrty(PRTYS_PROCESSTREE, (ULONG)pSessionData->PriorityClass, (LONG)pSessionData->PriorityDelta,
- pHP->ProcessId);
- if(rc!=NO_ERROR)
- {
- sprintf(ucMessageBuffer, "Can't change the priority while invoking %s - continuing...",
- pSessionData->PgmTitle);
- DOS_ERR(rc, pHP->hwndFrame, HELP_PRIORITY, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- /* *\
- * Now start the session, but beware of the error code ERROR_SMG_START_IN_BACKGROUND, *
- * which isn't actually an error code, but an informational message we ignore. *
- \* */
- switch(StartData.SessionType)
- {
- case PROG_WPSOBJECT:
- {
- HOBJECT hWPSObject;
-
- /* Find the handle of the WPS object */
- hWPSObject=WinQueryObject(pSessionData->PgmName);
- if(hWPSObject!=NULLHANDLE)
- WinSetObjectData(hWPSObject, "OPEN=DEFAULT");
- else rc=ERROR_INVALID_HANDLE;
- rc=NO_ERROR; /* WPS object can't be started when WPS is not running */
- }
- break;
-
- case PROG_31_STDSEAMLESSCOMMON:
- case PROG_31_ENHSEAMLESSCOMMON:
- {
- HAPP hApp;
-
- hApp=WinStartApp(NULLHANDLE, &ProgDetails, "", NULL, SAF_INSTALLEDCMDLINE);
- if(hApp==NULLHANDLE)
- {
- sprintf(ucMessageBuffer, "An error occured while invoking %s - continuing...",
- pSessionData->PgmTitle);
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_LAUNCH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- rc=NO_ERROR;
- }
- break;
-
- default:
- DosQueryCurrentDisk(&ulCurrentDrive, &ulLogicalDriveMap);
- DosQueryCurrentDir(ulCurrentDrive, ucCurrentDirectory, &ulCurrentDirectoryLen);
- rc=DosStartSession( /* Start the new session */
- &StartData, /* Session data */
- &SessID, /* Session ID of new session */
- &Pid); /* Process ID of new session */
- }
- switch(rc)
- {
- case NO_ERROR: /* Error codes for errors that are informational */
- case ERROR_SMG_START_IN_BACKGROUND:
- break;
-
- default:
- {
- sprintf(ucMessageBuffer, "An error occured while invoking %s from directory %c:\\%s. "\
- "Module %s contributed to the failure - continuing...",
- pSessionData->PgmTitle, 'A'+((char)ulCurrentDrive-1), ucCurrentDirectory, StartData.ObjectBuffer);
- DOS_ERR(rc, pHP->hwndFrame, HELP_LAUNCH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- /* Set PC/2's startup priority */
- if((pSessionData->PriorityClass!=PRTYC_NOCHANGE) || (pSessionData->PriorityDelta!=PRTYC_NOCHANGE))
- {
- rc=DosSetPrty(PRTYS_PROCESSTREE, (ULONG)PRTYC_REGULAR, (LONG)(-pSessionData->PriorityDelta),
- pHP->ProcessId);
- if(rc!=NO_ERROR)
- {
- sprintf(ucMessageBuffer, "Can't change the priority back to default after invoking %s - continuing...",
- pSessionData->PgmTitle);
- DOS_ERR(rc, pHP->hwndFrame, HELP_PRIORITY, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- ucMessageBuffer);
- }
- }
- /* Clear extended LIBPATH to prevent inheritance
- of unwanted data from a previous launch that set
- the extended LIBPATH */
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH("", BEGINLIBPATH);
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH("", ENDLIBPATH);
- /* *\
- * Release memory allocated for the DOS Settings. *
- \* */
- switch(StartData.SessionType)
- {
- case PROG_VDM:
- case PROG_WINDOWEDVDM:
- case PROG_WINDOW_REAL:
- case PROG_WINDOW_PROT:
- case PROG_31_ENH:
- case PROG_31_STDSEAMLESSCOMMON:
- case PROG_31_ENHSEAMLESSCOMMON:
- if(StartData.Environment) free(StartData.Environment);
- break;
- }
- /* If PC/2 inherited a customized environment,
- its now time to deallocate it */
- if(StartData.Environment) free(StartData.Environment);
- /* Set empty dynamic LIBPATH (WARP+) */
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH(NULL, BEGINLIBPATH);
- if(pHP->DosSetExtLIBPATH)
- pHP->DosSetExtLIBPATH(NULL, ENDLIBPATH);
- free(StartData.ObjectBuffer);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * Procedure to load a SESSIONDATA structure from a MENUDATA structure. *
- * Req: *
- * pMenuData ..... A pointer to a MENUDATA structure to extract the data required *
- * for a Menu/Program Installation dialog. *
- * pSessionData .. A pointer to a SESSIONDATA structure to write the extracted *
- * data into, which is then used in subsequent Menu/Program *
- * Installation dialogs window procedures. *
- * Returns: *
- * TRUE/FALSE .... If called sucessfully/unsucessfully *
- \*--------------------------------------------------------------------------------------*/
- BOOL LoadMenuData2SessionData(MENUDATA *pMenuData, SESSIONDATA *pSessionData)
- {
- strcpy(pSessionData->PgmTitle, pMenuData->PgmTitle);
- strcpy(pSessionData->WindowTitle, pMenuData->WindowTitle);
- strcpy(pSessionData->PgmName, pMenuData->PgmName);
- strcpy(pSessionData->PgmDirectory, pMenuData->PgmDirectory);
- strcpy(pSessionData->PgmInputs, pMenuData->PgmInputs);
- pSessionData->PgmDosSettings=pMenuData->PgmDosSettings;
- pSessionData->PgmEnvironment=pMenuData->PgmEnvironment;
- /* *\
- * Just straight forward copy of data from MENUDATA structure to SESSIONDATA structure. *
- * The allocated MENUDATA structure is filled during allocation with default values, *
- * we don't differentiate between empty and non-empty structures any more. *
- \* */
- pSessionData->SessionType=pMenuData->SessionType;
- pSessionData->PgmControl=pMenuData->PgmControl;
- pSessionData->FgBg=pMenuData->FgBg;
- pSessionData->InitXPos=pMenuData->InitXPos;
- pSessionData->InitYPos=pMenuData->InitYPos;
- pSessionData->InitXSize=pMenuData->InitXSize;
- pSessionData->InitYSize=pMenuData->InitYSize;
- (pSessionData->KeyData).usFlags=(pMenuData->KeyData).usFlags;
- (pSessionData->KeyData).usCh=(pMenuData->KeyData).usCh;
- (pSessionData->KeyData).pMenuData=pMenuData;
- pSessionData->SwpFlag=pMenuData->SwpFlag;
- pSessionData->PriorityClass=pMenuData->PriorityClass;
- pSessionData->PriorityDelta=pMenuData->PriorityDelta;
- return(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * Procedure to save a MENUDATA structure to a SESSIONDATA structure. *
- * Req: *
- * pMenuData ..... A pointer to a MENUDATA structure to write the data from a *
- * Menu/Program Installation dialog. *
- * pSessionData .. A pointer to a SESSIONDATA structure to extract the data from, *
- * which the user entered. *
- * Returns: *
- * TRUE/FALSE .... If called sucessfully/unsucessfully *
- \*--------------------------------------------------------------------------------------*/
- BOOL LoadSessionData2MenuData(MENUDATA *pMenuData, SESSIONDATA *pSessionData)
- {
- /* Ignore if not changed otherwise release memory
- and allocate a new one */
- if(strcmp(pMenuData->PgmTitle, pSessionData->PgmTitle)!=0)
- {
- free(pMenuData->PgmTitle);
- pMenuData->PgmTitle=malloc(1+strlen(pSessionData->PgmTitle));
- strcpy(pMenuData->PgmTitle, pSessionData->PgmTitle);
- }
- if(strcmp(pMenuData->WindowTitle, pSessionData->WindowTitle)!=0)
- {
- free(pMenuData->WindowTitle);
- pMenuData->WindowTitle=malloc(1+strlen(pSessionData->WindowTitle));
- strcpy(pMenuData->WindowTitle, pSessionData->WindowTitle);
- }
- if(strcmp(pMenuData->PgmName, pSessionData->PgmName)!=0)
- {
- free(pMenuData->PgmName);
- pMenuData->PgmName=malloc(1+strlen(pSessionData->PgmName));
- strcpy(pMenuData->PgmName, pSessionData->PgmName);
- }
- if(strcmp(pMenuData->PgmDirectory, pSessionData->PgmDirectory)!=0)
- {
- free(pMenuData->PgmDirectory);
- pMenuData->PgmDirectory=malloc(1+strlen(pSessionData->PgmDirectory));
- strcpy(pMenuData->PgmDirectory, pSessionData->PgmDirectory);
- }
- if(strcmp(pMenuData->PgmInputs, pSessionData->PgmInputs)!=0)
- {
- free(pMenuData->PgmInputs);
- pMenuData->PgmInputs=malloc(1+strlen(pSessionData->PgmInputs));
- strcpy(pMenuData->PgmInputs, pSessionData->PgmInputs);
- }
- switch(pSessionData->SessionType)
- { /* Save DOS settings for DOS type sessions */
- case PROG_VDM:
- case PROG_WINDOWEDVDM:
- case PROG_WINDOW_REAL:
- case PROG_WINDOW_PROT:
- case PROG_31_ENH:
- case PROG_31_STDSEAMLESSCOMMON:
- case PROG_31_ENHSEAMLESSCOMMON:
- /* Accept DOS sessings */
- pMenuData->PgmDosSettings=pSessionData->PgmDosSettings;
- break;
-
- default:
- /* For all other we load empty DOS settings.
- Normally they are empty, but default IDLE_SECONDS
- and IDLE_SENSITIVITY are added or if someone
- modifys the profile there may be some, which
- we force to be cleared */
- free(pSessionData->PgmDosSettings);
- pSessionData->PgmDosSettings=malloc(1+strlen(""));
- pMenuData->PgmDosSettings=pSessionData->PgmDosSettings;
- break;
- }
- switch(pSessionData->SessionType)
- {
- case PROG_PM:
- case PROG_FULLSCREEN:
- case PROG_WINDOWABLEVIO:
- /* Accept environment modifications */
- pMenuData->PgmEnvironment=pSessionData->PgmEnvironment;
- break;
-
- default:
- /* For all DOS base sessions, don't accept an environment */
- free(pSessionData->PgmEnvironment);
- pSessionData->PgmEnvironment=malloc(1+strlen(""));
- pMenuData->PgmEnvironment=pSessionData->PgmEnvironment;
- }
- pMenuData->PgmEnvironment=pSessionData->PgmEnvironment;
- pMenuData->SessionType=pSessionData->SessionType;
- pMenuData->PgmControl=pSessionData->PgmControl;
- pMenuData->FgBg=pSessionData->FgBg;
- pMenuData->InitXPos=pSessionData->InitXPos;
- pMenuData->InitYPos=pSessionData->InitYPos;
- pMenuData->InitXSize=pSessionData->InitXSize;
- pMenuData->InitYSize=pSessionData->InitYSize;
- (pMenuData->KeyData).usFlags=(pSessionData->KeyData).usFlags;
- (pMenuData->KeyData).usCh=(pSessionData->KeyData).usCh;
- pMenuData->SwpFlag=pSessionData->SwpFlag;
- pMenuData->PriorityClass=pSessionData->PriorityClass;
- pMenuData->PriorityDelta=pSessionData->PriorityDelta;
- return(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure allocates a MENUDATA structure and initializes it to the default *
- * values of an empty structure. *
- * Req: *
- * none *
- * Returns: *
- * pMenuData ..... A pointer to an MENUDATA structure. *
- \*--------------------------------------------------------------------------------------*/
- MENUDATA *AllocateMenuData(void)
- {
- UCHAR *pU;
- MENUDATA *pMD;
-
- pMD=malloc(sizeof(MENUDATA)); /* Allocate a MENUDATA structure */
- pMD->Item=ENTRYEMPTY; /* It's an empty structure */
- pMD->id=0;
- pMD->hwndItem=NULLHANDLE;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmTitle=pU; /* Load default values */
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->WindowTitle=pU;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmName=pU;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmDirectory=pU;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmInputs=pU;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmDosSettings=pU;
- strcpy(pU=malloc(strlen("")+1), "");
- pMD->PgmEnvironment=pU;
- pMD->SessionType=PROG_DEFAULT;
- pMD->PgmControl=SSF_CONTROL_VISIBLE;
- pMD->FgBg=SSF_FGBG_FORE;
- pMD->InitXPos=pHP->swpScreen.cx*0.15;
- pMD->InitYPos=pHP->swpScreen.cy*0.15;
- pMD->InitXSize=pHP->swpScreen.cx*0.70;
- pMD->InitYSize=pHP->swpScreen.cy*0.70;
- (pMD->KeyData).usFlags=KC_CTRL;
- (pMD->KeyData).usCh=0;
- (pMD->KeyData).pMenuData=NULL;
- pMD->SwpFlag=SWP_RESTORE;
- pMD->PriorityClass=PRTYC_NOCHANGE;
- pMD->PriorityDelta=PRTYC_NOCHANGE;
- pMD->Back=NULL;
- pMD->Submenu=NULL;
- pMD->Next=NULL;
- return(pMD);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This recursive procedure loads the popup menu from the profile. *
- * Req: *
- * pMenuData ..... A pointer to an MENUDATA structure. *
- * Returns: *
- * none *
- \*--------------------------------------------------------------------------------------*/
- void LoadMenu(MENUDATA *pMenuData)
- {
- static UCHAR Buffer[512];
- static UCHAR *Match;
- static USHORT Flag;
-
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- do
- {
- /* Should read MENUITEM or MENUCONTROL or
- SUBMENU BEGIN or SUBMENU END */
- if(strstr(Buffer, "SUBMENU END"))
- {
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- return; /* We are at an end of the list, terminate it
- and shell up one level by return() */
- }
- pMenuData->id=pHP->MenuDataId++; /* Fill with current id and increment id */
- if(strstr(Buffer, "PROFILE END")) return;
- if(strstr(Buffer, "MENUITEM")) Flag=ENTRYMENUITEM;
- else if(strstr(Buffer, "MENUCONTROL")) Flag=ENTRYCONTROL;
- else Flag=ENTRYSUBMENU;
- /* *\
- * Get the entry from the profile, but remove the heading description and the \n from *
- * the strings. *
- \* */
- /* Get the session title */
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- /* Replace CRLF with \0 */
- Buffer[strlen(Buffer)-1]='\0';
- if((Match=strchr(Buffer, ' '))==NULL) Match=strchr(Buffer, '\0');
- else for( ; (*Match==' ') && (*Match!='\0'); /* Match++ */)
- Match++;
- free(pMenuData->PgmTitle);
- pMenuData->PgmTitle=malloc(strlen(Match)+1);
- strcpy(pMenuData->PgmTitle, Match);
- if(Flag==ENTRYMENUITEM)
- {
- pMenuData->Item=ENTRYMENUITEM; /* It's a Menuitem */
- do /* Do until a complete MENUITEM was read */
- {
- /* Get a new line */
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- /* Replace CRLF with \0 */
- Buffer[strlen(Buffer)-1]='\0';
- /* Find first space after a ':' or NULL, if
- none can be found */
- Match=strchr(Buffer, ':');
- if(Match=='\0') Match=strchr(Buffer, '\0');
- else /* We found a ':', so we search for ' ' and
- return it or NULL, if none can be found */
- if((Match=strchr(Match, ' '))==NULL) Match=strchr(Buffer, '\0');
- else for( ; (*Match==' ') && (*Match!='\0'); /* Match++ */)
- Match++;;
- /* Now fill in the characters after the
- space, according for what structure
- element it is given */
- if(strstr(Buffer, "WindowTitle"))
- {
- free(pMenuData->WindowTitle);
- pMenuData->WindowTitle=malloc(strlen(Match)+1);
- strcpy(pMenuData->WindowTitle, Match);
- }
- if(strstr(Buffer, "PgmName"))
- {
- free(pMenuData->PgmName);
- pMenuData->PgmName=malloc(strlen(Match)+1);
- strcpy(pMenuData->PgmName, Match);
- }
- if(strstr(Buffer, "PgmDirectory"))
- {
- free(pMenuData->PgmDirectory);
- pMenuData->PgmDirectory=malloc(strlen(Match)+1);
- strcpy(pMenuData->PgmDirectory, Match);
- }
- if(strstr(Buffer, "PgmInputs"))
- {
- free(pMenuData->PgmInputs);
- pMenuData->PgmInputs=malloc(strlen(Match)+1);
- strcpy(pMenuData->PgmInputs, Match);
- }
- if(strstr(Buffer, "DOSSETTINGS BEGIN"))
- {
- UCHAR ucBuffer[LENDOSSETTINGS]="";
-
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- while(!strstr(Buffer, "DOSSETTINGS END"))
- { /* Add all DOS Settings to temporary buffer */
- UCHAR *pucTemp;
-
- /* Ensure that \r\n (CRLF) terminates DOS setting */
- if(*((pucTemp=strchr(Buffer, '\n'))-1)!='\r')
- {
- *pucTemp++='\r';
- *pucTemp++='\n';
- *pucTemp='\0';
- }
- if(strlen(ucBuffer)+strlen(Buffer)+2 < LENDOSSETTINGS)
- /* Don't copy just a line of only CFLF */
- if(strcmp(Buffer, "\r\n"))
- strcat(ucBuffer, Buffer);
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- }
- /* Now allocate the exactly required buffer and
- copy all DOS Settings there */
- free(pMenuData->PgmDosSettings);
- pMenuData->PgmDosSettings=strdup(ucBuffer);
- }
- if(strstr(Buffer, "ENVIRONMENT BEGIN"))
- {
- UCHAR ucBuffer[LENENVSETTINGS]="";
-
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- while(!strstr(Buffer, "ENVIRONMENT END"))
- { /* Add all Environment settings to temporary buffer */
- UCHAR *pucTemp;
-
- /* Ensure that \r\n (CRLF) terminates Environment setting */
- if(*((pucTemp=strchr(Buffer, '\n'))-1)!='\r')
- {
- *pucTemp++='\r';
- *pucTemp++='\n';
- *pucTemp='\0';
- }
- if(strlen(ucBuffer)+strlen(Buffer)+2 < LENENVSETTINGS)
- /* Don't copy just a line of only CFLF */
- if(strcmp(Buffer, "\r\n"))
- strcat(ucBuffer, Buffer);
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- }
- /* Now allocate the exactly required buffer and
- copy all Environment settings there */
- free(pMenuData->PgmEnvironment);
- pMenuData->PgmEnvironment=strdup(ucBuffer);
- }
- if(strstr(Buffer, "SessionType"))
- {
- ULONG ulTemp;
-
- pMenuData->SessionType=(USHORT)-1;
- for(ulTemp=0; ulTemp<SESSIONTYPESIZE; ulTemp++)
- if(strstr(Match, SessionType[ulTemp].pucSessionType))
- {
- pMenuData->SessionType=SessionType[ulTemp].usSessionType;
- }
- if(pMenuData->SessionType==(USHORT)-1)
- pMenuData->SessionType=(USHORT)atol(Match);
- }
- if(strstr(Buffer, "PgmControl"))
- {
- ULONG ulTemp;
-
- for(ulTemp=0; ulTemp<PGMCONTROLSIZE; ulTemp++)
- if(strstr(Match, PgmControl[ulTemp].pucPgmControl))
- pMenuData->PgmControl|=PgmControl[ulTemp].usPgmControl;
- if(pMenuData->PgmControl==0)
- pMenuData->PgmControl=(USHORT)atol(Match);
- }
- if(strstr(Buffer, "FgBg"))
- {
- if(strstr(Match, "SSF_FGBG_BACK"))
- pMenuData->FgBg=SSF_FGBG_BACK;
- else
- pMenuData->FgBg=SSF_FGBG_FORE;
- }
- if(strstr(Buffer, "InitXPos"))
- {
- pMenuData->InitXPos=(SHORT)atol(Match);
- }
- if(strstr(Buffer, "InitYPos"))
- {
- pMenuData->InitYPos=(SHORT)atol(Match);
- }
- if(strstr(Buffer, "InitXSize"))
- {
- pMenuData->InitXSize=(USHORT)atol(Match);
- }
- if(strstr(Buffer, "InitYSize"))
- {
- pMenuData->InitYSize=(USHORT)atol(Match);
- }
- if(strstr(Buffer, "KeyControl"))
- {
- if(strstr(Match, "KC_CTRL"))
- (pMenuData->KeyData).usFlags=KC_CTRL;
- if(strstr(Match, "KC_ALT"))
- (pMenuData->KeyData).usFlags=KC_ALT;
- }
- if(strstr(Buffer, "KeyData"))
- {
- KEYDATA *pKeyDataIndex;
- ULONG ulTemp;
-
- /* Find first char from end of string, which
- must be our hotkey */
- Match=strrchr(Buffer, ' ');
- if(Match!=NULL)
- {
- (pMenuData->KeyData).usCh=(USHORT)*(++Match);
- pKeyDataIndex=pHP->pKeyData;
- /* If we found a key set it to used */
- for(ulTemp=0; ulTemp<KEYDATACOUNT; pKeyDataIndex++, ulTemp++)
- if((pKeyDataIndex->usCh==(pMenuData->KeyData).usCh) &&
- (pKeyDataIndex->usFlags==(pMenuData->KeyData).usFlags))
- {
- pKeyDataIndex->bUsed=TRUE;
- pKeyDataIndex->pMenuData=pMenuData;
- }
- }
- }
- if(strstr(Buffer, "WindowControl"))
- {
- if(strstr(Match, "SWP_MAXIMIZE"))
- pMenuData->SwpFlag=(pMenuData->SwpFlag | SWP_MAXIMIZE) & ~SWP_RESTORE;
- if(strstr(Match, "SWP_RESTORE"))
- pMenuData->SwpFlag=(pMenuData->SwpFlag | SWP_RESTORE) & ~SWP_MAXIMIZE;
- if(strstr(Match, "SWP_NOMOVE"))
- pMenuData->SwpFlag|=SWP_NOMOVE;
- }
- if(strstr(Buffer, "PriorityClass"))
- {
- pMenuData->PriorityClass=(USHORT)atol(Match);
- }
- if(strstr(Buffer, "PriorityDelta"))
- {
- pMenuData->PriorityDelta=(SHORT)atol(Match);
- }
- } while((!strstr(Buffer, "MENUITEM")) &&
- (!strstr(Buffer, "MENUCONTROL")) &&
- (!strstr(Buffer, "SUBMENU BEGIN")) &&
- (!strstr(Buffer, "SUBMENU END")) &&
- (!strstr(Buffer, "PROFILE END")) &&
- !feof(pHP->Pc2Profile));
- if(!strcmp(pMenuData->WindowTitle, ""))
- { /* If no string to match with titlebar or Task List is
- defined, use the sessions title */
- free(pMenuData->WindowTitle);
- pMenuData->WindowTitle=malloc(strlen(pMenuData->PgmTitle)+1);
- strcpy(pMenuData->WindowTitle, pMenuData->PgmTitle);
- }
-
- switch(pMenuData->SessionType) /* The user may manipulate the profile, so ensure
- that bad things are prevented */
- {
- case PROG_WINDOWEDVDM:
- case PROG_VDM:
- case PROG_WINDOW_REAL:
- case PROG_WINDOW_PROT:
- case PROG_31_ENH:
- /* Priority for DOS sessions lock PM, so ignore */
- pMenuData->PriorityClass=PRTYC_NOCHANGE;
- pMenuData->PriorityDelta=PRTYC_NOCHANGE;
- break;
- }
- /* Insert this Menuitem at the end of the Popup-Menu */
- if(pMenuData->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMenuData->Back)->Submenu==pMenuData)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(NULL));
- }
- if(Flag==ENTRYCONTROL)
- {
- pHP->MenuDataId--; /* Don't use the default ID, because controls have
- their own */
- pMenuData->Item=ENTRYCONTROL; /* It's a Menucontrol */
- /* For conversion from version 1.70 to 1.80 we support
- also a string containing no mnemonic during read.
- For non-mnemonic strings we just scan for substrings.
- Written is always the new style */
- if(!strcmp(pMenuData->PgmTitle, CTRL_CONFIGMENU) ||
- strstr(pMenuData->PgmTitle, "Menu"))
- { strcpy(pMenuData->PgmTitle, CTRL_CONFIGMENU); pMenuData->id=ID_CONFIGDIALOG; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_CONFIGDESKTOP) ||
- strstr(pMenuData->PgmTitle, "Desktop"))
- { strcpy(pMenuData->PgmTitle, CTRL_CONFIGDESKTOP); pMenuData->id=ID_DESKTOPDIALOG; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_ABOUT) ||
- strstr(pMenuData->PgmTitle, "About"))
- { strcpy(pMenuData->PgmTitle, CTRL_ABOUT); pMenuData->id=ID_ABOUTDIALOG; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_SHUTDOWN) ||
- strstr(pMenuData->PgmTitle, "ShutDown"))
- { strcpy(pMenuData->PgmTitle, CTRL_SHUTDOWN); pMenuData->id=ID_SHUTDOWN; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_HELP) ||
- strstr(pMenuData->PgmTitle, "Help"))
- { strcpy(pMenuData->PgmTitle, CTRL_HELP); pMenuData->id=ID_HELP; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_SPOOLER) ||
- strstr(pMenuData->PgmTitle, "Spooler"))
- { strcpy(pMenuData->PgmTitle, CTRL_SPOOLER); pMenuData->id=ID_SPOOLER; }
- if(!strcmp(pMenuData->PgmTitle, CTRL_EXIT) ||
- strstr(pMenuData->PgmTitle, "Exit"))
- { strcpy(pMenuData->PgmTitle, CTRL_EXIT); pMenuData->id=ID_EXIT; }
- /* We assume that more than 1 separator may occur
- so to be able add, modify or delete on menuitems
- define a unique one */
- if(!strcmp(pMenuData->PgmTitle, CTRL_BREAKSEPARATOR)) pMenuData->id=pHP->MenuDataId++;
- if(!strcmp(pMenuData->PgmTitle, CTRL_SEPARATOR)) pMenuData->id=pHP->MenuDataId++;
- /* Get a new line */
- fgets(Buffer, sizeof(Buffer), pHP->Pc2Profile);
- /* Replace CRLF with \0 */
- Buffer[strlen(Buffer)-1]='\0';
- /* Insert this Menuitem at the end of the Popup-Menu */
- if(pMenuData->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMenuData->Back)->Submenu==pMenuData)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(NULL));
- }
- if(Flag==ENTRYSUBMENU)
- { /* If we load a SUBMENU BEGIN, fill with empty strings */
- MENUDATA *pMenuDataTemp;
-
- pMenuData->Item=ENTRYSUBMENU; /* It's a Submenu */
- /* Now obtain a entry for a submenu, adjust the
- linked list to it and call this procedure with
- the new entry recursivly again */
- pMenuDataTemp=AllocateMenuData();
- pMenuData->Submenu=pMenuDataTemp;
- pMenuDataTemp->Back=pMenuData;
- /* Insert this Menuitem at the end of the Popup-Menu */
- if(pMenuData->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMenuData->Back)->Submenu==pMenuData)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(pMenuData->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMenuData), MPFROMP(NULL));
- LoadMenu(pMenuDataTemp); /* It's assumed to be an empty entry, which will
- be corrected, if the first entry of the Submenu
- is found. As after recursion into we continue
- here, the next statement must be the test
- for the end of the profile */
- }
- /* *\
- * Now see if we're at the end of the profile. If so, then terminate linked list with *
- * 2 Null pointers, otherwise abtain a new menu space and adjust the menu pointer *
- * pMenuData to the newly created menu. *
- \* */
- if(strstr(Buffer, "PROFILE END"))
- break; /* Empty lines may follow and feof() then is FALSE
- and we loop again, reading invalid input. Avoid
- this by breaking out of the loop */
- else
- { /* If a SUBMENU END follows ignore it, because
- execution will return at beginning of the loop
- otherwise add a new item to the end of the
- linked list */
- if(!strstr(Buffer, "SUBMENU END"))
- {
- MENUDATA *pMenuDataTemp;
-
- pMenuDataTemp=AllocateMenuData();
- pMenuData->Next=pMenuDataTemp;
- pMenuDataTemp->Back=pMenuData;
- pMenuData=pMenuData->Next;
- }
- }
- } while(!feof(pHP->Pc2Profile));
- return;
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This recursive procedure saves the popup menu into the profile. *
- * Req: *
- * pMenuData ..... A pointer to an MENUDATA structure. *
- * Returns: *
- * none *
- \*--------------------------------------------------------------------------------------*/
- void SaveMenu(MENUDATA *pMenuData)
- {
- do
- {
- if(pMenuData->Item==ENTRYSUBMENU)
- {
- /* *\
- * If this is a SUBMENU, then write the header SUBMENU BEGIN and then write the profile *
- * data from teh MENUDATA structure pointet by pMenuData. Then increment the depth *
- * counter and call this procedure recursivly again. After coming back, restore the *
- * depth counter and write the header SUBMENU END. *
- \* */
- fprintf(pHP->Pc2Profile, "SUBMENU BEGIN\n");
- fprintf(pHP->Pc2Profile, "PgmTitle: %s\n", pMenuData->PgmTitle);
- SaveMenu(pMenuData->Submenu);
- fprintf(pHP->Pc2Profile, "SUBMENU END\n");
- }
- if(pMenuData->Item==ENTRYMENUITEM)
- {
- /* *\
- * If it is a MENUITEM, so write the header MENUITEM and then write the profile data *
- * from the MENUDATA structure pointed by pMenuData. *
- \* */
- fprintf(pHP->Pc2Profile, "MENUITEM\n");
- fprintf(pHP->Pc2Profile, "PgmTitle: %s\n", pMenuData->PgmTitle);
- /* Window's title only written if defined */
- if(strcmp(pMenuData->WindowTitle, pMenuData->PgmTitle))
- fprintf(pHP->Pc2Profile, "WindowTitle: %s\n", pMenuData->WindowTitle);
- if(strcmp(pMenuData->PgmName, ""))
- fprintf(pHP->Pc2Profile, "PgmName: %s\n", pMenuData->PgmName);
- if(strcmp(pMenuData->PgmDirectory, ""))
- fprintf(pHP->Pc2Profile, "PgmDirectory: %s\n", pMenuData->PgmDirectory);
- if(strcmp(pMenuData->PgmInputs, ""))
- fprintf(pHP->Pc2Profile, "PgmInputs: %s\n", pMenuData->PgmInputs);
- /* Write DOS Settings only if available */
- if(strlen(pMenuData->PgmDosSettings)!=0)
- {
- if((pMenuData->SessionType==PROG_VDM) ||
- (pMenuData->SessionType==PROG_WINDOWEDVDM) ||
- (pMenuData->SessionType==PROG_WINDOW_REAL) ||
- (pMenuData->SessionType==PROG_WINDOW_PROT) ||
- (pMenuData->SessionType==PROG_31_STDSEAMLESSCOMMON) ||
- (pMenuData->SessionType==PROG_31_ENHSEAMLESSCOMMON) ||
- (pMenuData->SessionType==PROG_31_ENH))
- {
- fprintf(pHP->Pc2Profile, "DOSSETTINGS BEGIN\n");
- /* The required \n is already part of the string */
- fprintf(pHP->Pc2Profile, "%s", pMenuData->PgmDosSettings);
- fprintf(pHP->Pc2Profile, "DOSSETTINGS END\n");
- }
- }
- /* Write Environment settings only if available */
- if(strlen(pMenuData->PgmEnvironment)!=0)
- {
- if((pMenuData->SessionType==PROG_FULLSCREEN) ||
- (pMenuData->SessionType==PROG_WINDOWABLEVIO) ||
- (pMenuData->SessionType==PROG_PM))
- {
- fprintf(pHP->Pc2Profile, "ENVIRONMENT BEGIN\n");
- /* The required \n is already part of the string */
- fprintf(pHP->Pc2Profile, "%s", pMenuData->PgmEnvironment);
- fprintf(pHP->Pc2Profile, "ENVIRONMENT END\n");
- }
- }
- if(pMenuData->SessionType!=PROG_DEFAULT)
- {
- ULONG ulTemp;
-
- fprintf(pHP->Pc2Profile, "SessionType: ");
- for(ulTemp=0; ulTemp<SESSIONTYPESIZE; ulTemp++)
- if(pMenuData->SessionType==SessionType[ulTemp].usSessionType)
- {
- fprintf(pHP->Pc2Profile, "%s", SessionType[ulTemp].pucSessionType);
- break;
- }
- fprintf(pHP->Pc2Profile, "\n");
- }
- if(pMenuData->PgmControl!=SSF_CONTROL_VISIBLE)
- {
- ULONG ulTemp;
-
- fprintf(pHP->Pc2Profile, "PgmControl:");
- for(ulTemp=0; ulTemp<PGMCONTROLSIZE; ulTemp++)
- if(pMenuData->PgmControl&PgmControl[ulTemp].usPgmControl)
- fprintf(pHP->Pc2Profile, " %s", PgmControl[ulTemp].pucPgmControl);
- fprintf(pHP->Pc2Profile, "\n");
- }
- if(pMenuData->FgBg & SSF_FGBG_BACK)
- fprintf(pHP->Pc2Profile, "FgBg: SSF_FGBG_BACK\n");
- if(pMenuData->PgmControl & SSF_CONTROL_SETPOS)
- {
- fprintf(pHP->Pc2Profile, "InitXPos: %ld\n", (LONG)pMenuData->InitXPos);
- fprintf(pHP->Pc2Profile, "InitYPos: %ld\n", (LONG)pMenuData->InitYPos);
- fprintf(pHP->Pc2Profile, "InitXSize: %lu\n", (ULONG)pMenuData->InitXSize);
- fprintf(pHP->Pc2Profile, "InitYSize: %lu\n", (ULONG)pMenuData->InitYSize);
- }
- if(pMenuData->SwpFlag & SWP_NOMOVE)
- fprintf(pHP->Pc2Profile, "WindowControl: SWP_NOMOVE\n");
- if((pMenuData->KeyData).usCh!=0)
- { /* KC_CTRL and/or KC_ALT may be set */
- if((pMenuData->KeyData).usFlags==KC_CTRL)
- fprintf(pHP->Pc2Profile, "KeyControl: KC_CTRL\n");
- if((pMenuData->KeyData).usFlags==KC_ALT)
- fprintf(pHP->Pc2Profile, "KeyControl: KC_ALT\n");
- if(pMenuData->SwpFlag & SWP_MAXIMIZE)
- fprintf(pHP->Pc2Profile, "WindowControl: SWP_MAXIMIZE\n");
- if(pMenuData->SwpFlag & SWP_RESTORE)
- fprintf(pHP->Pc2Profile, "WindowControl: SWP_RESTORE\n");
- fprintf(pHP->Pc2Profile, "KeyData: %c\n", (UCHAR)(pMenuData->KeyData).usCh);
- }
- if((pMenuData->PriorityClass!=PRTYC_NOCHANGE) || (pMenuData->PriorityDelta!=PRTYC_NOCHANGE))
- {
- fprintf(pHP->Pc2Profile, "PriorityClass: %lu\n", (ULONG)pMenuData->PriorityClass);
- fprintf(pHP->Pc2Profile, "PriorityDelta: %ld\n", (ULONG)pMenuData->PriorityDelta);
- }
- }
- if(pMenuData->Item==ENTRYCONTROL)
- {
- /* *\
- * If it is a CONTROL so write the header MENUCONTROL and then write the profile data *
- * from the MENUDATA structure pointed by pMenuData. *
- \* */
- fprintf(pHP->Pc2Profile, "MENUCONTROL\n");
- fprintf(pHP->Pc2Profile, "PgmTitle: %s\n", pMenuData->PgmTitle);
- }
- /* *\
- * If one is available, get the next element in the linked list, else we are at the end *
- * either at a leaf or at the real last element, in both cases shell back one level. *
- * Shell back either exits this procedure completle (we have written the complete *
- * linked list) or on level (we have written a complete submenu leaf). *
- \* */
- if(pMenuData->Next!=NULL) pMenuData=pMenuData->Next;
- else break;
- } while(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This recursive procedure searches through the linked list for an element. *
- * Req: *
- * pMD ........... A pointer to the first element to search on *
- * id ............ Pointer to the ID to search for (pointer because we don't want *
- * to get a copy during recursion *
- * The ID is destroyed, so only pass the address of a copy of ID *
- * Returns: *
- * MENUDATA * .... Pointer to match or NULL if not found *
- \*--------------------------------------------------------------------------------------*/
- MENUDATA *SearchItem(MENUDATA *pMD, ULONG *id)
- {
- static MENUDATA *pMDReturn;
-
- do
- {
- /* If found, save the pointer of it, set ID to the
- value 1 which never occures in the linked list
- to detect the match at the end of the recursion */
- if(pMD->id==*id) { pMDReturn=pMD; *id=TRUE; break; }
- /* Shell into the Submenus */
- if(pMD->Item==ENTRYSUBMENU)
- SearchItem(pMD->Submenu, id);
- if(pMD->Next!=NULL) pMD=pMD->Next; /* Keep on searching until found or end of linked list */
- else
- { /* We're at the end of the linked list */
- if(*id!=TRUE) pMDReturn=NULL; /* If we didn't find the item return NULL */
- break;
- }
- } while(TRUE);
- return(pMDReturn);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This recursive procedure searches through the linked list for an element. *
- * Req: *
- * pMD ........... A pointer to the first element to search on *
- * pWD ........... Pointer to the a WINDOWDATA structure containing the session *
- * and titlebar title to compare with during recursion *
- * pbFlag ........ A pointer to a flag which is set from FALSE to TRUE, if the *
- * item was found, the flag is destroyed, so pass a copy. *
- * Returns: *
- * MENUDATA * .... Pointer to match or NULL if not found *
- \*--------------------------------------------------------------------------------------*/
- MENUDATA *SearchTitle(MENUDATA *pMD, WINDOWDATA *pWD, BOOL *pbFlag)
- {
- static MENUDATA *pMDReturn;
-
- do
- {
- /* Break if pointer is invalid or item was found */
- if((pMD==NULL) || (*pbFlag==TRUE)) break;
- /* If found, save the pointer of match */
- if(strlen(pMD->WindowTitle))
- {
- if(strstr(pWD->ucPgmTitle, pMD->WindowTitle) ||
- strstr(pWD->ucWindowTitle, pMD->WindowTitle))
- {
- pMDReturn=pMD;
- *pbFlag=TRUE; /* Indicate we found and won't search further */
- break;
- }
- else
- /* We haven't found it yet */
- if(*pbFlag!=TRUE) pMDReturn=NULL;
- }
- /* We haven't found it yet */
- else if (*pbFlag!=TRUE) pMDReturn=NULL;
- /* Shell into the Submenus */
- if(pMD->Item==ENTRYSUBMENU)
- SearchTitle(pMD->Submenu, pWD, pbFlag);
- if(pMD->Next!=NULL) pMD=pMD->Next; /* Keep on searching until found or end of linked list */
- else break; /* We're at the end of the linked list */
- } while(TRUE);
- return(pMDReturn);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This recursive procedure searches through the linked list for all applications that *
- * have the autostart flag set and start it by simulating the applications selection *
- * from the Popup-Menu. *
- * Req: *
- * pMD ........... A pointer to the first element to search on *
- * Returns: *
- \*--------------------------------------------------------------------------------------*/
- void SearchAutoStartItem(MENUDATA *pMD)
- {
- do
- {
- /* If it is a Sub-Menu recurse into */
- if(pMD->Item==ENTRYSUBMENU)
- SearchAutoStartItem(pMD->Submenu);
- /* If the autostart flag is set simulate selection
- from Popup-Menu by simulating its message */
- if(pMD->PgmControl & SSF_CONTROL_AUTOSTART)
- /* Why on the hell using WinPostMsg() does not work,
- that is DosStartSession() fails because its implicit
- call of DosExecPgm() is sometimes not able to load
- a statically linked DLL, even if the working directory
- is set up correctly, I don know.
- Even using WinPostMsg() and calling SearchAutoStartItem()
- from the main thread fails with the same symptom. By the
- way, it even doesn't fail consistent, sometimes it works
- and the failing sessions are not always the same, not
- always the same count of sessions started...very peculiar */
- WinSendMsg(pHP->hwndClient, WM_COMMAND,
- /* Get ID and set it as posted by a menu control */
- MPFROM2SHORT((USHORT)(pMD->id), CMDSRC_MENU),
- /* Simulate Message a result of a keyboard operation */
- MPFROMCHAR(FALSE));
- if(pMD->Next!=NULL) pMD=pMD->Next; /* Keep on searching until found end of linked list */
- else break;
- } while(TRUE);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure adds/changes/query/removes an item to/from the Popup-Menu. *
- * Req: *
- * msg ........... What to do *
- * mp1 ........... Parameter 1 *
- * mp2 ........... Parameter 2 *
- * Returns: *
- * MRESULT ....... Returned value of function *
- \*--------------------------------------------------------------------------------------*/
- MRESULT SetPopupMenu(ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- MENUDATA *pMDChange; /* Pointer to menuentry to change within menu */
- MENUDATA *pMD; /* Pointer to menuentry where changed menuentry gets
- modified afterwards */
- ULONG id; /* ID of the menuentry pointed to bz pMD */
- MENUITEM miMI; /* Update menus with this structure */
- HWND hwndMenu; /* Menu window handle */
- HWND hwndSubMenu; /* Window handle of a pulldown menu within the menu bar */
- MRESULT mr; /* PM API result */
- BOOL bResult;
-
- bResult=FALSE;
- switch(msg)
- {
- /* *\
- * Syntax: MM_INSERTITEM(MENUITEM|SUBMENU), MENUDATA *pMDChange, MENUDATA *pMD *
- \* */
- /* *\
- * Insert a Menuitem, a Submenu, Menuentry or Control, into a (Sub)menu, even if it is *
- * empty. *
- \* */
- case MM_INSERTITEMMENUITEM:
- /* *\
- * Insert a Menuitem, a Submenu or Menuentry as the first child entry of a parent *
- * Submenu. *
- \* */
- case MM_INSERTITEMSUBMENU:
- pMDChange=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to insert */
- pMD=PVOIDFROMMP(mp2); /* Get pointer to MENUDATA structure insert afterwards */
- if(pMD==NULL)
- id=MIT_END; /* Insert at end */
- else if(!strcmp(pMD->PgmTitle, CTRL_BREAKSEPARATOR))
- id=pMD->Back->id; /* If we insert after a break separator, we effectifely
- insert after the menu entry before the break separator,
- because the break separator is only a style */
- else
- id=pMD->id; /* Get id of menuentry insert afterwards */
- /* If the Configuration dialog is added set flag
- to true */
- if(pMDChange->id==ID_CONFIGDIALOG) pHP->ulStatusFlag&=(~DISPLAYCONFIGDIALOG);
-
- /* *\
- * An item (Menuitem or Submenu) is to be inserted into the Popup-Menu, either after *
- * a Menuitem or as the first item of a/the (Sub)menu. *
- \* */
- if(WinSendMsg(
- pHP->hwndPopupMenu,
- MM_QUERYITEM, /* Query a menuitem */
- MPFROM2SHORT(id, TRUE), /* Identifier, include submenus */
- (MPARAM)&miMI)==FALSE) /* Into MENUITEM structure */
- miMI.hwndSubMenu=0;
- /* If we're going to insert a break separator, we don't
- insert a functional menu entry, but have to change the
- style of the menu we "insert" break separator afterwards */
- if(!strcmp(pMDChange->PgmTitle, CTRL_BREAKSEPARATOR))
- {
- /* Modify style */
- miMI.afStyle|=MIS_BREAKSEPARATOR;
- if(WinSendMsg(
- pHP->hwndPopupMenu,
- MM_SETITEM, /* Set a menuitem's attribute */
- /* Identifier, include submenus */
- MPFROM2SHORT(miMI.id, TRUE),
- /* Attributes to set */
- (MPARAM)&miMI)==FALSE)
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_CREATEDIALOG, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't modify PC/2's Popup-Menu - continuing...");
- /* Save the menu window handle the item belongs to */
- pMDChange->hwndItem=pMDChange->Back->hwndItem;
- break;
- }
- /* If the item after we insert is a Submenu, then
- use the Submenu handle to insert new items,
- otherwise use the handle of the previous item */
- if((miMI.hwndSubMenu!=0) && (msg==MM_INSERTITEMSUBMENU))
- {
- hwndMenu=miMI.hwndSubMenu;
- id=MIT_END;
- }
- if(msg==MM_INSERTITEMMENUITEM)
- { /* If this is the first item, use the Popup-Menu
- window handle */
- if(pMDChange->Back==NULL) hwndMenu=pHP->hwndPopupMenu;
- /* If we insert after an available item, get it's
- window handle */
- else hwndMenu=(pMDChange->Back)->hwndItem;
- }
- /* If previous exists, insert after the item with
- ID id */
- if(id!=(ULONG)MIT_END) miMI.iPosition++;
- else miMI.iPosition=id; /* Insert at end MIT_END */
- miMI.afAttribute=0; /* Special attribute */
- miMI.id=pMDChange->id; /* Item identifier */
- miMI.hItem=0; /* No handle */
- if(pMDChange->Item==ENTRYSUBMENU)
- { /* If we insert a Submenu, than we need to obtain
- a handle to create one */
- hwndSubMenu=WinCreateMenu( /* Create a submenu menuitem */
- hwndMenu, /* Owner- and parent-window handle */
- NULL); /* Binary menu template */
- miMI.afStyle=MIS_SUBMENU; /* Style to insert */
- miMI.hwndSubMenu=hwndSubMenu; /* Pulldown menu */
- }
- if(pMDChange->Item==ENTRYMENUITEM)
- { /* We insert a Menuitem */
- miMI.afStyle=MIS_TEXT; /* Style to insert */
- miMI.hwndSubMenu=0; /* No pulldown menu */
- }
- if(pMDChange->Item==ENTRYCONTROL)
- { /* We insert a Control */
- if(!strcmp(pMDChange->PgmTitle, CTRL_SEPARATOR))
- miMI.afStyle=MIS_SEPARATOR; /* For a seperator insert a separator */
- else
- miMI.afStyle=MIS_TEXT;
- miMI.hwndSubMenu=0;
- }
- pMDChange->hwndItem=hwndMenu; /* Save the window handle of the item */
- mr=WinSendMsg(
- hwndMenu,
- MM_INSERTITEM, /* Insert a menu item */
- &miMI, /* Item to insert */
- pMDChange->PgmTitle); /* Text to insert */
- if(((SHORT)mr==MIT_ERROR) || ((SHORT)mr==MIT_MEMERROR))
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_CREATEDIALOG, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't modify PC/2's Popup-Menu - continuing...");
- else bResult=TRUE;
- break;
-
- /* *\
- * Syntax: MM_MOVEMENUITEM, MENUDATA *pMDSource, MENUDATA *pMDDestination *
- \* */
- case MM_MOVEMENUITEM:
- /* *\
- * Move a MENUITEM structure with idSource after the idDestination. *
- \* */
- {
- MENUDATA *pMDSource;
- MENUDATA *pMDDestination;
- ULONG idSource; /* Id of Menuitem to be moved */
- ULONG idDestination; /* Id of Menuitem after which the removed Menuitem
- will be inserted */
- MENUITEM miSource; /* MENUITEM structure of to be moved Menuitem */
- MENUITEM miDestination; /* MENUITEM structure of Menuitem after which
- the removed Menuitem will be inserted */
-
- pMDSource=PVOIDFROMMP(mp1);
- pMDDestination=PVOIDFROMMP(mp2);
- idSource=pMDSource->id; /* Get id of to be removed Menuitem */
- /* If a menuitem has to be moved after a break separator
- move it after previous menu entry, because a break
- separator is just a style of this entry */
- if(!strcmp(pMDDestination->PgmTitle, CTRL_BREAKSEPARATOR))
- idDestination=pMDDestination->Back->id;
- else
- /* Get id of Menuitem after which removed Menuitem
- will be inserted */
- idDestination=pMDDestination->id;
- /* *\
- * If the source and destination Menuitem are elements of the same level then they have *
- * the same item handle. *
- \* */
- if(pMDSource->hwndItem==pMDDestination->hwndItem)
- bResult=TRUE;
- else
- bResult=FALSE;
- /* Query all (Sub)menus for to be moved Menuitem */
- WinSendMsg(pHP->hwndPopupMenu, MM_QUERYITEM,
- MPFROM2SHORT(idSource, TRUE), (MPARAM)&miSource);
- /* Delete the to be moved Menuitem. Don't use MM_DELETEITEM
- because it frees all OS/2 internal structures,
- whereas MM_REMOVEITEM doesn't free them */
- WinSendMsg(pHP->hwndPopupMenu, MM_REMOVEITEM,
- MPFROM2SHORT(idSource, TRUE), (MPARAM)NULL);
- /* Query all (Sub)menus for Menuitem after which
- the removed Menuitem will be inserted */
- WinSendMsg(pHP->hwndPopupMenu, MM_QUERYITEM,
- MPFROM2SHORT(idDestination, TRUE), (MPARAM)&miDestination);
-
- if(bResult==TRUE)
- { /* If the destination of the Source Menuitem follows
- any previous Menuitem in the same level, just
- insert it one position behind */
- miSource.iPosition=++miDestination.iPosition;
- hwndMenu=pMDDestination->hwndItem;
- mr=WinSendMsg(hwndMenu, MM_INSERTITEM, &miSource, pMDSource->PgmTitle);
- }
- else
- { /* If the destination of the source Menuitem is the
- first position of a Submenu, insert it at 0-based
- position 0 */
- hwndMenu=miDestination.hwndSubMenu;
- miSource.iPosition=0;
- mr=WinSendMsg(hwndMenu, MM_INSERTITEM, &miSource, pMDSource->PgmTitle);
- }
-
- }
- break;
-
- /* *\
- * Syntax: MM_SETITEMTEXT, MENUDATA *pMDChange, ULONG id *
- \* */
- case MM_SETITEMTEXT:
- pMDChange=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to update */
- id=LONGFROMMP(mp2); /* Get id to update */
- /* *\
- * A available menuitem was selected to change. Change the text of the menuitem to the *
- * new one. *
- \* */
- if(WinSendMsg(
- pHP->hwndPopupMenu,
- MM_SETITEMTEXT, /* Set the text of a menuitem */
- MPFROMSHORT(id), /* Item ID */
- /* New menuitem text */
- (MPARAM)pMDChange->PgmTitle)==FALSE)
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_CREATEDIALOG, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't modify PC/2's Popup-Menu - continuing...");
- else bResult=TRUE;
- break;
-
- /* *\
- * Syntax: MM_DELETEITEM, MENUDATA *pMDChange, MENUDATA *pMD *
- \* */
- case MM_DELETEITEM:
- pMDChange=PVOIDFROMMP(mp1); /* Get pointer to MENUDATA structure to delete */
- pMD=PVOIDFROMMP(mp2); /* Get pointer to MENUDATA structure insert afterwards */
- if(!strcmp(pMD->PgmTitle, CTRL_BREAKSEPARATOR))
- id=pMD->Back->id; /* If we delete a break separator, we effectifely
- delete the style of the previous menu entry */
- else
- id=pMD->id; /* Get id to delete */
- /* If the Configuration dialog is removed set flag
- to false */
- if(pMDChange->id==ID_CONFIGDIALOG) pHP->ulStatusFlag|=DISPLAYCONFIGDIALOG;
- /* *\
- * A available menuitem was selected to delete. Delete the specified menuitem. *
- \* */
- /* If we're going to delete a break separator, we don't
- insert a functional menu entry, but have to change the
- style of the menu we "delete" break separator afterwards */
- if(!strcmp(pMDChange->PgmTitle, CTRL_BREAKSEPARATOR))
- {
- if(WinSendMsg(
- pHP->hwndPopupMenu,
- MM_QUERYITEM, /* Query a menuitem */
- MPFROM2SHORT(id, TRUE), /* Identifier, include submenus */
- (MPARAM)&miMI)==FALSE) /* Into MENUITEM structure */
- miMI.hwndSubMenu=0;
- /* Modify style */
- miMI.afStyle&=(~MIS_BREAKSEPARATOR);
- if(WinSendMsg(
- pHP->hwndPopupMenu,
- MM_SETITEM, /* Set a menuitem's attribute */
- /* Identifier, include submenus */
- MPFROM2SHORT(pMD->id, TRUE),
- /* Attributes to set */
- (MPARAM)&miMI)==FALSE)
- PM_ERR(pHP->habPc2, pHP->hwndFrame, HELP_CREATEDIALOG, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't modify PC/2's Popup-Menu - continuing...");
- break;
- }
- if(pMDChange->Item==ENTRYSUBMENU)
- { /* It the menuitem is a Submenu, also delete the
- first item of it (which should be empty) */
- mr=WinSendMsg(
- pHP->hwndPopupMenu,
- MM_DELETEITEM, /* Delete a menuitem */
- /* Item ID, include Submenus */
- MPFROM2SHORT((pMDChange->Submenu->id), TRUE),
- (MPARAM)NULL);
- }
- mr=WinSendMsg(
- pHP->hwndPopupMenu,
- MM_DELETEITEM, /* Delete a menuitem */
- MPFROM2SHORT(id, TRUE), /* Item ID, include Submenus */
- (MPARAM)NULL);
- bResult=TRUE;
- break;
- }
- return(MPFROMSHORT(bResult));
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure handles to copy a fully qualified path & filename into the corres- *
- * ponding entryfields of the Program Installation dialog. *
- * Req: *
- * hwndDlg ....... handle of Program installation dialog *
- * pucFullFileName fully qualified path & filename of application to add *
- * the name of an object to add *
- * bObject ....... TRUE if it is an WPS object *
- \*--------------------------------------------------------------------------------------*/
- void InstallFilename2Dialog(HWND hwndDlg, UCHAR *pucFullFileName, BOOL bObject)
- {
- UCHAR ucBuffer[CCHMAXPATH+6]; /* Longer than 260 because of "s */
- UCHAR ucFullFileName[EF_SIZE255+1];
- UCHAR *pucTemp;
- BOOL bBatchFile=FALSE;
- ULONG ulAppType; /* Type of application we're installing */
- USHORT usSessionType;
-
- if(bObject==TRUE)
- {
- usSessionType=PROG_WPSOBJECT; /* It is an WPS object */
- /* Set title and object name info entryfields */
- if(!WinQueryWindowTextLength(WinWindowFromID(hwndDlg, PIEF_PROGRAMTITLE)))
- {
- if((pucTemp=strrchr(pucFullFileName, '\\'))!=NULL)
- WinSetDlgItemText(hwndDlg, PIEF_PROGRAMTITLE, ++pucTemp);
- else
- WinSetDlgItemText(hwndDlg, PIEF_PROGRAMTITLE, pucFullFileName);
- }
- WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, pucFullFileName);
- WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, "");
- WinSetDlgItemText(hwndDlg, PIEF_DIRECTORY, "");
- }
- else
- { /* It is a file */
- /* Get the type of application */
- DosQueryAppType(pucFullFileName, &ulAppType);
- usSessionType=PROG_DEFAULT; /* Assume Shell determined for default */
- if((ulAppType & 0x7)==FAPPTYP_WINDOWAPI) usSessionType=PROG_PM;
- if((ulAppType & 0x7)==FAPPTYP_WINDOWCOMPAT) usSessionType=PROG_WINDOWABLEVIO;
- if(ulAppType & FAPPTYP_DOS) usSessionType=PROG_WINDOWEDVDM;
- if(ulAppType & FAPPTYP_WINDOWSREAL) usSessionType=PROG_WINDOW_REAL;
- if(ulAppType & FAPPTYP_WINDOWSPROT) usSessionType=PROG_WINDOW_PROT;
- if(ulAppType & FAPPTYP_WINDOWSPROT31) usSessionType=PROG_31_ENH;
- }
- if(bObject==FALSE)
- {
- /* Convert to uppercase to test for .CMD extension */
- strcpy(ucFullFileName, pucFullFileName);
- strupr(ucFullFileName);
- /* Now test for a OS/2 batch file */
- if(strstr(ucFullFileName, ".CMD")!=NULL)
- {
- usSessionType=PROG_WINDOWABLEVIO;
- bBatchFile=TRUE;
- if(strchr(pucFullFileName, ' ')!=NULL)
- { /* If path and filename contains spaces, insert
- two quotation marks */
- strcpy(ucBuffer, "/c \"\"");
- strcat(ucBuffer, pucFullFileName);
- strcat(ucBuffer, "\"\"");
- }
- else
- { /* Else add just /c to [path]filename.cmd */
- strcpy(ucBuffer, "/c ");
- strcat(ucBuffer, pucFullFileName);
- }
- }
- /* Now test for a DOS batch file */
- if(strstr(ucFullFileName, ".BAT")!=NULL)
- {
- usSessionType=PROG_WINDOWEDVDM;
- bBatchFile=TRUE;
- strcpy(ucBuffer, "/c "); /* Add just /c to [path]filename.cmd */
- strcat(ucBuffer, pucFullFileName);
- }
- if(bBatchFile==TRUE)
- { /* Set batchfile as parameter and empty path & filename */
- WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, ucBuffer);
- WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, "");
- }
- else
- { /* Set full qualified path and empty parameters */
- WinSetDlgItemText(hwndDlg, PIEF_PATHFILENAME, pucFullFileName);
- WinSetDlgItemText(hwndDlg, PIEF_PARAMETERS, "");
- }
- strcpy(ucBuffer, pucFullFileName); /* Save full path & filename */
- /* Extract filename */
- pucTemp=pucFullFileName+strlen(pucFullFileName);
- for( ; (*pucTemp!='\\') && (pucTemp>=pucFullFileName); /* pucTemp-- */)
- pucTemp--;
- /* Set filename */
- if(!WinQueryWindowTextLength(WinWindowFromID(hwndDlg, PIEF_PROGRAMTITLE)))
- WinSetDlgItemText(hwndDlg, PIEF_PROGRAMTITLE, (pucTemp+1));
- *pucTemp='\0'; /* Get path as working directory */
- /* Set working directory */
- WinSetDlgItemText(hwndDlg, PIEF_DIRECTORY, pucFullFileName);
- }
- /* Reflect the application type with the Program
- Type radiobuttons */
- WinSendMsg(hwndDlg, WM_SETUPPROGRAMTYPE,
- MPFROMSHORT(usSessionType), (MPARAM)NULL);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure disables or enables child windows of a dialog window according to the *
- * bDisable flag. *
- * Req: *
- * hwndDlg ....... handle of Program installation dialog *
- * usDialogIDs ... array of IDs of the child windows of a dialog *
- * usItemCount ... number of IDs in the array *
- * ulStyle ....... WS_VISIBLE | WS_DISABLED or not *
- \*--------------------------------------------------------------------------------------*/
- void DisableDialogItem(HWND hwndDlg, USHORT usDialogIDs[], USHORT usItemCount, ULONG ulStyle)
- {
- USHORT usTemp;
-
- if(ulStyle&WS_DISABLED)
- /* Enumerate and disable all child windows */
- for(usTemp=0; usTemp<usItemCount; usTemp++)
- WinEnableWindow(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]), FALSE);
- else
- /* Enumerate and enable all child windows */
- for(usTemp=0; usTemp<usItemCount; usTemp++)
- WinEnableWindow(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]), TRUE);
- if(ulStyle&WS_VISIBLE)
- /* Enumerate and show all child windows */
- for(usTemp=0; usTemp<usItemCount; usTemp++)
- WinSetWindowPos(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]),
- 0, 0, 0, 0, 0, SWP_SHOW);
- else
- /* Enumerate and hide all child windows */
- for(usTemp=0; usTemp<usItemCount; usTemp++)
- WinSetWindowPos(WinWindowFromID(hwndDlg, usDialogIDs[usTemp]),
- 0, 0, 0, 0, 0, SWP_HIDE);
- }
-
- #define APPLICATIONNAMEPC2 "PC/2 Desktop Configuration"
- #define APPLICATIONNAMEPC2SPOOLER "PC/2 Spooler Configuration"
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure accesses the PC2.INI configuration file. *
- * Req: *
- * pucFilenameINI. pointer to path of PC2.INI *
- * bRead ......... TRUE/FALSE if read/write from/to PC2.INI *
- * Ref: *
- * HookParameters. read/write from/to PC2.INI *
- * Ret: *
- * NULL .......... Error occured, otherwise no error occured *
- \*--------------------------------------------------------------------------------------*/
- ULONG INIAccess(UCHAR *pucFilenameINI, BOOL bRead)
- {
- HINI hiniPC2INI;
- ULONG ulTemp;
- ULONG ulRc=(ULONG)TRUE;
-
- /* Open PC2.INI */
- hiniPC2INI=PrfOpenProfile(pHP->habPc2, pucFilenameINI);
- if(hiniPC2INI!=NULLHANDLE)
- { /* Only try to access a valid PC2.INI */
- if(bRead==TRUE)
- {
- ULONG ulReadStatusFlag;
-
- ulTemp=sizeof(ULONG);
- if(PrfQueryProfileData( /* Query binary data from profile */
- hiniPC2INI, /* Handle of profile */
- /* Application name */
- APPLICATIONNAMEPC2,
- "Desktop Status", /* Key name */
- &ulReadStatusFlag,
- &ulTemp)==FALSE) /* Size of value data */
- {
- ulRc=0L;
- pHP->ulStatusFlag=VIRTUALDESKTOP|CLICK2MOVE|OVERVIEW|SHOWSPOOLERWINDOW|BUTTON2ZORDER|NORMALSHUTDOWN;
- ulReadStatusFlag=pHP->ulStatusFlag;
- }
- pHP->ulStatusFlag=(ulReadStatusFlag & WRITEMASK);
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Debug Flag",
- &pHP->ulDebug, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulDebug=DEBUG_NO;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Scroll Percentage",
- &pHP->ulScrollPercentage, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulScrollPercentage=100;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Click Flag",
- &pHP->ulClickFlag, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulClickFlag=WM_BUTTON1DBLCLK;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "X Position",
- &pHP->swpPC2.x, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2.x=0;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Y Position",
- &pHP->swpPC2.y, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2.y=0;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "X Size",
- &pHP->swpPC2.cx, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2.cx=-1;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Y Size",
- &pHP->swpPC2.cy, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2.cy=-1;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER, "X Position",
- &pHP->swpPC2Spooler.x, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2Spooler.x=0;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER, "Y Position",
- &pHP->swpPC2Spooler.y, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2Spooler.y=0;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER, "X Size",
- &pHP->swpPC2Spooler.cx, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2Spooler.cx=-1;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER, "Y Size",
- &pHP->swpPC2Spooler.cy, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->swpPC2Spooler.cy=-1;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER, "Splitbar Position",
- &pHP->lSplitbarPosition, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->lSplitbarPosition=100;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "X Desktop Count",
- &pHP->ulHorizontalDesktops, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulHorizontalDesktops=3;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Y Desktop Count",
- &pHP->ulVerticalDesktops, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulVerticalDesktops=1;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Overview FCF",
- &pHP->ulOverviewFCF, &ulTemp)==FALSE)
- {
- ulRc=0L;
- pHP->ulOverviewFCF=FCF_OVERVIEWWINDOW;
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Background Bitmap Flag",
- &pHP->ulBackgroundBitmapFlag, &ulTemp)==FALSE)
- {
- ulRc=0L;
- /* Low USHORT of ulBackgroundBitmapFlag contains tile count */
- pHP->ulBackgroundBitmapFlag=BITMAPNORMAL | 3;
- }
- /* The length of Desktop name and Window List name
- is the same namely MAXNAMEL+1 */
- ulTemp=sizeof(pHP->ucDesktopName);
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Desktop Name",
- pHP->ucDesktopName, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucDesktopName, "Desktop");
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Window List Name",
- pHP->ucWindowListName, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucWindowListName, "Window List");
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Background Bitmap",
- pHP->ucBackgroundBitmap, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucBackgroundBitmap, "\\OS2\\BITMAP\\OS2LOGO.BMP");
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Window Font",
- pHP->ucPC2WindowFont, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucPC2WindowFont, "8.Helv");
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Popup-Menu Font",
- pHP->ucPopupMenuFont, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucPopupMenuFont, "8.Helv");
- }
- if(PrfQueryProfileData(hiniPC2INI, APPLICATIONNAMEPC2, "Spooler Font",
- pHP->ucPC2SpoolerFont, &ulTemp)==FALSE)
- {
- ulRc=0L;
- strcpy(pHP->ucPC2SpoolerFont, "8.Helv");
- }
- }
- else
- {
- ULONG ulWriteStatusFlag;
-
- /* Write only permanent status bits, ignore
- temporary ones */
- ulWriteStatusFlag=pHP->ulStatusFlag & WRITEMASK;
- WinSetPointer( /* Set wait pointer */
- HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
- /* Write binary data to profile */
- if(!PrfWriteProfileData(
- hiniPC2INI, /* Handle of profile */
- /* Application name */
- APPLICATIONNAMEPC2,
- "Desktop Status", /* Key name */
- /* Value data */
- &ulWriteStatusFlag,
- sizeof(ULONG))) /* Size of value data */
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Debug Flag", &pHP->ulDebug, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Scroll Percentage", &pHP->ulScrollPercentage, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Click Flag", &pHP->ulClickFlag, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "X Position", &pHP->swpPC2.x, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Y Position", &pHP->swpPC2.y, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "X Size", &pHP->swpPC2.cx, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Y Size", &pHP->swpPC2.cy, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER,
- "X Position", &pHP->swpPC2Spooler.x, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER,
- "Y Position", &pHP->swpPC2Spooler.y, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER,
- "X Size", &pHP->swpPC2Spooler.cx, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER,
- "Y Size", &pHP->swpPC2Spooler.cy, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2SPOOLER,
- "Splitbar Position", &pHP->lSplitbarPosition, sizeof(LONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "X Desktop Count", &pHP->ulHorizontalDesktops, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Y Desktop Count", &pHP->ulVerticalDesktops, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Overview FCF", &pHP->ulOverviewFCF, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Background Bitmap Flag", &pHP->ulBackgroundBitmapFlag, sizeof(ULONG)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Desktop Name", pHP->ucDesktopName, sizeof(pHP->ucDesktopName)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Window List Name", pHP->ucWindowListName,
- sizeof(pHP->ucWindowListName)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Background Bitmap", pHP->ucBackgroundBitmap,
- sizeof(pHP->ucBackgroundBitmap)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Window Font", pHP->ucPC2WindowFont,
- sizeof(pHP->ucPC2WindowFont)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Popup-Menu Font", pHP->ucPopupMenuFont,
- sizeof(pHP->ucPopupMenuFont)))
- ulRc=0L;
- if(!PrfWriteProfileData(hiniPC2INI, APPLICATIONNAMEPC2,
- "Spooler Font", pHP->ucPC2SpoolerFont,
- sizeof(pHP->ucPC2SpoolerFont)))
- ulRc=0L;
- WinSetPointer( /* Set arrow pointer */
- HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
- }
- /* Close PC2.INI */
- if(PrfCloseProfile(hiniPC2INI)==FALSE)
- USR_ERR(pHP->hwndFrame, HELP_PC2INI, MB_INFORMATION|MB_OK|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't save configuration data into PC2.INI - continuing... ");
- }
- else
- USR_ERR(pHP->hwndFrame, HELP_PC2INI, MB_INFORMATION|MB_OK|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't save configuration data into PC2.INI - continuing... ");
- return(ulRc);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure draws a representation of an window onto the overview window. *
- * Req: *
- * hpsClient ..... Presentation space to draw in *
- * pswpWindow .... Pointer to SWP structure containing the size & position to draw *
- * ulWindowColor . Color to fill rectangle with *
- * ulTextColor ... Color to draw rectangle text *
- * ulStyle ....... BACKGROUND_WND if it is a background window *
- * FOREGROUND_WND if it is a foreground window *
- * BORDERONLY_WND if the border should be drawn only *
- * pszWindowName . Pointer to the window's Window List entry or titlebar text *
- * Ref: *
- * none *
- \*--------------------------------------------------------------------------------------*/
- void DrawWindow(HPS hpsClient, SWP *pswpWindow, ULONG ulWindowColor, ULONG ulTextColor, ULONG ulStyle, PSZ pszWindowName)
- {
- POINTL pointl[5]; /* Coordinates of edges of one window */
- /* Dimensions of window's name */
- POINTL pointlFnt[TXTBOX_COUNT];
- ULONG ulNameLength; /* Count of characters of window's name used to display */
- /* Window's name textbox size */
- ULONG ulFntHeight, ulFntLength;
-
- pointl[0].x=pswpWindow->x; /* Lower left starting point */
- pointl[0].y=pswpWindow->y;
- pointl[1].x=pointl[0].x; /* Upper left point */
- pointl[1].y=pswpWindow->y+pswpWindow->cy;
- /* Upper right ending and starting point */
- pointl[2].x=pswpWindow->x+pswpWindow->cx;
- pointl[2].y=pointl[1].y;
- pointl[3].x=pointl[2].x; /* Lower right point */
- pointl[3].y=pointl[0].y;
- pointl[4].x=pointl[0].x; /* Lower left ending point */
- pointl[4].y=pointl[0].y;
- if(!(ulStyle & BORDERONLY_WND))
- {
- /* Fill Window background */
- GpiSetColor(hpsClient, ulWindowColor);
- GpiMove(hpsClient, &pointl[0]);
- GpiBox(hpsClient, DRO_OUTLINEFILL, &pointl[2], 0, 0);
- }
- /* Set 3D border color */
- GpiSetColor(hpsClient,
- WinQuerySysColor(HWND_DESKTOP, ((ulStyle & FOREGROUND_WND) ? SYSCLR_APPWORKSPACE : SYSCLR_SHADOW), 0L));
- GpiMove(hpsClient, &pointl[0]);
- /* Draw 3D border lines */
- GpiPolyLine(hpsClient, 2L, &pointl[1]);
- /* Set 3D border color */
- GpiSetColor(hpsClient,
- WinQuerySysColor(HWND_DESKTOP, ((ulStyle & FOREGROUND_WND) ? SYSCLR_SHADOW : SYSCLR_APPWORKSPACE), 0L));
- GpiMove(hpsClient, &pointl[2]);
- /* Draw 3D border lines */
- GpiPolyLine(hpsClient, 2L, &pointl[3]);
- if(ulStyle & FOREGROUND_WND)
- {
- /* Get dimensions of window's name */
- GpiQueryTextBox(hpsClient, 1L, pszWindowName, TXTBOX_COUNT, pointlFnt);
- ulFntHeight=pointlFnt[TXTBOX_TOPLEFT].y;
- ulFntLength=pointlFnt[TXTBOX_CONCAT].x;
- /* If the text is too high or long, don't display it and exit */
- if((ulFntHeight>(pswpWindow->cy-2)) || (ulFntLength>(pswpWindow->cx-4))) return;
- for(ulNameLength=2; ulNameLength<=strlen(pszWindowName); ulNameLength++)
- {
- /* Get dimensions of window's name */
- GpiQueryTextBox(hpsClient, ulNameLength, pszWindowName, TXTBOX_COUNT, pointlFnt);
- /* If current number of characters don't fit anymore
- into the window, break */
- if(pointlFnt[TXTBOX_CONCAT].x>=(pswpWindow->cx-4))
- break;
- /* Get valid dimensions */
- ulFntHeight=pointlFnt[TXTBOX_TOPLEFT].y;
- ulFntLength=pointlFnt[TXTBOX_CONCAT].x;
- }
- ulNameLength--; /* Adjust for not fitting/last character */
- /* Display windows title from Window List or titlebar */
- GpiSetColor(hpsClient, ulTextColor);
- pointl[0].x=pswpWindow->x+(pswpWindow->cx-ulFntLength)/2+2;
- pointl[0].y=pswpWindow->y+pswpWindow->cy-ulFntHeight+1;
- GpiMove(hpsClient, &pointl[0]);
- GpiCharString(hpsClient, ulNameLength, pszWindowName);
- }
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure converts DOS settings used in the configuration file and Program *
- * Installation dialog to the format required by the WINDOWS32PROPERTYDIALOG in the *
- * OS/2 PMVDMP.DLL. *
- * Req: *
- * pucSettings ... Pointer to the DOS Settings *
- * pulLength ..... Length of the DOS Settings buffer pucSettings on entry/exit *
- * bImport ....... TRUE if we convert data retured by WINDOWS32PROPERTYDIALOG *
- * FALSE if we convert data into WINDOWS32PROPERTYDIALOG format *
- * Ret: *
- * pucBuffer ..... Buffer when successfull containing the converted DOS Settings *
- * NULL on error *
- * This buffer is allocated as required by ImportDosSettings(). *
- * Ref: *
- * <string>\n<string>\n<string> Format of a DOS setting that contains *
- * more than one entry, e.g. DOS_VERSION *
- * <string>\0h One complete DOS setting, whereby *
- * <string> may of the above format *
- * \0h\0h End of DOS settings buffer *
- \*--------------------------------------------------------------------------------------*/
- UCHAR *ImportDosSettings(UCHAR *pucSettings, ULONG *pulLength, BOOL bImport)
- {
- UCHAR *pucBuffer; /* Return buffer */
- UCHAR *pucChar;
- ULONG ulIndex;
- ULONG ulCounter;
-
- if(bImport==TRUE)
- {
- /* Count all \0 characters */
- for(ulIndex=0, ulCounter=0, pucChar=pucSettings; ulIndex<*pulLength; ulIndex++, pucChar++)
- if(*pucChar=='\0') ulCounter++;
- *pulLength+=++ulCounter; /* Double because all \0 are replaced by \r\n which
- is CRLF, and add \0 termination */
- pucBuffer=malloc(*pulLength); /* Allocate return buffer */
- /* Copy DOS settings into return buffer by replacing
- \0 by \r\n (CRLF), replace \n by *. Reserve last
- char for terminating \0 */
- for(ulIndex=0, pucChar=pucBuffer; ulIndex+1<*pulLength; ulIndex++, pucChar++, pucSettings++)
- {
- if(*pucSettings=='\n') *pucChar='*';
- else if(*pucSettings=='\0')
- {
- *pucChar++='\r';
- *pucChar='\n';
- ulIndex++;
- }
- else
- *pucChar=*pucSettings;
- }
- *pucChar='\0'; /* Zero termination */
- }
- else
- {
- /* Count all \r characters */
- for(ulIndex=0, ulCounter=0, pucChar=pucSettings; ulIndex<*pulLength; ulIndex++, pucChar++)
- if(*pucChar=='\r') ulCounter++;
- *pulLength-=++ulCounter; /* Half because all \r\n (CRLF) are replaced by \0, remove
- trailing \0 termination */
- if(!*pulLength) return(NULL);
- pucBuffer=malloc(*pulLength); /* Allocate return buffer */
- /* Copy DOS settings into return buffer by replacing
- \r\n by \0 and * by \n */
- for(ulIndex=0, pucChar=pucBuffer; ulIndex<*pulLength; ulIndex++, pucChar++, pucSettings++)
- {
- if(*pucSettings=='*') *pucChar='\n';
- else if(*pucSettings=='\r')
- {
- *pucChar='\0';
- pucSettings++;
- }
- else
- *pucChar=*pucSettings;
- }
- }
- return(pucBuffer);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure fills a program MENUDATA structure from a PROGDETAILS structure. *
- * Req: *
- * pMenuData ..... MENUDATA structure to be filled from pProgDetails *
- * pProgDetails .. PROGDETAILS structure of WPS Object extracted to fill a program *
- * MENUDATA Menuitem from *
- * Ret: *
- * ulRc .......... Return code: NO_ERROR for no error, errorcode otherwise *
- * Ref: *
- \*--------------------------------------------------------------------------------------*/
- ULONG LoadProgDetails2MenuData(MENUDATA *pMenuData, PROGDETAILS *pProgDetails)
- {
- UCHAR pszExecutable[CCHMAXPATH];
- UCHAR ucBuffer[CCHMAXPATH*2];
- BOOL bCommandFile=FALSE;
-
- pMenuData->Item=ENTRYMENUITEM; /* Its a executable, therefor a Menuitem */
- /* Get the programs's name from WPSOBJECTLIST as
- the Menuitem's title */
- if(pProgDetails->pszTitle)
- {
- free(pMenuData->PgmTitle);
- pMenuData->PgmTitle=malloc(strlen(pProgDetails->pszTitle)+1);
- strcpy(pMenuData->PgmTitle, pProgDetails->pszTitle);
- /* Get the program's session title */
- free(pMenuData->WindowTitle);
- pMenuData->WindowTitle=malloc(strlen(pProgDetails->pszTitle)+1);
- strcpy(pMenuData->WindowTitle, pProgDetails->pszTitle);
- }
- else
- {
- free(pMenuData->PgmTitle); /* At least a title is required */
- pMenuData->PgmTitle=malloc(strlen("Unknown")+1);
- strcpy(pMenuData->PgmTitle, "Unknown");
- }
- /* Get the program's worling directory */
- if(pProgDetails->pszStartupDir)
- {
- free(pMenuData->PgmDirectory);
- pMenuData->PgmDirectory=malloc(strlen(pProgDetails->pszStartupDir)+1);
- strcpy(pMenuData->PgmDirectory, pProgDetails->pszStartupDir);
- }
- if(pProgDetails->pszExecutable)
- {
- /* Test for *.CMD or *.BAT as program's executable,
- which we must move to the MENUDATA.PgmInputs field */
- strcpy(pszExecutable, pProgDetails->pszExecutable);
- strupr(pszExecutable);
- if((strstr(pszExecutable, ".CMD")) || (strstr(pszExecutable, ".BAT")))
- {
- bCommandFile=TRUE;
- if(strchr(pszExecutable, ' '))
- { /* If filename contains spaces, insert two
- quotation marks */
- strcpy(ucBuffer, "/c \"");
- strcat(ucBuffer, pProgDetails->pszExecutable);
- strcat(ucBuffer, "\"\"");
- }
- else
- {
- strcpy(ucBuffer, "/c ");
- strcat(ucBuffer, pProgDetails->pszExecutable);
- }
- if(pProgDetails->pszParameters)
- { /* Add additional parameters too */
- strcat(ucBuffer, " ");
- strcat(ucBuffer, pProgDetails->pszParameters);
- }
- free(pMenuData->PgmInputs);
- pMenuData->PgmInputs=malloc(strlen(ucBuffer)+1);
- strcpy(pMenuData->PgmInputs, ucBuffer);
- }
- else
- {
- /* Get the program's executable name */
- free(pMenuData->PgmName);
- pMenuData->PgmName=malloc(strlen(pProgDetails->pszExecutable)+1);
- strcpy(pMenuData->PgmName, pProgDetails->pszExecutable);
- }
- }
- /* Get the program's commandline parameters */
- if((pProgDetails->pszParameters) && (bCommandFile==FALSE))
- {
- free(pMenuData->PgmInputs);
- pMenuData->PgmInputs=malloc(strlen(pProgDetails->pszParameters)+1);
- strcpy(pMenuData->PgmInputs, pProgDetails->pszParameters);
- }
- /* Get the program's environment, which is usually
- used to store the DOS settings */
- if(pProgDetails->pszEnvironment)
- {
- ULONG ulLengthOut; /* Lenght of DOS Settings returned by
- ImportDosSettings() */
- UCHAR *pucTemp; /* Used to find terminating \0\0 in DOS Settings
- used in PROGDETAILS */
- UCHAR *pucDosSettingsOut; /* DOS Settings converted from \0 terminated
- form used in PROGDETAILS to \n\r terminated
- form used in MENUDATA structure */
-
- free(pMenuData->PgmDosSettings);
- /* Count size of DOS Settings by counting all characters
- until terminating \0\0 is found */
- for(ulLengthOut=1, pucTemp=pProgDetails->pszEnvironment;
- !((*pucTemp=='\0') && (*(pucTemp+1)=='\0'));
- pucTemp++)
- {
- /* \n appeares for DOS Settings that may have multiple
- lines, e.g. DOS_DEVICE=x.sys\ny.sys\0 */
- if(*pucTemp=='\n') *pucTemp='*';
- ulLengthOut++;
- }
- free(pMenuData->PgmDosSettings);
- pucDosSettingsOut=ImportDosSettings(pProgDetails->pszEnvironment, &ulLengthOut , TRUE);
- /* ImportDosSettings() allocated a buffer of length
- ulLengthOut, in which the DOS Settings have been
- copied. */
- pMenuData->PgmDosSettings=pucDosSettingsOut;
- }
- /* Set program's session control */
- if(pProgDetails->progt.fbVisible & SHE_INVISIBLE)
- pMenuData->PgmControl|=SSF_CONTROL_INVISIBLE;
- /* Set program's session type */
- pMenuData->SessionType=pProgDetails->progt.progc;
- return(NO_ERROR);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure adds recursively a LIST of WPSOBJECTLIST elements to the Popup-Menu. *
- * Req: *
- * pMenuData ..... "Root" level of Popup-Menu to insert *
- * pListRoot ..... Pointer to LIST of WPSOBJECTLIST to insert a pMenuData *
- * Ret: *
- * ulRc .......... Return code: NO_ERROR for no error, errorcode otherwise *
- * Ref: *
- \*--------------------------------------------------------------------------------------*/
- ULONG ConvertWPSObjectList2MenuData(MENUDATA *pMenuData, WPSOBJECTLIST *pListRoot)
- {
- WPSOBJECTLIST *pWPOLCurrent; /* Current LIST element of pListRoot for current list level */
- MENUDATA *pMDInsertAfter; /* Last MENUDATA structure of current list level pMenuData */
- MENUDATA *pMDInsert; /* Current MENUDATA structure to insert */
-
- /* Find last elment of current MENUDATA LIST pMenuData */
- for(pMDInsertAfter=pMenuData; pMDInsertAfter->Next; /* pMDInsertAfter=pMDInsertAfter->Next */)
- pMDInsertAfter=pMDInsertAfter->Next;;
- /* Enumerate current level of WPSOBJECTLIST LIST pListRoot */
- pWPOLCurrent=pListRoot;
- while(pWPOLCurrent)
- {
- if(pMDInsertAfter->Item==ENTRYEMPTY)
- { /* An emtpy MENUDATA LIST item is the first item of a Submenu,
- so we have to fill this one */
- /* Fill this one from WPSOBJECTLIST LIST and assign it the
- next free id */
- pMDInsert=pMDInsertAfter;
- pMDInsert->id=pHP->MenuDataId++;
- }
- else
- { /* For any nonempty MENUDATA LIST item, we have to append a
- new MENUDATA item */
- /* Allocate a MENUDATA structure for current list
- element we are going to extract from the LIST and
- assign it the next free identifier */
- pMDInsert=AllocateMenuData();
- pMDInsert->id=pHP->MenuDataId++;
- /* Link the newly created in */
- pMDInsert->Back=pMDInsertAfter;
- pMDInsertAfter->Next=pMDInsert;
- }
- pMDInsertAfter=pMDInsert; /* Next iteration we insert after the MENUDATA item
- we currently insert/replace */
- /* *\
- * If the current element is a WPProgram Object extracted from the WPS, we have to *
- * convert a PROGDETAILS structure into a ENTRYMENUITEM type MENUDATA structure. *
- \* */
- if(pWPOLCurrent->ulType==WPSOBJECTPROGRAM)
- {
- pMDInsert->Item=ENTRYMENUITEM; /* It's a Menuitem */
- LoadProgDetails2MenuData(pMDInsert, (PROGDETAILS *)pWPOLCurrent->pData);
- /* Insert this Menuitem at the end of the current level
- pMenuData of the Popup-Menu */
- if(pMDInsert->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMDInsert->Back)->Submenu==pMDInsert)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(NULL));
- }
- /* *\
- * If the current element is a WPFolder Object extracted from the WPS, we have to *
- * convert a character pointer into a ENTRYSUBMENU type MENUDATA structure. *
- \* */
- if(pWPOLCurrent->ulType==WPSOBJECTFOLDER)
- {
- MENUDATA *pMDSubmenu; /* First Menuitem within the Submenu */
-
- pMDInsert->Item=ENTRYSUBMENU; /* It's a Submenu */
- /* Get the folder's name from WPSOBJECTLIST as
- the Submenu's title */
- free(pMDInsert->PgmTitle);
- pMDInsert->PgmTitle=malloc(strlen((UCHAR *)pWPOLCurrent->pData)+1);
- strcpy(pMDInsert->PgmTitle, (UCHAR *)pWPOLCurrent->pData);
- /* Now obtein a entry for a submenu, adjust the
- linked list to it and call this procedure with
- the new entry recursively again */
- pMDSubmenu=AllocateMenuData();
- pMDInsert->Submenu=pMDSubmenu;
- pMDSubmenu->Back=pMDInsert;
- /* Insert this Menuitem at the end of the current level
- pMenuData of Popup-Menu */
- if(pMDInsert->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMDInsert->Back)->Submenu==pMDInsert)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(NULL));
- /* Recursively add the folder's contents to the
- Submenu Menuitem */
- ConvertWPSObjectList2MenuData(pMDSubmenu, pWPOLCurrent->pFolder);
- }
- /* *\
- * If the current element is a WPObject Object extracted from the WPS, we have to *
- * convert a character pointer of the Object's ObjectID into a ENTRYMENUITEM type *
- * MENUDATA structure. *
- \* */
- if(pWPOLCurrent->ulType==WPSOBJECTOBJECT)
- {
- UCHAR *pucSeparator; /* We expect pData point to a string of
- pszObjectTitle@<ObjectID> where @ is our
- separator. This format is reliable, because
- WPS 2 PC/2 ensures it */
-
- pMDInsert->Item=ENTRYMENUITEM; /* It's a Menuitem */
- /* And it's a WPS Object */
- pMDInsert->SessionType=PROG_WPSOBJECT;
- pucSeparator=strrchr((UCHAR *)pWPOLCurrent->pData, '@');
- *pucSeparator++='\0'; /* Separate pszObjectTitle from <ObjectID> */
- /* Get the ObjectID from WPSOBJECTLIST as
- the Menuitem's title and path & filename */
- free(pMDInsert->PgmTitle);
- pMDInsert->PgmTitle=malloc(strlen((UCHAR *)pWPOLCurrent->pData)+1);
- strcpy(pMDInsert->PgmTitle, (UCHAR *)pWPOLCurrent->pData);
- free(pMDInsert->WindowTitle);
- pMDInsert->WindowTitle=malloc(strlen((UCHAR *)pWPOLCurrent->pData)+1);
- strcpy(pMDInsert->WindowTitle, (UCHAR *)pWPOLCurrent->pData);
- free(pMDInsert->PgmName);
- pMDInsert->PgmName=malloc(strlen(pucSeparator)+1);
- strcpy(pMDInsert->PgmName, pucSeparator);
- /* Insert this Menuitem at the end of the current level
- pMenuData of the Popup-Menu */
- if(pMDInsert->Back!=NULL)
- { /* This isn't the first item, insert after an
- existing item */
- if((pMDInsert->Back)->Submenu==pMDInsert)
- /* If this is the first item of a Submenu, then
- insert it as this */
- SetPopupMenu(MM_INSERTITEMSUBMENU, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- else
- /* Insert item after the existing item */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(pMDInsert->Back));
- }
- else /* This is the first item, insert at the end */
- SetPopupMenu(MM_INSERTITEMMENUITEM, MPFROMP(pMDInsert), MPFROMP(NULL));
- }
- /* Adjust to next WPSOBJECTLIST LIST element */
- pWPOLCurrent=pWPOLCurrent->pNext;
- }
- return(NO_ERROR);
- }
-
- /*--------------------------------------------------------------------------------------*\
- * This procedure changes to the root directory of all local drives. This includes also *
- * networked drives. But it avoids to change the directory on drives that have no *
- * file system attached, e.g. CD-ROM drives playing music CDs. *
- \*--------------------------------------------------------------------------------------*/
- ULONG SetDriveRoot(void)
- {
- /* *\
- * Change to the root directory of all non-removable drives. *
- \* */
- ULONG ulDriveNumber; /* Current drive (1=A, 2=B, ...) */
- ULONG ulLogicalDriveMap; /* Bitmap of available drives (Bit 0=A, 1=B, ...) */
- UCHAR ucDrive[]="C:"; /* Current drive */
- ULONG ulParamLengthInOut; /* Parameter Packet Length */
- ULONG ulDataLengthInOut; /* Data Packet Length */
- ULONG ulTemp;
- HFILE hfDiskHandle; /* File handle of current drive */
- ULONG ulActionTaken; /* Action taken on opened file (drive) */
- APIRET rc;
-
- /* Query drive bit map */
- DosQueryCurrentDisk(&ulDriveNumber, &ulLogicalDriveMap);
- /* Save current drive map to detect added local drives */
- pHP->ulLogicalDriveMap=ulLogicalDriveMap;
- if(!DosOpen("\\DEV\\CD-ROM2$", &hfDiskHandle, &ulActionTaken, 0, FILE_NORMAL,
- OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0))
- {
- struct _DPF /* Data Packet Format */
- {
- USHORT usCDCount; /* Number of CD-ROMs */
- USHORT usCDFirst; /* Number of drive of first CD-ROM (0...A, 1...B, ...) */
- } DPF;
-
- ulDataLengthInOut=sizeof(DPF);
- /* Get the first CD-ROM and number of CD-ROM drives */
- rc=DosDevIOCtl(hfDiskHandle, IOCTL_CHARDEVICE, DSK_DEVICESTATUS,
- NULL, 0, NULL,
- &DPF, ulDataLengthInOut, &ulDataLengthInOut);
- DosClose(hfDiskHandle);
- if(rc!=NO_ERROR)
- DOS_ERR(rc, pHP->hwndFrame, HELP_MEDIA, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't request media parameters - continuing...");
- /* Mark all CD-ROMs out of logical drive map to avoid
- changing to its root directory */
- /* Get first CD-ROM, Bit 0=A, 1=B, ... */
- for(ucDrive[0]='A', ulTemp=0x00000001; DPF.usCDFirst; DPF.usCDFirst--)
- {
- ucDrive[0]++;
- ulTemp<<=1;
- }
- /* For all CD-ROMs map them out */
- for( ; DPF.usCDCount; DPF.usCDCount--)
- {
- ulLogicalDriveMap&=(~ulTemp);
- ulTemp<<=1;
- }
- DosClose(hfDiskHandle);
- }
- for(ucDrive[0]='C', ulTemp=(ULONG)ucDrive[0]-'A', ulLogicalDriveMap>>=2; ulTemp<=(ULONG)('Z'-'A');
- ulTemp++, ucDrive[0]++, ulLogicalDriveMap>>=1)
- { /* Loop for drive C: to Z: (blocks of 0s must be
- expected because of network drives) */
- /* If drive is not attached ignore drive letter */
- if((ulLogicalDriveMap&0x00000001)==0) continue;
- /* Open drive device readonly and fail call on error */
- rc=DosOpen(ucDrive, &hfDiskHandle, &ulActionTaken, 0, FILE_NORMAL,
- OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
- OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READONLY, 0);
- if(rc==NO_ERROR)
- { /* On non-removeable media close it and change to the
- root directory of it. Don't change to root directory
- on removable media that isn't inserted or to not
- attached drives */
- struct _PPF /* Parameter Packet Format */
- {
- BYTE bCommandInformation;
- BYTE bDriveUnit;
- } PPF={0, 0};
- struct _DPF /* Data Packet Format */
- {
- BYTE bData;
- } DPF;
-
- ulParamLengthInOut=sizeof(PPF);
- ulDataLengthInOut=sizeof(DPF);
- /* Now query if the media is removable. The media
- needs not to be inserted */
- rc=DosDevIOCtl(hfDiskHandle, IOCTL_DISK, DSK_BLOCKREMOVABLE,
- &PPF, ulParamLengthInOut, &ulParamLengthInOut,
- &DPF, ulDataLengthInOut, &ulDataLengthInOut);
- /* Only Error 0 (no error) or Error 50
- (Network request not supported) are
- not treated as errors */
- if((rc!=NO_ERROR) && (rc!=ERROR_NOT_SUPPORTED))
- DOS_ERR(rc, pHP->hwndFrame, HELP_MEDIA, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't request media parameters - continuing...");
- DosClose(hfDiskHandle);
- if(DPF.bData)
- { /* If it is a nonremovable media, change to its root */
- /* 1=A, 2=B, 3=C,... */
- rc=DosSetDefaultDisk((ucDrive[0]+1)-'A');
- if(rc!=NO_ERROR)
- DOS_ERR(rc, pHP->hwndFrame, HELP_SETPATH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't change current directory - continuing...");
- rc=DosSetCurrentDir("\\");
- if(rc!=NO_ERROR)
- DOS_ERR(rc, pHP->hwndFrame, HELP_SETPATH, MB_ERROR|MB_OK|MB_HELP|MB_MOVEABLE|MB_DEFBUTTON1,
- "Can't change current directory - continuing...");
- }
- }
- }
- return(NO_ERROR);
- }