home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ddkx86v5.zip
/
DDKX86
/
SRC
/
CMD
/
SVGAINST
/
SVGAINST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-14
|
93KB
|
2,716 lines
/*DDK*************************************************************************/
/* */
/* COPYRIGHT Copyright (C) 1995 IBM Corporation */
/* */
/* The following IBM OS/2 WARP source code is provided to you solely for */
/* the purpose of assisting you in your development of OS/2 WARP device */
/* drivers. You may use this code in accordance with the IBM License */
/* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */
/* Copyright statement may not be removed. */
/* */
/*****************************************************************************/
/*SCCSID = %%s %%s %%s */
/****************************************************************************/
/* */
/* */
/* */
/****************************************************************************/
/*********************************************************************/
/* */
/* SOURCE FILE NAME: svgainst.c */
/* */
/* DESCRIPTIVE NAME: Main source file for SVGA action routine DLL */
/* */
/* FUNCTION: This contains the entry points for SVGAINST.DLL */
/* */
/*********************************************************************/
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_DOSPROCESS
#define INCL_DOSRESOURCES
#define INCL_WIN
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
#include <time.h>
#include <process.h>
#include "dispmain.h"
#include "dispact.h"
#include "svga.h"
/********************************************
*private function declarations for this module
*********************************************/
VOID APIENTRY svga_ParseAdapter(PDSPINSTL_CHAIN pInstalChain,
PADAPTERENTRY pAdpentry);
VOID APIENTRY svga_ParseMonitor(PDSPINSTL_CHAIN pInstalChain,
PVIDEOENTRY pVidentry);
ULONG APIENTRY svga_WriteResolution(PSZ pszConfig,PVIDEOENTRY pVidentry);
ULONG APIENTRY svga_WriteNewResolution(PVIDEOENTRY pVidEntry);
ULONG APIENTRY svga_GetCurrentResolution(VOID);
INT APIENTRY svga_WriteResolIni(PINIPARMS);
INT APIENTRY svga_WriteInterlIni(PINIPARMS);
INT APIENTRY svga_WriteRefrIni(PINIPARMS);
ULONG APIENTRY svga_UpWriteIni(PSZ pszApplication,PSZ pszKey,PSZ pszString);
MRESULT EXPENTRY WaitSvgaDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
//@TM feature
MRESULT EXPENTRY SelectSvgaUtilDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
MRESULT EXPENTRY SvgaUtilDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
APIRET CreateSvgaTmpBat(CHAR *achBuffer );
VOID InitHelp( HWND *phwndHelpInstance );
//@TM
BOOL OpenResolutionsFile(PRESOLUTIONS pResolutions,PULONG pulCount);
APIRET GetResolutionsData(PRESOLUTIONS pResolutions,
PRESOLUTIONS pResolutionsToDisplay,
HWND hwnd,
PDSPINSTL_CHAIN pInstalChain,
BOOL fUseDefault,
PULONG pulCount,
PFN pfnGetNext,
BOOL *fShowResolutionsToUser);
BOOL ReadResolutionsFile(PRESOLUTIONS pResolutions,HFILE hf,PULONG pulCount);
VOID RunSvga(PVOID);
PSZ strip_white(PSZ pszString);
BOOL ValidateResolutions(PRESOLUTIONS pResolutions,
PRESOLUTIONS pResolutionsToDisplay,
PDSPINSTL_CHAIN pDspInstlHeadChain,
BOOL fUseDefault,
PULONG pulCount,
ULONG ulCount,
PFN pfnGetNext);
BOOL CompareResolutions(PSZ pszResolution,PRESOLUTIONS pSupportedResolutions,
ULONG ulCount);
APIRET APIENTRY GetDllHandle( PHMODULE phmodResource);
VOID APIENTRY WaitThread(PVOID);
VOID StringToResolution(PSZ pszString,PRESOLUTIONDATA pResolutionData);
VOID APIENTRY BuildSvgaNodes(PDSPINSTL_CHAIN pDspinstlChain,
PRESOLUTIONS pSelectedResolutions,
ULONG ulCount,
LONG lDesignatedResolution);
PSZ GetSelectedResolution(PRESOLUTIONS pResolution,ULONG ulCount);
PDSPINSTL_CHAIN GetLastElement(PDSPINSTL_CHAIN pDspInstlChain);
USHORT APIENTRY16 Dos16GetPrty(USHORT usScope,PUSHORT pusPriority,USHORT pid);
VOID SvgaReportError(ULONG rc,PSZ pszMsg,HWND hwndOwner);
VOID svgaLog(PSZ pszMsg);
USHORT SvgaMessageBox(ULONG rc,PSZ pszMsg,HWND hwndOwner);
PSZ GetDesignatedResolution(PDSPINSTL_CHAIN pChain,ULONG ulCount,
LONG lDesignatedResolution);
/* Amol; D58319;12/09/92*/
BOOL CheckSVGAMem (PRESOLUTIONS, ULONG);
BOOL IsResolutionOver1Mg(PSZ pszResolution,PRESOLUTIONDATA pResolution);
BOOL SelectResolutionForUser( PDSPINSTL_CHAIN pInstalChain,
PRESOLUTIONS pResolutionsToDisplay,
PULONG pulCount );
/*****************************************
*private data declarations
*****************************************/
PSZ pszConfig = "MONITOR.CFG"; //name of monitor file to pass
PSZ pszAdapter = "ADAPTER.CFG"; //name of adapter file to pass
PSZ pszDefMonKey; //default monitor key
PSZ pszSelMonKey; //selected monitor key
PSZ pszDefAdpKey;
PSZ pszSelAdpKey;
PSZ pszResolutionString = NULL; //CID
RESOLUTIONS ResolutionsArray[MAX_RESOLUTIONS];
RESOLUTIONS ResolutionsToDisplay[MAX_RESOLUTIONS];
HMODULE hmodResource;
BOOL f1024K; /* Amol; Defect #58319; 12/09/92 */
//@TMCHAR *szErrorMsg []=
//@TM{
//@TM "A error has occurred reading the svgadata.pmi file",
//@TM "Unable to determine hardware configuration",
//@TM "Unable to resolve module handle",
//@TM "The current hardware configuration does not support the high resolution mode. \
//@TM If you continue, your video support might be unusable. Do you want to continue ?"
//@TM};
CHAR szResolution[SIZ_PARMS];
CHAR szInterLace [SIZ_PARMS];
CHAR szRefresh [SIZ_PARMS];
CHAR szString1 [SIZ_PARMS];
CHAR szString2 [SIZ_PARMS];
CHAR szString3 [SIZ_PARMS];
INIPARMS IniParms [] =
{
MONITOR_RES, szResolution,szString1,svga_WriteResolIni,
MONITOR_VREFRESH, szRefresh ,szString2,NULL,
MONITOR_INTERLACE,szInterLace ,szString3,NULL,
};
PFN pfnLogFunction = NULL;
TID tidThread;
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:Default_Primary
*
* Purpose:This action routine handles svga specific routines that
* need to be called from the display install utility for the
* default primary selection.This routine does the following:
* a)Gets a pointer to the head of the selected display install
* chain
* b)Does the setup for the GetResolutionsData routine and calls it
* c)If no error occurred call to have the resolutions displayed to
* the user.
* d)Call to have the linked list built,based upon the resoluition
* the user has selected.
*
*
* Returns:
* Non-Zero - Error occurred,User Aborted.
* 0 - Successful Operation,Continue
\****************************************************************/
LONG EXPENTRY Default_Primary(HWND hwnd,PDSPINSTL_GLOBAL_DATA pInstalData)
{
PRESOLUTIONS pResolutions;
ULONG ulSelections = 0;
LONG lRetValue;
PDSPINSTL_CHAIN pHeadofChain;
BOOL fShowResolutionsToUser = TRUE;
LONG lGetDesignated = -1;
pfnLogFunction = pInstalData->pfnLogFunction;
/*
* If resolution string passed in make it global
*/
if( pInstalData->pszResolutionString )
{
pszResolutionString = malloc(
strlen( pInstalData->pszResolutionString)
+ 1);
strcpy( pszResolutionString, pInstalData->pszResolutionString );
}
/*
*start at the head
*of the chain
*/
if((*pInstalData->pfnNextElementRoutine)(&pHeadofChain,
CHAIN_HEAD,
NULL) )
{
return(CANCEL_OPERATION);
}
/*
*set up to get the supported resolutions
*/
memset(ResolutionsArray,0,sizeof(RESOLUTIONS) * MAX_RESOLUTIONS);
memset(ResolutionsToDisplay,0,sizeof(RESOLUTIONS) * MAX_RESOLUTIONS);
/*
*get the resolutions data,setting the default flag
*to true.
*/
if((lRetValue = GetResolutionsData(ResolutionsArray,
ResolutionsToDisplay,
hwnd,pHeadofChain,
TRUE,
&ulSelections,
pInstalData->pfnNextElementRoutine,
&fShowResolutionsToUser) ))
{
if (lRetValue != CONTINUE_WITH_ERR)
return(lRetValue);
}
if(fShowResolutionsToUser)
{
/*
*display the list of resolutions
*/
if( lRetValue = (*pInstalData->pfnSpecifyResolution)(hwnd,&ResolutionsToDisplay,
ulSelections,
FALSE) )
{
/*
*user aborted
*/
return(lRetValue);
}
}
else
{
/*
*this should only be happening on speedway
*make sure the first one in our list is selected
*/
lGetDesignated = 0;
}
/*
*build the key for the
*first node and set the next node to be the
*node that was selected
*/
BuildSvgaNodes(pHeadofChain,
ResolutionsToDisplay,
ulSelections,
lGetDesignated);
return(lRetValue);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:Default_Secondary
*
* Purpose:This action routine handles the calling of the specify
* adapter and specify monitor routines. The key that is
* returned in the adapter structre is saved off so as to
* used later while querying the .DSP files.
*
*
*
* Usage:
*
* Returns:
* Non-Zero - Error occurred,User Aborted.
* 0 - Successful Operation,Continue
\****************************************************************/
LONG EXPENTRY Default_Secondary(HWND hwnd,PDSPINSTL_GLOBAL_DATA pInstalData)
{
ADAPTERENTRY adpentry;
VIDEOENTRY videntry;
LONG rc;
PDSPINSTL_CHAIN pDspChain;
pfnLogFunction = pInstalData->pfnLogFunction;
/*
*start at the head
*of the chain
*/
pDspChain = pInstalData->pHeadDspInstl_Chain;
if((rc = (*pInstalData->pfnSpecifyVideoMonitor)(hwnd,pszConfig, &videntry)))
{
/*
*user aborted
*/
return(CANCEL_OPERATION);
}
return(rc);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:Selected_Primary
* Purpose:This action routine handles svga specific routines that
* need to be called from the display install utility for the
* selected primary selection.This routine does the following:
* a)Gets a pointer to the head of the selected display install
* chain
* b)Does the setup for the GetResolutionsData routine and calls it
* c)If no error occurred call to have the resolutions displayed to
* the user.
* d)Call to have the linked list built,based upon the resolution
* the user has selected.
* Note - Kenner
* Changed the usedefaultflag so that it is always true.
* this will insure that only resolutions the hardware can support
* are displayed to the customer.
*
* Returns:
* Non-Zero - Error occurred,User Aborted.
* 0 - Successful Operation,Continue
\****************************************************************/
LONG EXPENTRY Selected_Primary(HWND hwnd,PDSPINSTL_GLOBAL_DATA pInstalData)
{
PRESOLUTIONS pResolutions;
ULONG ulSelections = 0;
LONG lRetValue;
PDSPINSTL_CHAIN pHeadofChain;
BOOL fShowResolutionsToUser = TRUE;
LONG lGetDesignated = -1;
pfnLogFunction = pInstalData->pfnLogFunction;
/*
* If resolution string passed in make it global
*/
if( pInstalData->pszResolutionString )
{
pszResolutionString = malloc(
strlen( pInstalData->pszResolutionString)
+ 1);
strcpy( pszResolutionString, pInstalData->pszResolutionString );
}
/*
*start at the head
*of the chain
*/
if( (*pInstalData->pfnNextElementRoutine)(&pHeadofChain,
CHAIN_HEAD,
NULL) )
{
return(CANCEL_OPERATION);
}
/*
*read in the resolutions file
*/
memset(ResolutionsArray,0,sizeof(RESOLUTIONS) * MAX_RESOLUTIONS);
memset(ResolutionsToDisplay,0,sizeof(RESOLUTIONS) * MAX_RESOLUTIONS);
if((lRetValue = GetResolutionsData(ResolutionsArray,
ResolutionsToDisplay,
hwnd,pHeadofChain,
TRUE,
&ulSelections,
pInstalData->pfnNextElementRoutine,
&fShowResolutionsToUser) ))
{
if (lRetValue != CONTINUE_WITH_ERR)
return(lRetValue);
}
if(fShowResolutionsToUser)
{
if( lRetValue = (*pInstalData->pfnSpecifyResolution)(hwnd,&ResolutionsToDisplay,
ulSelections,
FALSE) )
{
return(lRetValue);
}
}
else
{
/*
*this should only be happening on speedway
*make sure the first one in our list is selected
*/
lGetDesignated = 0;
}
/*
*build the key for the
*first node and set the next node to be the
*node that was selected
*/
BuildSvgaNodes(pHeadofChain,
ResolutionsToDisplay,
ulSelections,
lGetDesignated);
return(lRetValue);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:BuildSvgaNodes
*
* Purpose:This routine will build the configuration node and the
* associated key to look for in the dsp files.The next node
* in the link will be set to the one that matches what the
* user selected. The next link will be set to the first
* node that does not have a resoulution associated with
* it.
* Updated 8-18-92 -Kenner
* Check the first node that does not have a resolution
* to see if HI-RESOLUTION was selected,if so reset the
* key to pick up the hires fonts.
*
* Head -> pszKey = "C600x400x256"
* NextNode -> pszKey = "600x400x256"
* NextNode -> pszKey = "FONT_HI" || "FONT_LO"
* Returns:
* VOID
\****************************************************************/
VOID APIENTRY BuildSvgaNodes(PDSPINSTL_CHAIN pDspinstlChain,
PRESOLUTIONS pSelectedResolutions,
ULONG ulCount,
LONG lGetDesignated)
{
PSZ pszSelectedResolution;
PDSPINSTL_CHAIN pTempChain,pLastResolution;
CHAR szTemp[MAX_SIZ_KEY];
/*
*get the selected resolutions
*/
if( lGetDesignated == -1 || pszResolutionString != NULL)
{
pszSelectedResolution = GetSelectedResolution(pSelectedResolutions,ulCount);
}
else
{
/*
*get the reslution
*designated
*/
pszSelectedResolution = GetDesignatedResolution(pDspinstlChain,ulCount,
lGetDesignated);
}
/*
*get the first node after the head of the
*list that does not have a associated resolution
*/
pLastResolution = GetLastElement(pDspinstlChain);
/*
*build the key for the head
*of our chain
*/
memset( szTemp,0, sizeof( szTemp));
if( pDspinstlChain->pszKey )
{
strncpy( szTemp, pDspinstlChain->pszKey, strlen(pDspinstlChain->pszKey) + 1);
free(pDspinstlChain->pszKey);
}
pDspinstlChain->pszKey = malloc(MAX_SIZ_KEY);
*(pDspinstlChain->pszKey) = 'C';
*(pDspinstlChain->pszKey+1) = '\0';
strcat( pDspinstlChain->pszKey, szTemp);
for(pTempChain = pDspinstlChain;pTempChain;
pTempChain = pTempChain->pNextDspInstl)
{
/*
*find the right one in the node that matches what we have
*selected
*/
if(pTempChain->pszResolution)
{
/*
*found it
*/
if(!strcmp(pTempChain->pszResolution,
pszSelectedResolution) )
{
pDspinstlChain->pNextDspInstl =
pTempChain;
/*
*we used to incorrectly use the resolution
*as the key,should be using the key from
*the dsc file to match the key
*for the dsp file
*/
strcat(pDspinstlChain->pszKey,pTempChain->pszKey);
/*
*set the next node to
*start with the next node in the list
*that does not have a resolution
*/
pTempChain->pNextDspInstl = pLastResolution;
/*
*we should now be looking at the first diskette
*that does not have a resolution,this should now
*be the fonts diskette
*check to see if the resoulution that was selected was
*HI-RES if so reset the key to pick-up the hires font
*dsp file
*/
// if(!strcmp(pszSelectedResolution,_1024_768_256 ) ||
// !strcmp(pszSelectedResolution,_1024_768_16 ) )
// {
// pLastResolution->pszKey = malloc(MAX_SIZ_KEY);
// strcpy(pLastResolution->pszKey,FONT_HI);
// }
break;
}
}
}
return;
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:GetLastElement()
*
* Purpose:Returns the a pointer to the last node in the list
* that contains a valid resolution.
*
* Returns:
* pDspTemp - will point to either the first node that does
* not have a resolution or the last node in
* the linked list whichever occurs first
\****************************************************************/
PDSPINSTL_CHAIN GetLastElement(PDSPINSTL_CHAIN pDspInstlChain)
{
PDSPINSTL_CHAIN pDspTemp;
/*
*the assumption for svga is that the first node is
*always null
*/
for(pDspTemp = pDspInstlChain->pNextDspInstl;pDspTemp->pszResolution;)
{
if(!pDspTemp->pNextDspInstl)
{
pDspTemp = NULL;
break;
}
pDspTemp = pDspTemp->pNextDspInstl;
}
return(pDspTemp);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:GetSelectedResolution
*
* Purpose: This routine will loop through the list of pSelectedResolutions
* for up to ulCount number of elements looking for the ulSelected
* flag to be set to TRUE. A pointer to the first ulSelected
* element will be returned or NULL if no selection was made.
* Returns:
* pszResolutions = a pointer to the selected resolutions string
* or NULL if none was selected.
\****************************************************************/
PSZ GetSelectedResolution(PRESOLUTIONS pSelectedResolutions,ULONG ulCount)
{
ULONG ulCounter;
PRESOLUTIONS pTemp;
PSZ pszResolutions = NULL;
for(ulCounter =0,pTemp = pSelectedResolutions; ulCounter < ulCount;
pTemp++,ulCounter++)
{
if(pTemp->ulSelected)
{
pszResolutions= pTemp->achResolutionString;
break;
}
}
return(pszResolutions);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:Selected_Secondary
*
* Purpose:This action routine handles the calling of the specify
* adapter and specify monitor routines. The key that is
* returned in the adapter structre is saved off so as to
* used later while querying the .DSP files.
*
*
*
* Usage:This routine should be called when the user has selected
* to install a secondary monitor/adapter.
*
* Returns:
* Non-Zero - Erorr occurred,User Aborted.
* 0 - Successful Operation,Continue
\****************************************************************/
LONG EXPENTRY Selected_Secondary(HWND hwnd,PDSPINSTL_GLOBAL_DATA pInstalData)
{
ADAPTERENTRY adpentry;
VIDEOENTRY videntry;
LONG rc;
PDSPINSTL_CHAIN pDspChain;
pfnLogFunction = pInstalData->pfnLogFunction;
/*
*start at the head
*of the chain
*/
pDspChain = pInstalData->pHeadDspInstl_Chain;
if(!(rc = (*pInstalData->pfnSpecifyDisplayAdapter)(hwnd,pszAdapter, &adpentry) ) )
{
/*
*parse out the adapter info
*and save the key
*/
svga_ParseAdapter(pDspChain,&adpentry);
if((rc = (*pInstalData->pfnSpecifyVideoMonitor)(hwnd,pszConfig, &videntry)))
{
SvgaReportError(rc,NULL,hwnd);
}
}
return(rc);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:svga_ParseAdapter
*
* Purpose:This routine will move over to the last argument in
* the achParms buffer and save it off the the key that
* is passed,pszKey is assumed to contain a buffer big
* enough to hold the key
* Returns:
* VOID
\****************************************************************/
VOID APIENTRY svga_ParseAdapter(PDSPINSTL_CHAIN pInstalChain,
PADAPTERENTRY pAdpentry)
{
SHORT sCount;
PSZ pszEnd;
PDSPINSTL_CHAIN pTempChain;
/*
*move over to the key for the adapter
*and save it off
*/
pszEnd = pAdpentry->achParms;
for(sCount= (pAdpentry->cParms -1);sCount;sCount--)
{
pszEnd = (pszEnd + strlen(pszEnd) +1);
}
/*
*start at the head of the
*chain and give every node
*a copy of the key that was selected
*/
for(pTempChain = pInstalChain;pTempChain; )
{
strcpy(pTempChain->pszKey,pszEnd);
pTempChain = pTempChain->pNextDspInstl;
}
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:svga_WriteNewResolution
*
* Purpose:To parse the resolution strings and make the
* updates to the ini file.
* Returns:
* Non Zero - Error occurred
* 0 - No error
\****************************************************************/
ULONG APIENTRY svga_WriteNewResolution(PVIDEOENTRY pVidEntry)
{
ULONG cbCount;
PSZ pszDelimiter;
PSZ pszApplicationName;
CHAR szMonitorRes[SIZ_TOWRITE];
CHAR szMonitorInt[SIZ_TOWRITE];
CHAR szMonitorRef[SIZ_TOWRITE];
CHAR szStringToWrite[C_MAX_VID_PARMS];
SHORT sArgs;
ULONG ulReturn = 0;
PINIPARMS pIniParms;
do
{
for(cbCount = 0;cbCount <pVidEntry->cVideoParms;cbCount++)
{
memset(szResolution,0,sizeof(szResolution) );
memset(szInterLace,0,sizeof(szInterLace) );
memset(szStringToWrite,0,C_MAX_VID_PARMS);
/*
*parse the three substrings out
*/
pIniParms= IniParms;
for(pszDelimiter = pVidEntry->avidparm[cbCount].achParms,sArgs = 0;
sArgs <pVidEntry->avidparm[cbCount].cParms;
sArgs++,
pIniParms++)
{
strcpy(pIniParms->pszParms,pszDelimiter);
pszDelimiter = (pszDelimiter + (strlen(pszDelimiter) + 1) );
}
/*
*write each one out to the ini file
*/
pIniParms= IniParms;
for(sArgs = 0;sArgs <pVidEntry->cVideoParms;
sArgs++,
pIniParms++)
{
if( pIniParms->pfnWriteParmToIni(IniParms) )
{
/*
*generate error
*/
break;
}
}
}
}ONCE;
return(ulReturn);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:svga_UpWriteIni
*
* Purpose:Update the ini file.
*
*
*
* Usage: Used to update the user ini,expects formed keys,and strings.
*
*
* Returns:
* 0 - if successful execution completed
* 1 - if error
\****************************************************************/
ULONG APIENTRY svga_UpWriteIni(PSZ pszApplication,PSZ pszKey,PSZ pszString)
{
HINI UserIni = HINI_USERPROFILE;
ULONG ulReturn = 0;
if(!PrfWriteProfileString(UserIni,
pszApplication,
pszKey,
pszString) )
{
ulReturn = WRITE_INI_ERROR;
}
return(ulReturn);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:svga_WriteResolIni()
*
* Purpose:Set up to right the resolution to the ini file
* based on the arguments contained in the pIniParms
* structure.
*
* Returns:
* 0 - if successful execution completed
* 1 - if error
\****************************************************************/
INT APIENTRY svga_WriteResolIni(PINIPARMS pIniParms)
{
APIRET ulRet;
/*
*write out the string to the ini
*/
ulRet = svga_UpWriteIni(MONITOR_RES,
pIniParms->pszParms,
pIniParms[INDEX_VREFRESH].pszParms);
return(!ulRet);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:WaitThread
*
* Purpose:This thread will sleep for SLEEP_TIME milliseconds,
* query the process id of that was passed to in the
* pWaitData structure.Once the process id we are interested
* in,is no longer a valid process,this thread will post
* the AM_QUIT message back to the owner of hwnd.
* The session id that was passed to the thread in the
* pWaitData structure will also be terminated.
* Returns:
* VOID
\****************************************************************/
VOID APIENTRY WaitThread(PVOID pvMessageData)
{
PSVGAWAITDATA pWaitData;
RESULTCODES Results;
ULONG ulProcessId;
USHORT usPriority,rc;
HWND hwndMain;
pWaitData = (PSVGAWAITDATA)pvMessageData;
do
{
/*
*
*/
DosSleep(SLEEP_TIME);
if(rc = Dos16GetPrty(PRTYS_PROCESS,
&usPriority,
(USHORT)pWaitData->ulProcessid) )
{
if(rc == ERROR_INVALID_PROCID)
{
break;
}
}
}FOREVER;
/*
*send message back to the main loop
*that we are done
*/
if(pWaitData->hwnd)
{
WinPostMsg(pWaitData->hwnd, AM_QUIT,(MPARAM)FALSE, 0);
}
/*
*kill off the session that svga.exe
*was started in
*/
DosStopSession(0,pWaitData->ulSession);
DosExit(EXIT_THREAD,0);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:WaitSvgaDlgProc()
*
* Purpose:This routine throws up the Hardware determination in
* progress dialog box,and waits for the AM_QUIT message
* to be sent back to it. No buttons are enable on the
* dialog box,so no other messages,except the default are
* expected.
* Returns:
* TRUE is always returned.
\****************************************************************/
MRESULT EXPENTRY WaitSvgaDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HWND hwndListBox;
ULONG iItem,ulCount;
static SVGAWAITDATA WaitData;
switch (msg)
{
case WM_INITDLG:
hwndListBox = WinWindowFromID(hwnd, IDL_GENERAL);
CenterDialog(hwnd);
/*
* Create a seperate thread to run svga.exe
*/
WaitData.hwnd = hwnd;
if(DosCreateThread(&tidThread,
(PFNTHREAD)RunSvga,
(ULONG)&WaitData,
FALSE,
STACK_SIZE_THRD) )
{
WinPostMsg(hwnd, AM_QUIT,(MPARAM)TRUE, 0);
}
//91642 if( RunSvga(hwnd) )
//91642 {
//91642 WinPostMsg(hwnd, AM_QUIT,(MPARAM)TRUE, 0);
//91642 }
break;
case WM_CLOSE:
break;
/*
*our thread should send us this message
*when the svga process dies
*/
case AM_QUIT:
//91642 DosKillThread(tidThread);
WinDismissDlg(hwnd,SHORT1FROMMP(mp1));
break;
default:
return(WinDefDlgProc(hwnd, msg, mp1, mp2));
break;
}
return 0L;
}
/****************************************************************\
*
*-----------------------------------------------------------------------
*
* Name:SelectSvgaUtilDlgProc()
*
* Purpose:This routine is the main dialog procedure for selecting an SVGA
* monitor configuration utility.
*
* Called by: GetResolutionsData()
*
* Calls to: InitHelp()
* CreateSvgaTmpBat()
* SvgaUtilDlgProc()
* SvgaReportError()
*
* Returns:
* (MPARAM)TRUE is returned on an error condition or WM_CANCEL
\************************************************************************/
MRESULT EXPENTRY SelectSvgaUtilDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
BOOL fError;
APIRET apiRet;
switch(msg)
{
case WM_INITDLG:
/*
initialize Help Manager
*/
InitHelp(&hwndHelpInstance);
if (hwndHelpInstance)
WinAssociateHelpInstance(hwndHelpInstance, hwnd);
CenterDialog(hwnd);
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case DID_OK:
apiRet = DID_OK;
/*
* Use Default Settings
*/
if (SHORT1FROMMR(WinSendMsg(WinWindowFromID(hwnd, IDB_DEFAULTSETTINGS),
BM_QUERYCHECK, 0L, 0L)))
{
if (CreateSvgaTmpBat( NULL ))
{
SvgaReportError(MSG_UNABLE_TO_DETERMINE_HARD,
NULL,
hwnd);
apiRet = DID_ERROR;
}
}
else if (SHORT1FROMMR(WinSendMsg(WinWindowFromID(hwnd, IDB_SVGAUTIL),
BM_QUERYCHECK, 0L, 0L)))
{
apiRet = WinDlgBox((HWND)HWND_DESKTOP,
HWND_DESKTOP,
(PFNWP)SvgaUtilDlgProc,
hmodResource,
DLG_SVGAUTIL,
NULL);
}
if (apiRet == DID_OK)
WinPostMsg(hwnd, AM_QUIT,0,0);
else if (apiRet == DID_ERROR)
WinPostMsg(hwnd, AM_QUIT,(MPARAM)TRUE, 0);
break;
case DID_CANCEL:
WinPostMsg(hwnd, AM_QUIT,(MPARAM)TRUE, 0);
break;
}
break;
case AM_QUIT:
WinDismissDlg(hwnd, SHORT1FROMMP(mp1));
break;
default:
return(WinDefDlgProc(hwnd, msg, mp1, mp2));
break;
}
return 0L;
}
/****************************************************************\
*
*-----------------------------------------------------------------------
*
* Name:SvgaUtilDlgProc()
*
* Purpose:This routine prompt the user for the SVGA display adapter
* utility file location and then creates the batch file
* used by RunSvga().
*
* Called by: GetResolutionsData()
*
* Calls to: InitHelp()
* CreateSvgaTmpBat()
* SvgaReportError()
*
* Returns:
* DID_OK, DID_CANCEL, DID_ERROR
\************************************************************************/
MRESULT EXPENTRY SvgaUtilDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
FILEDLG pfdFileDlg;
static CHAR szTitle[CCHMAXPATH];
PSZ pszFullFile = "*.*";
HWND hwndWinFileDlg;
PSVGAUTILDATA pUtilData;
static CHAR pszSourceDir[] = "A:\\";
PSZ pszName;
APIRET apiRet;
ULONG ulBufLen;
USHORT i;
FILESTATUS FileBuf;
BOOL fError;
CHAR szBuffer[CCHMAXPATH];
switch(msg)
{
case WM_INITDLG:
if (hwndHelpInstance)
WinAssociateHelpInstance(hwndHelpInstance, hwnd);
/*
* malloc util data structure
*/
pUtilData = malloc( sizeof( SVGAUTILDATA ) );
pUtilData->pszBuffer = malloc( CCHMAXPATH );
pUtilData->pszMsg = malloc( CCHMAXPATH );
pUtilData->pszTitle = malloc( CCHMAXPATH );
pUtilData->fParms = FALSE;
pUtilData->hab = WinInitialize(0);
/*
* Load resource strings from dll
*/
WinLoadString(pUtilData->hab, hmodResource, MSG_FILE_NOT_EXIST, CCHMAXPATH,
pUtilData->pszMsg);
WinLoadString(pUtilData->hab, hmodResource, MSG_SVGAUTIL_NOT_FOUND, CCHMAXPATH,
pUtilData->pszTitle);
WinLoadString(pUtilData->hab, hmodResource, MSG_FILEDLG_TITLE, CCHMAXPATH,
szTitle);
WinSetWindowULong(hwnd, QWL_USER, (ULONG)pUtilData);
CenterDialog(hwnd);
WinPostMsg(hwnd,WM_INIT,0,0);
break;
case WM_INIT:
WinSendDlgItemMsg(hwnd, /* set text limit of entry field */
IDE_SOURCEDIR,
EM_SETTEXTLIMIT,
MPFROMSHORT(CCHMAXPATH -10),
(MPARAM)0L);
WinSetDlgItemText(hwnd, /* set source directory a:\ */
IDE_SOURCEDIR,
pszSourceDir);
WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, IDE_SOURCEDIR));
break;
case AM_QUIT:
pUtilData = (PSVGAUTILDATA)WinQueryWindowULong(hwnd, QWL_USER);
free( pUtilData->pszBuffer );
free( pUtilData->pszMsg );
free( pUtilData->pszTitle );
free( pUtilData );
WinTerminate(pUtilData->hab);
WinDismissDlg(hwnd, SHORT1FROMMP(mp1));
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1))
{
case DID_OK:
fError = FALSE;
fSvgaUtilPresent = FALSE;
pUtilData = (PSVGAUTILDATA)WinQueryWindowULong(hwnd, QWL_USER);
WinQueryDlgItemText( hwnd,
IDE_SOURCEDIR,
CCHMAXPATH - 10,
pUtilData->pszBuffer );
/*
* If user selects okay without entering
* a utility program
*/
if(!strcmp( pUtilData->pszBuffer, pszSourceDir) ||
strlen(pUtilData->pszBuffer) <= 3)
{
WinPostMsg(hwnd,WM_INIT,0,0);
break;
}
else
{
/*
parse buffer to first space character and
only copy name, not parameters
*/
pUtilData->fParms = FALSE;
ulBufLen = strlen( pUtilData->pszBuffer );
for( i=0; i<ulBufLen; i++ ) {
if( *((CHAR *)pUtilData->pszBuffer + i) == ' ')
{
pszName =malloc( i );
memcpy( pszName, pUtilData->pszBuffer, i );
*(pszName + i) = '\0';
pUtilData->fParms = TRUE;
break;
}
}
if(!pUtilData->fParms)
{
pszName = strdup( pUtilData->pszBuffer );
}
/*
*make sure the program can be found
*/
DosError( HARDERROR_DISABLE );
apiRet = DosQueryPathInfo( pszName,
FIL_STANDARD,
&FileBuf,
sizeof( FileBuf ) );
DosError( HARDERROR_ENABLE );
if(apiRet) {
sprintf( szBuffer, pUtilData->pszMsg, pszName );
WinMessageBox( HWND_DESKTOP,
hwnd,
szBuffer,
pUtilData->pszTitle,
HELP_DLG_SELECTSVGAUTIL,
MB_OK | MB_HELP | MB_INFORMATION | MB_MOVEABLE);
free( pszName );
WinPostMsg(hwnd,WM_INIT,0,0);
break;
}
fSvgaUtilPresent = TRUE;
if( CreateSvgaTmpBat( pUtilData->pszBuffer ) )
{
SvgaReportError(MSG_UNABLE_TO_DETERMINE_HARD,
NULL,
hwnd);
fError = TRUE;
}
free( pszName );
}
(fError ? WinPostMsg(hwnd, AM_QUIT,(MPARAM)DID_ERROR, 0) :
WinPostMsg(hwnd, AM_QUIT,(MPARAM)DID_OK,0));
break;
case DID_LOCATE:
memset( &pfdFileDlg,0,sizeof(FILEDLG));
pfdFileDlg.cbSize = sizeof(FILEDLG);
pfdFileDlg.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_OPEN_DIALOG;
pfdFileDlg.pszTitle = szTitle;
pUtilData = (PSVGAUTILDATA)WinQueryWindowULong(hwnd,
QWL_USER);
WinQueryDlgItemText( hwnd,
IDE_SOURCEDIR,
CCHMAXPATH - 10,
pUtilData->pszBuffer );
pfdFileDlg.pszIDrive = "A:";
if(strcmp( pUtilData->pszBuffer, pszSourceDir ))
{
ulBufLen = strlen( pUtilData->pszBuffer );
for(i=0;i<ulBufLen;i++)
{
if(*pUtilData->pszBuffer != ' ')
{
*pfdFileDlg.pszIDrive =
*pUtilData->pszBuffer;
break;
}
pUtilData->pszBuffer++;
}
}
strcpy( pfdFileDlg.szFullFile, pszFullFile );
hwndWinFileDlg = WinFileDlg( HWND_DESKTOP, hwnd, &pfdFileDlg );
if( hwndWinFileDlg && (pfdFileDlg.lReturn == DID_OK ) )
{
WinSetDlgItemText( hwnd, IDE_SOURCEDIR, pfdFileDlg.szFullFile );
}
break;
case DID_CANCEL:
WinPostMsg(hwnd, AM_QUIT,(MPARAM)DID_CANCEL, 0);
break;
default:
WinDismissDlg(hwnd, SHORT1FROMMP(mp1));
break;
}
break;
default:
return(WinDefDlgProc(hwnd, msg, mp1, mp2));
break;
}
return 0L;
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:GetResolutionsData()
*
* Purpose:This routine should be used to determine which resolutions
* to display to the user. If the default flag is set,the
* svgadata.pmi file will be read,and the intersection of the
* dsc file and svgadata file will be displayed. Otherwise all
* of the resolutions the dsc file supports will be displayed.
*
* pResolutions - pointer to where to read in the
* resolutions from the svgadata.pmi
* file.
*
* pResolutionsToDisplay - pointer to the array of structures
* where to store the list of suppoted
* resolutions to display to the user.
*
* hwnd - parent window handle
*
* pInstalData - pointer to the head of the list that
* contains the list of resolutions from
* the dsc file.
* fUseDefault - flag to indicate whether to use
* only the intersection of the dsc
* resolutions and the svgadata.pmi
* resolutons.
* pulCount - pointer to the number of supported
* resolutions to display
*
* Returns:
* apiRet - re-map all error codes to CANCEL_OPERATION
* ,forces the calling program to return to the main
* panel
* 0 - NO error
\****************************************************************/
APIRET GetResolutionsData(PRESOLUTIONS pResolutions,
PRESOLUTIONS pResolutionsToDisplay,
HWND hwnd,
PDSPINSTL_CHAIN pInstalChain,
BOOL fUseDefault,
PULONG pulCount,
PFN pfnGetNext,
BOOL *pulShowSelectionsToUser)
{
APIRET apiRet = 0;
HWND hwndMain;
ULONG ulCount,ulSize;
PVOID pVoid;
static bOnce = TRUE;
RESOLUTIONDATA resData;
do
{
/*
*make sure we run svga.exe at least once,or if the
*svgadata.pmi file does not exist
*/
if(OpenResolutionsFile(pResolutions,&ulCount) || bOnce)
{
/*
*get handle to our dll's resources
*/
if(apiRet = GetDllHandle(&hmodResource) )
{
SvgaReportError(MSG_GET_DLL_HANDLE,NULL,hwnd);
break;
}
/*
* If a resolution string was passed in then run
* unattended.
*/
if( pszResolutionString )
{
if (CreateSvgaTmpBat( NULL ))
{
SvgaReportError(MSG_UNABLE_TO_DETERMINE_HARD,
NULL,
hwnd);
apiRet = DID_ERROR;
}
apiRet = WinDlgBox((HWND)HWND_DESKTOP,
HWND_DESKTOP,
(PFNWP)WaitSvgaDlgProc,
hmodResource,
DLG_RUNSVGA,
NULL);
}
else
{
/*
* Prompt for svga utility, create svgatmp.bat
* If function fails don't run svgatmp.bat
*/
if(!(apiRet = WinDlgBox((HWND)HWND_DESKTOP,
HWND_DESKTOP,
(PFNWP)SelectSvgaUtilDlgProc,
hmodResource,
DLG_SELECTSVGAUTIL,
NULL)))
{
/*
*throw up a message box
*to indicate wait a moment
*while we run the svgatmp.bat
*/
apiRet = WinDlgBox((HWND)HWND_DESKTOP,
HWND_DESKTOP,
(PFNWP)WaitSvgaDlgProc,
hmodResource,
DLG_RUNSVGA,
NULL);
if( apiRet )
{
SvgaReportError(MSG_UNABLE_TO_DETERMINE_HARD,
NULL,
hwnd);
}
}
}
}
/*
*if we got no error while trying to run svga
*/
if(!apiRet)
{
bOnce = FALSE;
/*
*we should have a valid file
*by now
*/
if(apiRet = OpenResolutionsFile(pResolutions,&ulCount) )
{
/*
*report error if we still don't have something
*we can read
*/
SvgaReportError(MSG_BAD_RESOLUTIONS_FILE,NULL,hwnd);
break;
}
apiRet = ValidateResolutions(pResolutions,
pResolutionsToDisplay,
pInstalChain,
fUseDefault,
pulCount,
ulCount,
pfnGetNext);
/*
*error or no resolutions that
*match the dsc files
*/
if(apiRet || !(*pulCount) )
{
//D92820 apiRet = SvgaMessageBox(MSG_HARDWARE_CONFIG_ERROR,NULL,hwnd);
//D92820 if(apiRet == MBID_YES ) /* never hits this code */
//D92820 {
//D92820 *pulShowSelectionsToUser = FALSE;
//D92820 apiRet = 0;
//D92820 apiRet = CONTINUE_WITH_ERR;
//D92820 }
apiRet = CANCEL_OPERATION;
svgaLog("ERROR: High resolution mode not supported"); //NLS??
}
else if( pszResolutionString )
{
/*
* compare the valid resolutions with the one passed
* to the action routine dll.
*/
if(CompareResolutions( pszResolutionString,
pResolutionsToDisplay,
*pulCount ) == TRUE)
{
/*
* Select the resolution for the user bypassing the
* specify resolution dialog.
*/
if( SelectResolutionForUser(pInstalChain,
pResolutionsToDisplay,
pulCount ) == TRUE )
{
*pulShowSelectionsToUser = FALSE;
}
}
else
pszResolutionString = NULL;
}
}
}ONCE;
if(apiRet)
{
if (apiRet != CONTINUE_WITH_ERR)
apiRet = CANCEL_OPERATION;
}
return(apiRet);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:OpenResolutionsFile()
*
* Purpose: This routine will open the svgadata.pmi file and if
* successful will call readresolutions file.
*
* pResolutions - pointer to a array of resolutions structures that
* is expected to be large enough to hold all of the
* supported resoulutions.
* pulCount - the count of supported resolutions will be stored
* here.
* Returns:
* FALSE - No Error occurred.
* TRUE - Error occurred.
\****************************************************************/
BOOL OpenResolutionsFile(PRESOLUTIONS pResolutions,PULONG pulCount)
{
BOOL fError =FALSE;
HFILE hf;
ULONG ulAction,rc;
PSZ pszResolutionsFile = RESOLUTIONS_FILE;
ULONG ulBootDrive;
/*
*set the boot drive
*/
DosQuerySysInfo(QSV_BOOT_DRIVE,
QSV_BOOT_DRIVE,
&ulBootDrive,
sizeof(ulBootDrive));
*pszResolutionsFile = (CHAR)(ulBootDrive + 'A' - 1);
if(!(rc = DosOpen(pszResolutionsFile,
&hf,
&ulAction,
0,
FILE_ARCHIVED | FILE_READONLY | FILE_SYSTEM
| FILE_HIDDEN,
FILE_OPEN,
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
NULL)))
{
if(ReadResolutionsFile(pResolutions,hf,pulCount) )
{
fError = TRUE;
}
DosClose(hf);
}
else
{
fError =TRUE;
}
return(fError);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:ReadResolutionsFile()
*
* Purpose: This routine will read the parameter file, and parse
* the graphics information and save the supported resolutions
* mode into the pResolutions structure that was passed.
* It is assumed the pResolutions structure is large enough to
* hold all of the supported resolutions.
*
* pResolutions - pointer to the list of structures
* where the resolutions will be stored.
* hfile - handle to the file that should have
* already been opened.
* pulCount - where the number of supported resolutions
* that was placed in pResolutions will be
* stored.
* Returns:
* FALSE - No error occurred.
* TRUE - error occurred.
\****************************************************************/
BOOL ReadResolutionsFile(PRESOLUTIONS pResolutions,HFILE hf,PULONG pulCount)
{
BOOL fError = TRUE;
PVOID pvBuffer = NULL;
FILESTATUS fstsFile;
ULONG ulBytesRead,ulIndex;
PSZ pszNextResolution,pszNextMode;
do
{
*pulCount = 0;
DosQueryFileInfo(hf,
FIL_STANDARD,
&fstsFile,
sizeof(FILESTATUS)); /* get size of file */
if(fstsFile.cbFile < (ULONG)-1) /* file size < 64K ? */
{
pvBuffer = malloc(fstsFile.cbFile + 1);
if( pvBuffer)
{
DosRead(hf,pvBuffer,fstsFile.cbFile,&ulBytesRead);
pszNextResolution = pvBuffer;
while(pszNextResolution)
{
/*
*get to the next graphics mode string
*/
if(pszNextMode = strstr(pszNextResolution,GRAPHICS_MODE))
{
pszNextResolution = (strchr(pszNextMode,':') + 1);
pszNextResolution = strip_white(pszNextResolution);
ulIndex = strcspn(pszNextResolution,".");
strncpy(pResolutions->achResolutionString,
pszNextResolution,ulIndex);
pResolutions++;
(*pulCount)++;
}
else
{
pszNextResolution = NULL;
}
}
fError = FALSE;
}
}
fError = FALSE;
}ONCE;
if(pvBuffer)
{
free(pvBuffer);
}
return(fError);
}
/*************************************************************
*
*
* Name: CreateSvgaTmpBat()
*
* Purpose: This function will make sure svga.exe exist, if
* so, it will create the svgatmp.bat file used by
* RunSvga()
*
* Returns: apiRet.
*
**************************************************************/
APIRET CreateSvgaTmpBat( CHAR *pszBuffer )
{
APIRET apiRet = 0;
HFILE hFile;
ULONG ulAction, ulTemp, ulBootDrive;
PSZ pszSvgaTmpBatFile = SVGATMP_BAT;
CHAR szSvgaFullProg[CCHMAXPATH];
PSZ pszArg1 = " ON";
PSZ pszArg2 = " INIT";
memset( szSvgaFullProg,0, sizeof( szSvgaFullProg ) );
/*
** get full program path for svga.exe
*/
if(!(apiRet = DosSearchPath(SEARCH_ENVIRONMENT,
"PATH",
SVGA_PROGRAM,
szSvgaFullProg,
CCHMAXPATH)) )
{
/* get boot drive */
DosQuerySysInfo(QSV_BOOT_DRIVE,
QSV_BOOT_DRIVE,
&ulBootDrive,
sizeof(ulBootDrive));
*pszSvgaTmpBatFile = (CHAR)(ulBootDrive + 'A' - 1);
if(!(apiRet = DosOpen(pszSvgaTmpBatFile,
&hFile,
&ulAction,
0,
FILE_NORMAL,
FILE_TRUNCATE | FILE_CREATE,
OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE,
NULL)))
{
strcat( szSvgaFullProg, pszArg1 );
if( fSvgaUtilPresent ){
strcat( pszBuffer, "\r\n" );
DosWrite(hFile, pszBuffer, strlen(pszBuffer),
&ulTemp);
DosWrite(hFile, szSvgaFullProg, strlen(szSvgaFullProg),
&ulTemp);
}
else{
strcat( szSvgaFullProg, pszArg2 );
DosWrite(hFile, szSvgaFullProg, strlen(szSvgaFullProg),
&ulTemp);
}
DosClose(hFile);
}
}
return( apiRet );
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:RunSvga
*
* Purpose:This routine will run the dos batch file svgatmp.bat.
* If user has a Svga Utility, svga.exe will be passed
* the argument "ON", else svga.exe will be passed the
* arguement "ON DEFAULT". If the svga.exe is successfully
* started up in another session then, a separate thread will
* be started up,which will monitor the process id that is
* passed to it.
*
* Returns:
* Non - zero - The system error number that occurred.
* 0 - No Error occurred
\****************************************************************/
VOID RunSvga(PVOID pvMessageData)
{
APIRET apiRet = 0;
ULONG rc,ulSession,ulProcessId, ulBootDrive;
CHAR szArgs[CCHMAXPATH];
CHAR szFullProg[CCHMAXPATH];
PSZ pszSvgaTmpBatFile = SVGATMP_BAT;
PSZ pszCommandCom = "C:\\OS2\\MDOS\\COMMAND.COM";
static PSZ pszConfigSys = szConfigSys;
static PSZ pszAutoExecName = szAutoExecName;
static PSZ pszConfigDsp = szConfigDsp;
static PSZ pszAutoExecDsp = szAutoExecDsp;
STARTDATA StartData;
FILESTATUS fsts;
static PSVGAWAITDATA pWaitData;
HQUEUE hqueue;
REQUESTDATA requestData;
ULONG ulData;
PSESSIONRESULT psesres;
BYTE bElemPrty;
CHAR szError[CCHMAXPATH];
pWaitData = (PSVGAWAITDATA)pvMessageData;
memset(szArgs,0,sizeof(szArgs) );
memset(szFullProg,0,sizeof(szFullProg) );
memset(&StartData,0,sizeof(StartData) );
/*
*make sure the program can be found, first search the
*os2\mdos directory, if not found, search the path.
*/
DosQuerySysInfo(QSV_BOOT_DRIVE,
QSV_BOOT_DRIVE,
&ulBootDrive,
sizeof(ulBootDrive));
*pszCommandCom = (CHAR)(ulBootDrive + 'A' - 1);
if( apiRet = DosQueryPathInfo( pszCommandCom,
1,
&fsts, sizeof(fsts)))
{
apiRet = DosSearchPath(SEARCH_ENVIRONMENT,
"PATH",
COMMAND_COM,
szFullProg,
CCHMAXPATH);
}
else
strcpy( szFullProg, pszCommandCom );
if(!apiRet)
{
*pszSvgaTmpBatFile = (CHAR)(ulBootDrive + 'A' - 1);
if( fSvgaUtilPresent ) {
/* Before executing command.com, if svga utility present then
copy save config.sys and autoexec.bat to *.dsp ) */
*pszConfigSys = (CHAR)(ulBootDrive + 'A' - 1);
*pszAutoExecName = (CHAR)(ulBootDrive + 'A' - 1);
*pszAutoExecDsp = (CHAR)(ulBootDrive + 'A' - 1);
*pszConfigDsp = (CHAR)(ulBootDrive + 'A' - 1);
DosCopy( pszConfigSys, pszConfigDsp, DCPY_EXISTING );
DosCopy( pszAutoExecName, pszAutoExecDsp, DCPY_EXISTING );
}
strcpy( szArgs, "/C ");
strcat( szArgs, pszSvgaTmpBatFile );
StartData.Length = sizeof(StartData);
StartData.Related = SSF_RELATED_CHILD;
StartData.FgBg = SSF_FGBG_FORE;
StartData.TraceOpt = SSF_TRACEOPT_NONE;
StartData.PgmTitle = COMMAND_COM;
StartData.PgmName = szFullProg;
StartData.PgmInputs = szArgs;
StartData.TermQ = "\\queues\\svgainst.que";
StartData.Environment = NULL;
StartData.InheritOpt = 0;
StartData.SessionType = SSF_TYPE_VDM;
StartData.PgmHandle = 0;
if(!(apiRet = DosCreateQueue(&hqueue,
QUE_FIFO,
"\\queues\\svgainst.que")))
{
apiRet = DosStartSession(&StartData,
(PULONG)&pWaitData->ulSession,
(PPID)&pWaitData->ulProcessid);
if( apiRet == 0 || apiRet == ERROR_SMG_START_IN_BACKGROUND)
{
/* initialize data */
apiRet = 0;
requestData.ulData = -1;
requestData.pid = pWaitData->ulSession;
while(!DosReadQueue( hqueue,
&requestData,
&ulData,
(PPVOID)&psesres,
0,
DCWW_WAIT,
&bElemPrty,
NULL) &&
requestData.ulData);
if(psesres->usResultCode)
{
apiRet = psesres->usResultCode;
sprintf(szError, "SVGA.EXE error:rc=%ld", apiRet);
svgaLog(szError);
}
}
else
{
sprintf(szError, "DosStartSession error:rc=%ld",apiRet);
svgaLog(szError);
}
DosCloseQueue(hqueue);
}
}
if( fSvgaUtilPresent )
{
DosCopy( pszConfigDsp, pszConfigSys, DCPY_EXISTING );
DosCopy( pszAutoExecDsp, pszAutoExecName, DCPY_EXISTING);
DosDelete( pszAutoExecDsp );
DosDelete( pszConfigDsp );
}
(apiRet ? WinPostMsg(pWaitData->hwnd, AM_QUIT,(MPARAM)TRUE, 0)
: WinPostMsg(pWaitData->hwnd, AM_QUIT,(MPARAM)FALSE, 0));
DosExit(EXIT_THREAD,0);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:strip_white
*
* Purpose:strip leading blank character from a string.
*
* Returns:
* Pointer to the first non-blank character in the string
* that is passed.
\****************************************************************/
PSZ strip_white(PSZ pszString)
{
while(*pszString == ' ')
{
pszString++;
}
return(pszString);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:ValidateResolutions
*
* Purpose:If we are not using the default supported resolutions
* or if we are using only the supported resolutions and
* they are correctly validated,the resolutions that are
* contained in the pDspChain will be saved in the
* pResolutionToDisplay Stucture. It is expected that the
* pResolutions stucture is large enough to hold all of the
* supported resolutions.
*
*
* pResolutions - pointer to the list of supported resolutions
* pResolutionsToDisplay - pointer to the resolutions data structure
* where the resolutions from the dsc file
* are saved to.
* pInstalData - pointer to the linked list of resolutions
* that was passed to us by the
* display install utility.
* fUseDefault - flag to indicate whether to use the only
* default resolutions or not.
* pulCount - The number of resolutions that were
* stored in the pResolutionsToDisplay
* structure.
* ulCount - The number of supported resolutios
* in the pResolutions structure.
* Returns:
* FALSE - Currently always returns FALSE.
* TRUE - if error
\****************************************************************/
BOOL ValidateResolutions(PRESOLUTIONS pResolutions,
PRESOLUTIONS pResolutionsToDisplay,
PDSPINSTL_CHAIN pInstalData,
BOOL fUseDefault,
PULONG pulCount,
ULONG ulCount,
PFN pfnGetNext)
{
PDSPINSTL_CHAIN pDspChain;
/* Amol; Defect #58319; 12/09/92 */
f1024K /* Check if SVGA card has more than */
= CheckSVGAMem /* 512K memory */
(pResolutions, ulCount);
*pulCount = 0;
for(pDspChain = pInstalData;pDspChain;
pDspChain = pDspChain->pNextDspInstl)
{
/*
*if we've got a resolution
*/
if(pDspChain->pszResolution)
{
/*
*if we are not using the default include
*it ||
*if we are using the default compare it
*against the resolutions the adapter card
*supports for this machine
*/
if(!fUseDefault || CompareResolutions(pDspChain->pszResolution,
pResolutions,ulCount) )
{
/*
*save off the resolutions that are supported
*/
strcpy(pResolutionsToDisplay->achResolutionString,
pDspChain->pszResolution);
(*pulCount)++;
pResolutionsToDisplay++;
}
}
}
return(FALSE);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:SelectResolutionForUser
*
* Purpose:To select the chain element that matches the resolution
* passed on the command using the /RES: parameter from
* DSPINSTL
*
* Returns:
* TRUE - Selected Supported Resolution
* FALSE - Not a supported Resolution
\****************************************************************/
BOOL SelectResolutionForUser( PDSPINSTL_CHAIN pInstalData,
PRESOLUTIONS pResolutionsToDisplay,
PULONG pulCount )
{
PDSPINSTL_CHAIN pDspChain;
RESOLUTIONDATA resolutionParm;
RESOLUTIONDATA resolutionChain;
BOOL fSupported = FALSE;
/*
* Convert the resolution parameter passed
*/
StringToResolution(pszResolutionString, &resolutionParm);
for(pDspChain = pInstalData;pDspChain;
pDspChain = pDspChain->pNextDspInstl)
{
/*
*if we've got a resolution
*/
if(pDspChain->pszResolution)
{
/*
* Convert the resolution string from the DSC file
*/
StringToResolution(pDspChain->pszResolution, &resolutionChain);
/*
* Compare the DSC resolution to the resolution
* parameter passed on the command line
*/
if((resolutionParm.Horiz == resolutionChain.Horiz) &&
(resolutionParm.Vert == resolutionChain.Vert) &&
(resolutionParm.Colors == resolutionChain.Colors))
{
strcpy( pResolutionsToDisplay->achResolutionString,
pDspChain->pszResolution );
pResolutionsToDisplay->ulSelected = TRUE;
*pulCount = 1;
fSupported = TRUE;
break;
}
}
}
return( fSupported );
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:CompareResolutions
*
* Purpose:To determine if the string pszResolution is contained in
* the list of supported resolutions (pSupportedResolutions).
* This routine will parse through ulResolutionCount number of
* items in the pSupportedResolutions strucuture that is passed.
* Returns:
* TRUE - Supported Resolution
* FALSE - Not supported Resolution
\****************************************************************/
BOOL CompareResolutions(PSZ pszResolution,PRESOLUTIONS pSupportedResolutions,
ULONG ulResolutionCount)
{
BOOL fSupported = FALSE;
PRESOLUTIONS pTemp;
ULONG ulCounter = 0;
RESOLUTIONDATA DscResolution,SupportedResolution;
memset(&DscResolution,0,sizeof(RESOLUTIONDATA) );
StringToResolution(pszResolution,&DscResolution);
for(pTemp = pSupportedResolutions;ulCounter < ulResolutionCount;
ulCounter++,
pTemp++)
{
/*
*convert each one to resolution format
*/
memset(&SupportedResolution,0,sizeof(SupportedResolution) );
StringToResolution(pTemp->achResolutionString,&SupportedResolution);
/*
*does the string match any of
*our resoutions
*/
/* Amol; Defect #58319; 12/09/1992 */
/*
*if the video board has less than one meg of vram
*then filter out any drivers that need one meg
*/
if (!f1024K &&
IsResolutionOver1Mg (pszResolution, &DscResolution))
break;
if(DscResolution.Horiz == SupportedResolution.Horiz)
{
if(DscResolution.Vert == SupportedResolution.Vert)
{
if(DscResolution.Colors == SupportedResolution.Colors)
{
fSupported = TRUE;
break;
}
}
}
}
return(fSupported);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:StringToResolution
*
* Purpose: Convert a resolution in string format to
* it's corresponding parts and put them into
* the resolution data structure.
* Returns:
*
* VOID - there is no error return.
\****************************************************************/
VOID StringToResolution(PSZ pszString,PRESOLUTIONDATA pResolutionData)
{
PSZ pszTokens = "0123456789",pszNextToken;
SHORT sPass;
for(sPass = 0,pszNextToken = pszString; sPass < RESOLUTION_NUM; sPass++)
{
pszNextToken = strpbrk(pszNextToken,pszTokens);
if(pszNextToken)
{
switch(sPass)
{
case 0:
pResolutionData->Horiz = atoi(pszNextToken);
break;
case 1:
pResolutionData->Vert = atoi(pszNextToken);
break;
case 2:
pResolutionData->Colors = atoi(pszNextToken);
break;
}
pszNextToken = (pszNextToken + strspn(pszNextToken,pszTokens) );
}
}
return;
}
//////////////////////////////////////////////////////////////////
//
// Name: SvgaReportError
//
// Purpose: Display error message.
//
// Usage: Called when a fatal error occurrs while installing a
// device driver.
//
// Method: - Display message box with error message.
// - Log error to logfile.
//
// Returns:
//
//////////////////////////////////////////////////////////////////
VOID SvgaReportError(ULONG rc,PSZ pszMsg,HWND hwndOwner)
{
//@TM PSZ pszErrorTitle = "Svga Installation Error";
HAB hab;
CHAR szMsg[CCHMAXPATH];
CHAR szErrorTitle[CCHMAXPATH];
WinAlarm(HWND_DESKTOP, WA_ERROR);
hab = WinInitialize(0);
//@TM if (!pszMsg)
//@TM {
//@TM pszMsg = szErrorMsg[rc];
//@TM }
WinLoadString(hab, hmodResource, rc, CCHMAXPATH,
szMsg);
WinLoadString(hab, hmodResource, MSG_SVGA_ERROR_TITLE, CCHMAXPATH,
szErrorTitle);
WinMessageBox(HWND_DESKTOP,
hwndOwner,
szMsg,
szErrorTitle,
MBX_INSTERROR,
MB_OK | MB_ERROR | MB_MOVEABLE | MB_SYSTEMMODAL);
/*
*log the error
*/
svgaLog(szMsg);
WinTerminate( hab );
} /* SvgaReportError() */
//////////////////////////////////////////////////////////////////
//
// Name: CenterDialog
//
// Purpose: Center a dialog box on the main window.
//
// Usage: Called during the WM_INITDLG of all dialog window
// procedures.
//
// Method:
//
// Returns:
// VOID
//////////////////////////////////////////////////////////////////
VOID CenterDialog(HWND hwnd)
{
SWP swpDlgPos; /* structure for position of dialog */
SWP swpFramePos; /* structure for position of frame */
POINTL ptlDesktop; /* height and width of desktop */
/* get gesktop size */
ptlDesktop.x = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
ptlDesktop.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
/* get dialog position */
WinQueryWindowPos(hwnd, &swpDlgPos);
if (WinIsWindowVisible(hwnd) && /* center everything but logo and */
(hwnd != hwnd)) /* and main frame on hwndMain */
{
/* get frame position */
WinQueryWindowPos(hwnd, &swpFramePos);
/* center the dialog vertically on frame */
swpDlgPos.y = (SHORT)((swpFramePos.cy / 2) - (swpDlgPos.cy / 2) + swpFramePos.y);
/* center the dialog horizontally on frame */
swpDlgPos.x = (SHORT)((swpFramePos.cx /2) - (swpDlgPos.cx /2) + swpFramePos.x);
}
else
{
/* center the dialog vertically on the desktop */
swpDlgPos.y = (SHORT)((ptlDesktop.y / 2) - (LONG)(swpDlgPos.cy / 2));
/* center the dialog horizontally on the desktop */
swpDlgPos.x = (SHORT)((ptlDesktop.x /2) - (LONG)(swpDlgPos.cx /2));
}
/* be sure the dialog didn't go off the left edge of the screen */
if (swpDlgPos.x < 0)
swpDlgPos.x = 0;
/* be sure the dialog didn't go off the bottom edge of the screen */
if (swpDlgPos.y < 0)
swpDlgPos.y = 0;
/* be sure the dialog didn't go off the right edge of the screen */
if (((LONG)swpDlgPos.x + (LONG)swpDlgPos.cx) > ptlDesktop.x)
swpDlgPos.x = (SHORT)(ptlDesktop.x - (LONG)swpDlgPos.cx);
/* be sure the dialog didn't go off the top edge of the screen */
if (((LONG)swpDlgPos.y + (LONG)swpDlgPos.cy) > ptlDesktop.y)
swpDlgPos.y = (SHORT)(ptlDesktop.y - (LONG)swpDlgPos.cy);
/* reposition the dialog and make it visible. */
WinSetWindowPos(hwnd,
HWND_TOP,
swpDlgPos.x,
swpDlgPos.y,
0, 0,
SWP_ACTIVATE | SWP_MOVE | SWP_ZORDER | SWP_SHOW);
} /* CenterDialog() */
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:GetDllHandle
*
* Purpose: Get a module resource handle to the svga.dll.
*
*
*
* Usage:Pass a pointer to a resource handle to the routine. If
* error,the system error number is returned,else 0 is
* returned.
* Returns:
* apiRet - System Error number
* 0 - if no error
\****************************************************************/
APIRET APIENTRY GetDllHandle( PHMODULE phmodResource)
{
APIRET apiRet;
CHAR szFailName[CCHMAXPATH];
PSZ pszModuleName = SVGA_MODULE;
PSZ pszModuleTemp = SVGA_MODULE;
ULONG ulDrive;
CHAR szPath[CCHMAXPATH];
PSZ pchCur,pszTemp;
ULONG ulSize;
DosError(HARDERROR_DISABLE);
memset(szFailName,0,sizeof(szFailName) );
/*
*try to load in from the dpath
*/
if( pszTemp = strchr(pszModuleTemp,'.') )
{
*pszTemp = 0;
}
if(apiRet = DosLoadModule(szFailName, 0,pszModuleTemp, phmodResource) )
{
/*
*if not go out to the drives
*/
for(ulDrive= 1; ulDrive <= MAXDRIVES;ulDrive++ )
{
/*
*build the paths for each drive,
*where oh,where might you be tonight
*/
memset(szPath,0,sizeof(szPath) );
ulSize = sizeof(szPath) - 3;
DosQueryCurrentDir(ulDrive,&szPath[3],&ulSize);
szPath[0] = 'A' + ulDrive - 1;
szPath[1] = ':';
szPath[2] = '\\';
if( (szPath[strlen(szPath)-1]) != '\\')
{
strcat(szPath,"\\");
}
strcat(szPath,pszModuleName);
/*
*try to load off this drive
*/
apiRet = DosLoadModule(szFailName, sizeof(szFailName),
szPath, phmodResource);
if(!apiRet)
{
/*
*we loaded,time to boogey out
*/
break;
}
}
}
DosError(HARDERROR_ENABLE);
return(apiRet);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name: svgaLog
*
* Purpose: Generic logging routine for svga installation
* error. Note: this should be changed so that the
* display install utility can pass through a funciton
* pointer to it's own logging function.NOTE>>>>>>
*
*
*
* Usage:
*
* Method:
* -
*
* -
* -
*
* -
* -
*
* Returns:
*
* VOID
\****************************************************************/
VOID svgaLog(PSZ pszMsg)
{
CHAR szDateTime [SIZ_DATE_TIME];
CHAR *pszNull;
memset(szDateTime,' ',sizeof(szDateTime) );
_strdate(szDateTime);
/*
*get rid of the null and keep the date,time
*on the same line in the log file
*/
if( (pszNull = strchr(szDateTime,'\0') ) )
{
*pszNull = ' ';
}
_strtime( &szDateTime[SIZ_DATE_TIME /2]);
if(pfnLogFunction)
{
(*pfnLogFunction)(szDateTime);
(*pfnLogFunction)(pszMsg);
}
}
//////////////////////////////////////////////////////////////////
//
// Name: SvgaReportError
//
// Purpose: Display error message.
//
// Usage: Called when a fatal error occurrs while installing a
// device driver.
//
// Method: - Display message box with error message.
// - Log error to logfile.
//
// Returns:
//
//////////////////////////////////////////////////////////////////
USHORT SvgaMessageBox(ULONG rc,PSZ pszMsg,HWND hwndOwner)
{
//@TM PSZ pszErrorTitle = "Svga Installation Message";
HAB hab;
USHORT usRc;
CHAR szMsg[CCHMAXPATH];
CHAR szErrorTitle[CCHMAXPATH];
WinAlarm(HWND_DESKTOP, WA_ERROR);
hab = WinInitialize(0);
//@TM if (!pszMsg)
//@TM {
//@TM pszMsg = szErrorMsg[rc];
//@TM }
WinLoadString(hab, hmodResource, MSG_SVGA_INSTALL, CCHMAXPATH,
szErrorTitle);
WinLoadString(hab, hmodResource, rc, CCHMAXPATH,
szMsg);
usRc = WinMessageBox(HWND_DESKTOP,
hwndOwner,
szMsg,
szErrorTitle,
MBX_INSTERROR,
MB_YESNO | MB_ERROR | MB_MOVEABLE |
MB_DEFBUTTON2 | MB_SYSTEMMODAL);
WinTerminate( hab );
return(usRc);
}
/****************************************************************\
*
*--------------------------------------------------------------
*
* Name:GetSelectedResolution
*
* Purpose: This routine will loop through the list of pSelectedResolutions
* for up to ulCount number of elements looking for the ulSelected
* flag to be set to TRUE. A pointer to the first ulSelected
* element will be returned or NULL if no selection was made.
* Returns:
* pszResolutions = a pointer to the selected resolutions string
* or NULL if none was selected.
\****************************************************************/
PSZ GetDesignatedResolution(PDSPINSTL_CHAIN pChain,
ULONG ulCount,
LONG lOffSetToGet)
{
ULONG ulCounter;
PSZ pszResolutions = NULL;
PDSPINSTL_CHAIN pTemp;
for(ulCounter =0,pTemp = pChain; pTemp;
pTemp = pTemp->pNextDspInstl,ulCounter++)
{
if(pTemp->pszResolution)
{
pszResolutions= pTemp->pszResolution;
break;
}
}
return(pszResolutions);
}
/***************************************************************************/
/* Amol; D58319; 12/09/92 */
BOOL CheckSVGAMem (PRESOLUTIONS pResolutions, ULONG ulResolutionCount)
/*-------------------------------------------------------------------------*\
*
* This is a routine to check if 1024x768 resolution has been specified for
* this SVGA card. If it has been, then the routine returns TRUE else returns
* FALSE. If the 1024x768 resolution is indeed supported, then it means that
* the card has at least 1 MB memory on it.
*
\*-------------------------------------------------------------------------*/
{
ULONG ulCounter = 0;
RESOLUTIONDATA resData;
for (; ulCounter < ulResolutionCount; ulCounter++)
{
StringToResolution /* Convert string to resolution */
((pResolutions + ulCounter)->achResolutionString, &resData);
if ((resData.Horiz >= 1024) && /* Does this support 1024x768x256 ? */
(resData.Vert >= 768) &&
(resData.Colors >= 256))
/* Yes, it does support the above ! */
return TRUE; /* Done - return TRUE status */
}
return FALSE; /* Done - return FALSE status */
} /* CheckSVGAMem */
/***************************************************************************/
/* Amol; D58319; 12/11/92 */
BOOL IsResolutionOver1Mg (PSZ pszResolution,PRESOLUTIONDATA pResolutions)
/*-------------------------------------------------------------------------*\
*
* This is a routine to check if pszResolution specifies a driver requiring
* 1 MB or more.
*
* The routine returns TRUE if the driver requires 1 MB or more else returns
* FALSE.
*
\*-------------------------------------------------------------------------*/
{
PSZ pszResCopy = strdup (pszResolution);
strupr (pszResCopy);
if ((pResolutions->Horiz >= 1024) && /* Check for 1024x768x256 mode */
(pResolutions->Vert >= 768) &&
(pResolutions->Colors >= 256))
/* This means more than 1 MB VRAM */
return TRUE; /* Done - return TRUE status */
if (strstr (pszResCopy, "1.0") && /* Check if 1.0 MB was specified */
(strstr (pszResCopy, "MG") ||
strstr (pszResCopy, "MB")))
/* 1.0 MB was NOT specified */
return TRUE; /* Done - return TRUE status */
return FALSE; /* Done - return FALSE status */
} /* IsResolutionOver1Mg */
//////////////////////////////////////////////////////////////////
//
// Name: InitHelp
//
// Purpose: Initializes the IPF help facility.
//
// Usage: Called once during initialization of the program.
//
// Method: Initializes the HELPINIT structure and creates the
// help instance.
//
// Returns:
//
//////////////////////////////////////////////////////////////////
VOID InitHelp(HWND *phwndHelpInstance)
{
HELPINIT hmInitStruct;
CHAR szMsg[CCHMAXPATH];
CHAR szErrorTitle[CCHMAXPATH];
CHAR szMainTitle[CCHMAXPATH];
PSZ pszHelpFile = "C:\\OS2\\HELP\\DSPINSTL.HLP";
static HAB hab;
ULONG ulBootDrive;
#ifndef RESPONSE_FILE
hab = WinInitialize( 0 );
WinLoadString(hab, hmodResource, MSG_MAINHELPTITLE, CCHMAXPATH,
szMainTitle);
DosQuerySysInfo(QSV_BOOT_DRIVE,
QSV_BOOT_DRIVE,
&ulBootDrive,
sizeof(ulBootDrive));
*pszHelpFile = (CHAR)(ulBootDrive + 'A' - 1);
/* inititalize help init structure */
hmInitStruct.cb = sizeof(HELPINIT);
hmInitStruct.ulReturnCode = 0;
hmInitStruct.pszTutorialName = (PSZ)NULL;
hmInitStruct.phtHelpTable = (PHELPTABLE)(0xffff0000 | MAIN_HELP_TABLE);
hmInitStruct.hmodHelpTableModule = 0;
hmInitStruct.hmodAccelActionBarModule = 0;
hmInitStruct.idAccelTable = 0;
hmInitStruct.idActionBar = 0;
hmInitStruct.pszHelpWindowTitle = szMainTitle;
hmInitStruct.fShowPanelId = (ULONG)CMIC_HIDE_PANEL_ID;
hmInitStruct.pszHelpLibraryName = pszHelpFile;
/* creating help instance */
*phwndHelpInstance = WinCreateHelpInstance(hab, &hmInitStruct);
if (!*phwndHelpInstance || hmInitStruct.ulReturnCode)
{
WinLoadString(hab, hmodResource, MSG_APPTITLE, CCHMAXPATH,
szErrorTitle);
WinLoadString(hab, hmodResource, MSG_HELPNOTAVAIL, CCHMAXPATH,
szMsg);
WinMessageBox(HWND_DESKTOP,
HWND_DESKTOP,
szMsg,
szErrorTitle,
0,
MB_OK | MB_INFORMATION | MB_MOVEABLE);
if (*phwndHelpInstance)
{
WinDestroyHelpInstance(hwndHelpInstance);
}
}
#endif
} /* InitHelp() */
/**************************************************************************/