windows-nt/Source/XPSP1/NT/shell/osshell/control/drivers/drivers.c
2020-09-26 16:20:57 +08:00

1404 lines
42 KiB
C

/* DRIVERS.C
**
** Copyright (C) Microsoft, 1990, All Rights Reserved.
**
** Multimedia Control Panel Applet for installing/configuring installable
** device drivers. See the ispec doc DRIVERS.DOC for more information.
**
** History:
**
** Tue Jul 31 1990 -by- MichaelE
** Created.
**
** Thu Oct 25 1990 -by- MichaelE
** Added restart, horz. scroll, added SKIPDESC reading desc. strings.
**
** Sat Oct 27 1990 -by- MichaelE
** Added FileCopy. Uses SULIB.LIB and LZCOPY.LIB. Finished stuff
** for case of installing a driver with more than one type.
**
** May 1991 -by- JohnYG
** Added and replaced too many things to list. Better management
** of removed drivers, correct usage of DRV_INSTALL/DRV_REMOVE,
** installing VxD's, replaced "Unknown" dialog with an OEMSETUP.INF
** method, proper "Cancel" method, fixed many potential UAE's.
*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntseapi.h>
#include <windows.h>
#include <mmsystem.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <cpl.h>
#include <cphelp.h>
#include "drivers.h"
#include "sulib.h"
typedef struct
{
int idIcon;
int idName;
int idInfo;
BOOL bEnabled;
DWORD dwContext;
PSTR pszHelp;
} APPLET_INFO;
#define NUM_APPLETS 1
#define OBJECT_SIZE 1024
APPLET_INFO near applets[NUM_APPLETS];
BOOL bBadOemSetup;
BOOL bRestart = FALSE;
int iRestartMessage = 0;
BOOL bInstallBootLine = FALSE;
BOOL bCopyVxD;
BOOL bFindOEM = FALSE;
BOOL bRelated = FALSE;
BOOL bDriversAppInUse;
BOOL bCopyingRelated;
BOOL bDescFileValid;
HANDLE myInstance;
HWND hlistbox;
UINT wHelpMessage;
DWORD dwContext;
PINF pinfOldDefault;
char szDriversHlp[24];
char szLastQuery[20];
char szSetupInf[18];
char szKnown[250];
char szRestartDrv[80];
char szUnlisted[150];
char szRelatedDesc[30];
char szAppName[26];
char szDrivers[12];
char szRemove[12];
char szControlIni[20];
char szSysIni[20];
char szMCI[6];
char szOutOfRemoveSpace[54];
char szDriversDesc[38];
char szUserDrivers[38];
// Where the source of files to copy is - user updates
char szDirOfSrc[MAX_PATH];
char szAddDriver[36];
char szNoDesc[36];
char szError[20];
char szRemoveOrNot[250];
char szRemoveOrNotStrict[250];
char szStringBuf[128];
char szMDrivers[38];
char szMDrivers32[38];
char szFullPath[MAXFILESPECLEN];
char szSystem[MAX_PATH];
char szOemInf[MAX_PATH];
char aszClose[16];
char szFileError[50];
static HANDLE hIList;
static HANDLE hWndMain;
/*
* Global flag telling us if we're allowed to write to ini files
*/
BOOL IniFileWriteAllowed;
DWORD GetFileDateTime (LPSTR);
PSTR GetProfile (PSTR,PSTR, PSTR, PSTR, int);
int AddIDriver (HWND, PIDRIVER);
void AddIDrivers (HWND, PSTR, PSTR);
BOOL InitInstalled (HWND, PSTR);
BOOL InitAvailable (HWND, int);
void CloseDrivers (HWND);
void RemoveAvailable (HWND);
BOOL UserInstalled (PSTR);
BOOL RestartDlg (HWND, unsigned, UINT, LONG);
BOOL AddUnlistedDlg (HWND, unsigned, UINT, LONG);
int AvailableDriversDlg (HWND, unsigned, UINT, LONG);
BOOL ListInstalledDlg (HWND, unsigned, UINT, LONG);
LONG CPlApplet (HWND, unsigned, UINT, LONG);
void ReBoot (HWND);
/*
* CheckSectionAccess()
*
* See if we can read/write to a given section
*/
BOOL CheckSectionAccess(char *szIniFile, char *SectionName)
{
static char TestKey[] = "TestKey!!!";
static char TestData[] = "TestData";
static char ReturnData[50];
/*
* Check we can write, read back and delete our key
*/
return WritePrivateProfileString(SectionName,
TestKey,
TestData,
szIniFile) &&
GetPrivateProfileString(SectionName,
TestKey,
"",
ReturnData,
sizeof(ReturnData),
szIniFile) == (DWORD)strlen(TestData) &&
WritePrivateProfileString(SectionName,
TestKey,
NULL,
szIniFile);
}
/*
* CheckIniAccess()
*
* Checks access to our 2 .ini file sections - DRIVERS_SECTION and
* MCI_SECTION by just writing and reading some junk
*
* Basically if we don't have access to these sections we're not
* going to allow Add and Remove. The individual MCI drivers must
* take care not to put their data into non-writeable storage although
* this completely messes up the default parameters thing so we're going
* to put these into a well-known key in the win.ini file (ie per user).
*
*/
BOOL CheckIniAccess(void)
{
return CheckSectionAccess(szSysIni, szDrivers) &&
CheckSectionAccess(szSysIni, szMCI) &&
CheckSectionAccess(szControlIni, szUserDrivers) &&
CheckSectionAccess(szControlIni, szDriversDesc) &&
CheckSectionAccess(szControlIni, szRelatedDesc);
}
/*
* QueryRemoveDrivers()
*
* Ask the user if they're sure. If the Driver is one required by the
* system (ie not listed in [Userinstallable.drivers] in control.ini)
* warn the user of that too.
*/
BOOL NEAR PASCAL QueryRemoveDrivers(HWND hDlg, PSTR szKey, PSTR szDesc)
{
char bufout[MAXSTR];
if (UserInstalled(szKey))
wsprintf(bufout, szRemoveOrNot, (LPSTR)szDesc);
else
wsprintf(bufout, szRemoveOrNotStrict, (LPSTR)szDesc);
return (MessageBox(hDlg, bufout, szRemove,
MB_ICONEXCLAMATION | MB_TASKMODAL | MB_YESNO) == IDYES );
}
/*
* GetProfile()
*
* Get private profile strings.
*/
PSTR GetProfile(PSTR pstrAppName, PSTR pstrKeyName, PSTR pstrIniFile,
PSTR pstrRet, int iSize)
{
char szNULL[2];
szNULL[0] = '\0';
GetPrivateProfileString(pstrAppName, (pstrKeyName==NULL) ? NULL :
(LPSTR)pstrKeyName, szNULL, pstrRet, iSize, pstrIniFile);
return(pstrRet);
}
/*********************************************************************
*
* AddIDriver()
*
* Add the passed driver to the Installed drivers list box, return
* the list box index.
*
*********************************************************************/
int AddIDriver(HWND hWnd, PIDRIVER pIDriver)
{
int iIndex;
PIDRIVER pIDriverlocal;
iIndex = (int)SendMessage(hWnd, LB_GETCOUNT, 0, 0L);
while ( iIndex-- > 0)
if ( (int)(pIDriverlocal = (PIDRIVER)SendMessage(hWnd, LB_GETITEMDATA, iIndex, 0L)) != LB_ERR)
if (!FileNameCmp(pIDriverlocal->szFile, pIDriver->szFile))
return(0);
//
// create the list box item
//
if ((iIndex = (int)SendMessage(hWnd, LB_ADDSTRING, 0,
(LONG)(LPSTR)pIDriver->szDesc)) != LB_ERR)
SendMessage(hWnd, LB_SETITEMDATA, iIndex, (LONG)pIDriver);
return(iIndex);
}
/*********************************************************************
*
* AddIDrivers()
*
* Add drivers in the passed key strings list to the Installed Drivers box.
*
*********************************************************************/
void AddIDrivers(HWND hWnd, PSTR pstrKeys, PSTR pstrSection)
{
PIDRIVER pIDriver;
HWND hWndInstalled;
PSTR pstrKey;
PSTR pstrDesc;
hWndInstalled = GetDlgItem(hWnd, LB_INSTALLED);
pstrKey = pstrKeys;
pstrDesc = (PSTR)LocalAlloc(LPTR, MAXSTR);
/*
* parse key strings for profile, and make IDRIVER structs
*/
while ( *pstrKey )
{
pIDriver = (PIDRIVER)LocalAlloc(LPTR, sizeof(IDRIVER));
if ( pIDriver )
{
PSTR pstr;
if (*GetProfile(pstrSection, pstrKey, szSysIni, pIDriver->szFile,
sizeof(pIDriver->szFile)) == '\0')
{
LocalFree((HANDLE)pIDriver);
goto nextkey;
}
for ( pstr=pIDriver->szFile; *pstr && (*pstr!=COMMA) &&
(*pstr!=SPACE); pstr++ )
;
*pstr = '\0';
#ifdef TRASHDRIVERDESC
if (bDescFileValid)
#endif
/*
* try to load the cached description
*/
GetProfile(szDriversDesc,
pIDriver->szFile,
szControlIni,
pIDriver->szDesc,
sizeof(pIDriver->szDesc));
/*
* if we failed, then try to get the information from
* mmdriver.inf or the exehdr
*/
if (pIDriver->szDesc[0] == '\0')
{
if (LoadDesc(pIDriver, pstrKey, pstrDesc) != DESC_NOFILE)
{
if (!*pstrDesc)
{
/*
* failed to load a description.
* The file isn't in setup.inf
* and doesn't have exehdr information
*/
lstrcpy(pIDriver->szDesc, pIDriver->szFile);
lstrcat(pIDriver->szDesc, szNoDesc);
}
else
lstrcpy(pIDriver->szDesc, pstrDesc);
WritePrivateProfileString(szDriversDesc, pIDriver->szFile,
pIDriver->szDesc, szControlIni);
} else {
LocalFree((HANDLE)pIDriver);
goto nextkey;
}
}
strncpy(pIDriver->szAlias, pstrKey, sizeof(pIDriver->szAlias));
pIDriver->szAlias[sizeof(pIDriver->szAlias) - 1] = 0;
mbstowcs(pIDriver->wszAlias, pIDriver->szAlias, MAX_PATH);
strncpy(pIDriver->szSection, pstrSection,sizeof(pIDriver->szSection));
pIDriver->szSection[sizeof(pIDriver->szSection) - 1] = 0;
mbstowcs(pIDriver->wszSection, pIDriver->szSection, MAX_PATH);
pIDriver->KernelDriver = IsFileKernelDriver(pIDriver->szFile);
pIDriver->fQueryable = pIDriver->KernelDriver ? 0 : -1;
if (AddIDriver(hWndInstalled, pIDriver) < LB_OKAY)
LocalFree((HANDLE)pIDriver);
}
else
break; //ERROR Low Memory
nextkey: while (*pstrKey++);
}
LocalFree((HANDLE)pstrDesc);
}
/*********************************************************************
*
* FindInstallableDriversSection()
*
*********************************************************************/
PINF FindInstallableDriversSection(PINF pinf)
{
PINF pinfFound;
pinfFound = infFindSection(pinf, szMDrivers32);
if (pinfFound == NULL) {
pinfFound = infFindSection(pinf, szMDrivers);
}
return pinfFound;
}
/*********************************************************************
*
* InitInstalled()
*
* Add the drivers installed in [DRIVERS] and [MCI] to the Installed
* Drivers list box.
*
*********************************************************************/
BOOL InitInstalled(HWND hWnd, PSTR pstrSection)
{
BOOL bSuccess=FALSE;
PSTR pstr;
#ifdef TRASHDRIVERDESC
UINT wTime;
BOOL fForce;
char szOut[10];
wTime = LOWORD(GetFileDateTime(szControlIni)) >> 1;
if (fForce = (GetPrivateProfileInt((LPSTR)szUserDrivers,
(LPSTR)szLastQuery, 0, (LPSTR)szControlIni) != wTime))
{
wsprintf(szOut, "%d", wTime);
WritePrivateProfileString((LPSTR)szUserDrivers, (LPSTR)szLastQuery,
szOut, (LPSTR)szControlIni);
WritePrivateProfileString((LPSTR)szDriversDesc, NULL, NULL,
(LPSTR)szControlIni);
bDescFileValid = FALSE;
}
else
bDescFileValid = TRUE;
#endif
pstr = (PSTR)LocalAlloc(LPTR, SECTION);
if ( pstr )
{
if (*GetProfile(pstrSection, NULL, szSysIni, pstr, SECTION ))
{
AddIDrivers(hWnd,pstr,pstrSection);
bSuccess = TRUE;
}
LocalFree((HANDLE)pstr);
}
return(bSuccess);
}
static VOID CancelToClose(HWND hwnd)
{
char aszText[sizeof(aszClose)];
GetDlgItemText(hwnd, IDCANCEL, aszText, sizeof(aszText));
if (lstrcmp(aszText, aszClose))
SetDlgItemText(hwnd, IDCANCEL, aszClose);
}
static BOOL fRemove=FALSE;
/********************************************************************
*
* ListInstalledDlg()
*
* Display list of installed installable drivers. Return TRUE/FALSE
* indicating if should restart windows.
*
********************************************************************/
BOOL ListInstalledDlg(HWND hDlg, UINT uMsg, UINT wParam, LONG lParam)
{
DRVCONFIGINFO DrvConfigInfo;
HANDLE hWndI, hWnd;
PIDRIVER pIDriver;
int iIndex;
switch ( uMsg )
{
case WM_INITDIALOG:
wsStartWait();
// Window is redrawn twice at startup but showwindow does not fix it
// ShowWindow(hDlg, TRUE);
hWndI = GetDlgItem(hDlg, LB_INSTALLED);
SendMessage(hWndI,WM_SETREDRAW, FALSE, 0L);
/*
* Handle the fact that we may not be able to update our .ini
* sections
*
*/
IniFileWriteAllowed = CheckIniAccess();
if (!IniFileWriteAllowed) {
EnableWindow(GetDlgItem(hDlg, ID_ADD),FALSE);
{
char szCantAdd[120];
LoadString(myInstance, IDS_CANTADD, szCantAdd,
sizeof(szCantAdd));
MessageBox(hDlg, szCantAdd, szError,
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
}
}
if (!(InitInstalled(hDlg, szDrivers) | InitInstalled(hDlg, szMCI)))
{
EnableWindow(GetDlgItem(hDlg, ID_CONFIGURE),FALSE);
EnableWindow(GetDlgItem(hDlg, ID_REMOVE),FALSE);
}
SendMessage(hWndI, LB_SETCURSEL, 0, 0L );
PostMessage(hDlg, WM_COMMAND, MAKELONG(LB_INSTALLED, LBN_SELCHANGE),
(LONG)hWndI);
SendMessage(hWndI,WM_SETREDRAW, TRUE, 0L);
wsEndWait();
break;
case WM_COMMAND:
hlistbox = hWndI = GetDlgItem(hDlg, LB_INSTALLED);
hWndMain = hDlg;
iIndex = (int)SendMessage(hWndI, LB_GETCURSEL, 0, 0L);
pIDriver = (PIDRIVER)SendMessage(hWndI, LB_GETITEMDATA, iIndex, 0L);
switch ( LOWORD(wParam ))
{
case IDH_CHILD_DRIVERS:
goto DoHelp;
case LB_INSTALLED:
switch ( HIWORD(wParam) )
{
case LBN_SELCHANGE:
case LBN_SETFOCUS:
{
BOOL fConfigurable;
fConfigurable = ((iIndex >= LB_OKAY) && IsConfigurable(pIDriver, hDlg));
EnableWindow(GetDlgItem(hDlg, ID_CONFIGURE),
fConfigurable);
// Only enable the button if we are not in the
// process of removing a driver. Otherwise a
// button click can get stacked up, the line
// in the list box can get removed, perhaps as a
// related driver, and bad things start to happen.
EnableWindow(GetDlgItem(hDlg, ID_REMOVE),
IniFileWriteAllowed && !fRemove &&
iIndex != LB_ERR);
break;
}
case LBN_DBLCLK:
if ( IsWindowEnabled(hWnd = GetDlgItem(hDlg, ID_CONFIGURE)) )
PostMessage(hDlg, WM_COMMAND, MAKELONG(ID_CONFIGURE, BN_CLICKED),(LONG)hWnd);
break;
}
break;
case ID_ADD:
DialogBox(myInstance, MAKEINTRESOURCE(DLG_KNOWN), hDlg,
AvailableDriversDlg);
CancelToClose(hDlg);
break;
case ID_CONFIGURE:
{
HANDLE hDriver;
hDriver = OpenDriver(pIDriver->wszAlias,
pIDriver->wszSection,
0L);
if (hDriver)
{
InitDrvConfigInfo(&DrvConfigInfo, pIDriver);
if ((SendDriverMessage(
hDriver,
DRV_CONFIGURE,
(LONG)hDlg,
(LONG)(LPDRVCONFIGINFO)&DrvConfigInfo) ==
DRVCNF_RESTART))
{
iRestartMessage= 0;
DialogBox(myInstance,
MAKEINTRESOURCE(DLG_RESTART), hDlg, RestartDlg);
}
CloseDriver(hDriver, 0L, 0L);
CancelToClose(hDlg);
}
else
OpenDriverError(hDlg, pIDriver->szDesc, pIDriver->szFile);
}
break;
case ID_REMOVE:
// Prevent any more REMOVE button presses
// Otherwise one can get stacked up and cause trouble,
// particularly if it is assocated with a driver that
// is automatically removed. We have to use a static
// as any focus changes cause the button to change state.
fRemove = TRUE;
EnableWindow(GetDlgItem(hDlg, ID_REMOVE),FALSE);
if (QueryRemoveDrivers(hDlg, pIDriver->szAlias, pIDriver->szDesc))
{
LONG Status;
Status = PostRemove(hWndI, pIDriver, TRUE, iIndex);
if (Status != DRVCNF_CANCEL)
{
// As we have removed a driver we need to reset
// the current selection
PostMessage(hWndI, LB_SETCURSEL, 0, 0L );
iRestartMessage= IDS_RESTART_REM;
if (Status == DRVCNF_RESTART) {
DialogBox(myInstance,
MAKEINTRESOURCE(DLG_RESTART), hDlg, RestartDlg);
}
}
}
/* Reenable the Config/Remove buttons */
fRemove = FALSE; // Remove can be activated again
// Force the button state to be updated
PostMessage(hWndMain, WM_COMMAND,
MAKELONG(LB_INSTALLED, LBN_SELCHANGE),
(LONG)hWndI);
CancelToClose(hDlg);
break;
case IDCANCEL:
wsStartWait();
/*
* free the driver structs added as DATAITEM
*/
CloseDrivers(hWndI);
wsEndWait();
EndDialog(hDlg, FALSE);
break;
default:
return(FALSE);
}
break;
case WM_DESTROY:
return(FALSE);
default:
if (uMsg == wHelpMessage)
{
DoHelp:
WinHelp(hDlg, szDriversHlp, HELP_CONTEXT, IDH_CHILD_DRIVERS);
return TRUE;
}
else
return FALSE;
break;
}
return(TRUE);
}
/*--------------------------------------------------------------------------*
* *
* *
* LB_AVAILABLE Dialog Routines *
* *
* *
*--------------------------------------------------------------------------*/
/*
* DLG: LB_AVAILABLE
*
* InitAvailable()
*
* Add the available drivers from mmdriver.inf to the passed list box.
* The format of [Installable.drivers] in setup.inf is:
* profile=disk#:driverfile,"type1,type2","Installable driver Description","vxd1.386,vxd2.386","opt1,2,3"
*
* for example:
*
* driver1=6:sndblst.drv,"midi,wave","SoundBlaster MIDI and Waveform drivers","vdmad.386,vadmad.386","3,260"
*/
BOOL InitAvailable(HWND hWnd, int iLine)
{
PINF pinf;
BOOL bInitd=FALSE;
PSTR pstrKey;
int iIndex;
char szDesc[MAX_INF_LINE_LEN];
SendMessage(hWnd,WM_SETREDRAW, FALSE, 0L);
/*
* Parse the list of keywords and load their strings
*/
for (pinf = FindInstallableDriversSection(NULL); pinf; pinf = infNextLine(pinf))
{
//
// found at least one keyname!
//
bInitd = TRUE;
if ( (pstrKey = (PSTR)LocalAlloc(LPTR, MAX_SYS_INF_LEN)) != NULL )
infParseField(pinf, 0, pstrKey);
else
break;
/*
* add the installable driver's description to listbox, and filename as data
*/
infParseField(pinf, 3, szDesc);
if ( (iIndex = (int)SendMessage(hWnd, LB_ADDSTRING, 0, (LONG)(LPSTR)szDesc)) != LB_ERR )
SendMessage(hWnd, LB_SETITEMDATA, iIndex, (LONG)pstrKey);
}
if (iLine == UNLIST_LINE)
{
//
// Add the "Install unlisted..." choice to the top of the list
// box.
LoadString(myInstance, IDS_UPDATED, szDesc, sizeof(szDesc));
if ((iIndex = (int)(LONG)SendMessage(hWnd, LB_INSERTSTRING, 0, (LPARAM)(LPSTR)szDesc)) != LB_ERR)
SendMessage(hWnd, LB_SETITEMDATA, (WPARAM)iIndex, (LPARAM)0);
}
if (bInitd)
SendMessage(hWnd, LB_SETCURSEL, 0, 0L );
SendMessage(hWnd,WM_SETREDRAW, TRUE, 0L);
return(bInitd);
}
/*
* DLG: LB_AVAILABLE
*
* RemoveAvailable()
*
* Remove all drivers from the listbox and free all storage associated with
* the keyname
*/
void RemoveAvailable(HWND hWnd)
{
int iIndex;
HWND hWndA;
PSTR pstrKey;
hWndA = GetDlgItem(hWnd, LB_AVAILABLE);
iIndex = (int)SendMessage(hWndA, LB_GETCOUNT, 0, 0L);
while ( iIndex-- > 0)
{
if (( (int)(pstrKey = (PSTR)SendMessage(hWndA, LB_GETITEMDATA, iIndex,
0L)) != LB_ERR ) && pstrKey)
LocalFree((HLOCAL)pstrKey);
}
}
/*
* DLG: LB_AVAILABLE
*
* AvailableDriversDlg()
*
* List the available installable drivers or return FALSE if there are none.
*/
int AvailableDriversDlg(HWND hWnd, UINT uMsg, UINT wParam, LONG lParam)
{
PSTR pstrKey; //-jyg- added
HWND hWndA, hWndI;
int iIndex;
switch ( uMsg )
{
case WM_INITDIALOG:
ShowWindow(hWnd, TRUE);
wsStartWait();
if (pinfOldDefault)
{
infSetDefault(pinfOldDefault);
pinfOldDefault = NULL;
}
if ( !InitAvailable(hWndA = GetDlgItem(hWnd, LB_AVAILABLE), UNLIST_LINE))
{
/*
* We weren't able to find the [installable.drivers] section
* of the
* mmdriver.inf OR it was corrupt. Go ahead and query the
* user to find an oemsetup.inf to make our default. This
* is a bad state.
*/
EndDialog(hWnd, FALSE);
bFindOEM = TRUE;
strcpy(szDrv, szOemInf);
if (DialogBox(myInstance, MAKEINTRESOURCE(DLG_INSERTDISK),
hWnd, AddDriversDlg) == TRUE)
PostMessage(hWnd, WM_INITDIALOG, 0, 0L);
else
pinfOldDefault = infSetDefault(pinfOldDefault);
bFindOEM = FALSE;
}
wsEndWait();
break;
case WM_COMMAND:
switch ( LOWORD(wParam ))
{
case IDH_DLG_ADD_DRIVERS:
goto DoHelp;
case LB_AVAILABLE:
// Hm... We've picked it.
if ( HIWORD(wParam) == LBN_DBLCLK )
SendMessage(hWnd, WM_COMMAND, IDOK, 0L);
break;
case IDOK:
/*
* We've made our selection
*/
hWndA = GetDlgItem(hWnd, LB_AVAILABLE);
if ( (iIndex = (int)SendMessage(hWndA, LB_GETCURSEL, 0, 0L)) != LB_ERR)
{
if (!iIndex)
{
/*
* The first entry is for OEMs
*/
int iFound;
bBadOemSetup = FALSE;
bFindOEM = TRUE;
hMesgBoxParent = hWnd;
while ((iFound = DialogBox(myInstance,
MAKEINTRESOURCE(DLG_INSERTDISK), hWnd,
AddDriversDlg)) == 2);
if (iFound == 1)
{
RemoveAvailable(hWnd);
SendDlgItemMessage(hWnd, LB_AVAILABLE,
LB_RESETCONTENT, 0, 0L);
PostMessage(hWnd, WM_INITDIALOG, 0, 0L);
}
bFindOEM = FALSE;
}
else
{
/*
* The user selected an entry from our .inf
*/
wsStartWait();
/*
* The data associated with the list item is
* the driver key name (field 0 in the inf file).
*/
pstrKey = (PSTR)SendMessage(hWndA, LB_GETITEMDATA, iIndex, 0L);
bCopyingRelated = FALSE;
bQueryExist = TRUE;
if (InstallDrivers(hWndMain, hWnd, pstrKey))
{
hWndI = GetDlgItem(hWndMain, LB_INSTALLED);
PostMessage(hWndI, LB_SETCURSEL, 0, 0L );
PostMessage(hWndMain, WM_COMMAND,
MAKELONG(LB_INSTALLED, LBN_SELCHANGE),
(LONG)hWndI);
wsEndWait();
/*
* If bRestart is true then the system must
* be restarted to activate these changes
*/
if (bRestart)
{
iRestartMessage= IDS_RESTART_ADD;
DialogBox(myInstance,
MAKEINTRESOURCE(DLG_RESTART), hWnd,
RestartDlg);
}
}
else
wsEndWait();
bRestart = FALSE;
bRelated = FALSE;
}
}
EndDialog(hWnd, FALSE);
break;
case IDCANCEL:
EndDialog(hWnd, FALSE);
break;
default:
return(FALSE);
}
break;
case WM_DESTROY:
//
// free the strings added as DATAITEM to the avail list
RemoveAvailable(hWnd);
return(FALSE);
default:
if (uMsg == wHelpMessage)
{
DoHelp:
WinHelp(hWnd, szDriversHlp, HELP_CONTEXT, IDH_DLG_ADD_DRIVERS);
return TRUE;
}
else
return FALSE;
break;
}
return(TRUE);
}
/* Main CPL proc. This is for communication with CPL.EXE
*/
LONG CPlApplet(HWND hCPlWnd, UINT uMsg, UINT lParam1, LONG lParam2)
{
int i;
LPNEWCPLINFO lpCPlInfo;
char strOldDir[MAX_PATH], strSysDir[MAX_PATH];
switch( uMsg )
{
case CPL_INIT:
wHelpMessage = RegisterWindowMessage("ShellHelp");
return(TRUE);
case CPL_GETCOUNT:
return(1);
case CPL_NEWINQUIRE:
i = 0;
lpCPlInfo = (LPNEWCPLINFO)lParam2;
lpCPlInfo->hIcon = LoadIcon(myInstance,
MAKEINTRESOURCE(applets[i].idIcon));
if(!LoadString(myInstance, applets[i].idName, lpCPlInfo->szName,
sizeof(lpCPlInfo->szName)))
lpCPlInfo->szName[0] = 0;
if(!LoadString(myInstance, applets[i].idInfo, lpCPlInfo->szInfo,
sizeof(lpCPlInfo->szInfo)))
lpCPlInfo->szInfo[0] = 0;
lpCPlInfo->dwSize = sizeof(NEWCPLINFO);
lpCPlInfo->lData = (LONG)i;
lpCPlInfo->dwHelpContext = applets[i].dwContext;
lstrcpy(lpCPlInfo->szHelpFile, applets[i].pszHelp);
break;
case CPL_DBLCLK:
if (bDriversAppInUse)
{
MessageBeep(0);
return (FALSE);
}
bDriversAppInUse = TRUE;
pinfOldDefault = NULL;
GetSystemDirectory(strSysDir, MAX_PATH);
GetCurrentDirectory(MAX_PATH, strOldDir);
/*
* Switch to the system directory for our work
*/
SetCurrentDirectory(strSysDir);
/*
* Call initialization routine
*/
wsInfParseInit();
if (DialogBox(myInstance,
MAKEINTRESOURCE(DLG_INSTALLED),
hCPlWnd,
ListInstalledDlg)) {
/*
* they changed configuration of a driver and said 'yes, restart'
*/
ReBoot(hCPlWnd);
}
infClose(NULL);
/*
* Restore current directory setting
*/
SetCurrentDirectory(strOldDir);
//SetActiveWindow(hCPlWnd);
bDriversAppInUse = FALSE;
return (TRUE);
break;
case CPL_EXIT:
break;
}
return(0L);
}
BOOL DllInitialize( IN PVOID hInstance
, IN DWORD ulReason
, IN PCONTEXT pctx OPTIONAL
)
{
if (ulReason != DLL_PROCESS_ATTACH)
return TRUE;
myInstance = hInstance;
LoadString(myInstance, IDS_CLOSE, aszClose, sizeof(aszClose));
LoadString(myInstance, IDS_DRIVERDESC, szDriversDesc, sizeof(szDriversDesc));
LoadString(myInstance, IDS_FILE_ERROR, szFileError, sizeof(szFileError));
LoadString(myInstance, IDS_INSTALLDRIVERS, szMDrivers, sizeof(szMDrivers));
LoadString(myInstance, IDS_INSTALLDRIVERS32, szMDrivers32, sizeof(szMDrivers));
LoadString(myInstance, IDS_RELATEDDESC, szRelatedDesc, sizeof(szRelatedDesc));
LoadString(myInstance, IDS_USERINSTALLDRIVERS, szUserDrivers, sizeof(szUserDrivers));
LoadString(myInstance, IDS_UNLISTED, (LPSTR)szUnlisted, sizeof(szUnlisted));
LoadString(myInstance, IDS_KNOWN, szKnown, sizeof(szKnown));
LoadString(myInstance, IDS_OEMSETUP, szOemInf, sizeof(szOemInf));
LoadString(myInstance, IDS_SYSTEM, szSystem, sizeof(szSystem));
LoadString(myInstance, IDS_OUT_OF_REMOVE_SPACE, szOutOfRemoveSpace, sizeof(szOutOfRemoveSpace));
LoadString(myInstance, IDS_NO_DESCRIPTION, szNoDesc, sizeof(szNoDesc));
LoadString(myInstance, IDS_ERRORBOX, szError, sizeof(szError));
LoadString(myInstance, IDS_REMOVEORNOT, szRemoveOrNot, sizeof(szRemoveOrNot));
LoadString(myInstance, IDS_REMOVEORNOTSTRICT, szRemoveOrNotStrict, sizeof(szRemoveOrNotStrict));
LoadString(myInstance, IDS_SETUPINF, szSetupInf, sizeof(szSetupInf));
LoadString(myInstance, IDS_APPNAME, szAppName, sizeof(szAppName));
LoadString(myInstance, IDS_DRIVERS, szDrivers, sizeof(szDrivers));
LoadString(myInstance, IDS_REMOVE, szRemove, sizeof(szRemove));
LoadString(myInstance, IDS_CONTROLINI, szControlIni, sizeof(szControlIni));
LoadString(myInstance, IDS_SYSINI, szSysIni, sizeof(szSysIni));
LoadString(myInstance, IDS_MCI, szMCI, sizeof(szMCI));
LoadString(myInstance, IDS_DEFDRIVE, szDirOfSrc, sizeof(szDirOfSrc));
LoadString(myInstance, IDS_CONTROL_HLP, szDriversHlp, sizeof(szDriversHlp));
LoadString(myInstance, IDS_LASTQUERY, szLastQuery, sizeof(szLastQuery));
applets[0].idIcon = DRIVERS_ICON;
applets[0].idName = IDS_NAME;
applets[0].idInfo = IDS_INFO;
applets[0].bEnabled = TRUE;
applets[0].dwContext = IDH_CHILD_DRIVERS;
applets[0].pszHelp = szDriversHlp;
return TRUE;
}
void DeleteCPLCache(void)
{
HKEY hKeyCache;
if (ERROR_SUCCESS ==
RegOpenKey(HKEY_CURRENT_USER,
TEXT("Control Panel\\Cache\\multimed.cpl"),
&hKeyCache)) {
for ( ; ; ) {
TCHAR Name[50];
if (ERROR_SUCCESS ==
RegEnumKey(hKeyCache,
0,
Name,
sizeof(Name) / sizeof(Name[0]))) {
HKEY hSubKey;
RegDeleteKey(hKeyCache, Name);
} else {
break; // leave loop
}
}
RegDeleteKey(hKeyCache, NULL);
RegCloseKey(hKeyCache);
}
}
/*
** RestartDlg()
**
** Offer user the choice to (not) restart windows.
*/
BOOL RestartDlg(HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam)
{
switch (uiMessage)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
//
// don't restart windows
//
EndDialog(hDlg, FALSE);
break;
case IDOK:
//
// do restart windows, *dont* dismiss dialog incase
// the user canceled it.
//
ReBoot(hDlg);
SetActiveWindow(hDlg);
//EndDialog(hDlg, TRUE);
break;
default:
return FALSE;
}
return TRUE;
case WM_INITDIALOG:
/*
** Delete the control panel's cache so it will get it
** right!
*/
DeleteCPLCache();
if (iRestartMessage)
{
char szMesg1[300];
char szMesg2[300];
LoadString(myInstance, iRestartMessage, szMesg1, sizeof(szMesg1));
wsprintf(szMesg2, szMesg1, (LPSTR)szRestartDrv);
SetDlgItemText(hDlg, IDS_RESTARTTEXT, (LPSTR)szMesg2);
}
return TRUE;
case WM_KEYUP:
if (wParam == VK_F3)
//
// don't restart windows
//
EndDialog(hDlg, FALSE);
break;
default:
break;
}
return FALSE;
}
/*
* UserInstalled()
*
*
*/
BOOL UserInstalled(PSTR szKey)
{
char buf[MAXSTR];
if (*GetProfile(szUserDrivers, (LPSTR)szKey, szControlIni, buf, MAXSTR) != '\0')
return(TRUE);
else
return(FALSE);
}
/*
* AddUnlistedDlg()
*
* The following function processes requests by the user to install unlisted
* or updated drivers.
*
* PARAMETERS: The normal Dialog box parameters
* RETURN VALUE: The usual Dialog box return value
*/
BOOL AddUnlistedDlg(HWND hDlg, unsigned nMsg, UINT wParam, LONG lParam)
{
switch (nMsg)
{
case WM_INITDIALOG:
{
HWND hListDrivers;
BOOL bFoundDrivers;
wsStartWait();
hListDrivers = GetDlgItem(hDlg, LB_UNLISTED);
/* Search for drivers */
bFoundDrivers = InitAvailable(hListDrivers, NO_UNLIST_LINE);
if (!bFoundDrivers)
{
//
// We weren't able to find the MMDRIVERS section of the
// setup.inf OR it was corrupt. Go ahead and query the
// user to find an oemsetup.inf to make our default. This
// is a bad state.
//
int iFound;
bFindOEM = TRUE;
bBadOemSetup = TRUE;
while ((iFound = DialogBox(myInstance,
MAKEINTRESOURCE(DLG_INSERTDISK), hMesgBoxParent,
AddDriversDlg)) == 2);
bFindOEM = FALSE;
if (iFound == 1)
{
SendDlgItemMessage(hDlg, LB_AVAILABLE,
LB_RESETCONTENT, 0, 0L);
PostMessage(hDlg, WM_INITDIALOG, 0, 0L);
}
EndDialog(hDlg, FALSE);
}
SendMessage(hListDrivers, LB_SETCURSEL, 0, 0L);
wsEndWait();
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDH_DLG_ADD_UNKNOWN:
goto DoHelp;
case LB_UNLISTED:
if (HIWORD(wParam) != LBN_DBLCLK)
break;
// else Fall through here
case IDOK:
{
HWND hWndI, hWndA;
int iIndex;
PSTR pstrKey;
hWndA = GetDlgItem(hDlg, LB_UNLISTED);
if ( (iIndex = (int)SendMessage(hWndA, LB_GETCURSEL, 0, 0L))
!= LB_ERR)
{
wsStartWait();
pstrKey = (PSTR)SendMessage(hWndA, LB_GETITEMDATA, iIndex, 0L);
bCopyingRelated = FALSE;
bQueryExist = TRUE;
if (InstallDrivers(hWndMain, hDlg, pstrKey))
{
hWndI = GetDlgItem(hWndMain, LB_INSTALLED);
PostMessage(hWndI, LB_SETCURSEL, 0, 0L );
PostMessage(hWndMain, WM_COMMAND,
MAKELONG(LB_INSTALLED, LBN_SELCHANGE),
(LONG)hWndI);
wsEndWait();
if (bRestart)
{
iRestartMessage= IDS_RESTART_ADD;
DialogBox(myInstance, MAKEINTRESOURCE(DLG_RESTART),
hDlg, RestartDlg);
}
}
else
wsEndWait();
bRelated = FALSE;
bRestart = FALSE;
}
EndDialog(hDlg, FALSE);
}
break;
case IDCANCEL:
EndDialog(hDlg, wParam);
break;
default:
return FALSE;
}
default:
if (nMsg == wHelpMessage)
{
DoHelp:
WinHelp(hDlg, szDriversHlp, HELP_CONTEXT, IDH_DLG_ADD_UNKNOWN);
break;
}
else
return FALSE;
}
return TRUE;
}
/*
* ReBoot()
*
* Restart the system. If this fails we put up a message box
*/
void ReBoot(HWND hDlg)
{
DWORD Error;
BOOLEAN WasEnabled;
/*
* We must adjust our privilege level to be allowed to restart the
* system
*/
RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE,
TRUE,
FALSE,
&WasEnabled
);
/*
* Try to reboot the system
*/
if (!ExitWindowsEx(EWX_REBOOT, 0xFFFFFFFF)) {
Error = GetLastError();
/*
* Put up a message box if we failed
*/
if (Error != NO_ERROR) {
char szCantRestart[80];
LoadString(myInstance,
Error == ERROR_PRIVILEGE_NOT_HELD ||
Error == ERROR_NOT_ALL_ASSIGNED ||
Error == ERROR_ACCESS_DENIED ?
IDS_CANNOT_RESTART_PRIVILEGE :
IDS_CANNOT_RESTART_UNKNOWN,
szCantRestart,
sizeof(szCantRestart));
MessageBox(hDlg, szCantRestart, szError,
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
}
}
}
/*
* CloseDrivers()
*
* Make free memory for drivers.
*/
void CloseDrivers(HWND hWnd)
{
PIDRIVER pIDriver;
int iIndex;
/*
* Go through the drivers remaining in the Installed list
*/
iIndex = (int)SendMessage(hWnd, LB_GETCOUNT, 0, 0L);
while ( iIndex-- > 0 )
if ( (int)(pIDriver = (PIDRIVER)SendMessage(hWnd, LB_GETITEMDATA,
iIndex, 0L)) != LB_ERR)
{
LocalFree((HLOCAL)pIDriver);
}
}
void OpenDriverError(HWND hDlg, LPSTR szDriver, LPSTR szFile)
{
char szMesg[MAXSTR];
char szMesg2[MAXSTR];
LoadString(myInstance, IDS_INSTALLING_DRIVERS, szMesg, sizeof(szMesg));
wsprintf(szMesg2, szMesg, szDriver, szFile);
MessageBox(hDlg, szMesg2, szError, MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
}