WindowsXP-SP1/shell/osshell/control/mmsys/mmdriver.c
2020-09-30 16:53:49 +02:00

364 lines
10 KiB
C

/*----------------------------------------------------------------------------
| mmdriver.c - Install Multimedia Drivers
|
| Copyright (C) Microsoft, 1989, 1990. All Rights Reserved
|
| History:
| 09/11/90 davidle created
| Install Multimedia Drivers
|
| Tue Jan 29 1991 -by- MichaelE
| Redesigned installing installable drivers so additional drivers
| can be installed by adding them to setup.inf's [installable.drivers]
|
| Wed Mar 20 1991 -by- MichaelE
| Changed mmAddInstallableDriver to accept multiple VxDs.
| Changed and WriteNextPrivateProfileString to check if the profile
| being concatenated is already there.
|
| Sun Apr 14 1991 -by- MichaelE
| WriteNextPrivateProfileString -> Next386EnhDevice.
|
| Sun Apr 14 1991 -by- JohnYG
| Taken from setup for drivers applet.
|
| Wed Jun 05 1991 -by- MichaelE
| Added FileCopy of associated file list to windows system dir.
|
*----------------------------------------------------------------------------*/
#include <windows.h>
#include <mmsystem.h>
#include <winsvc.h>
#include <string.h>
#include <stdlib.h>
#include "drivers.h"
#include "sulib.h"
/*
* Local functions
*/
static BOOL mmAddInstallableDriver (PINF, LPTSTR, LPTSTR, PIDRIVER );
static void GetDrivers (PINF, LPTSTR, LPTSTR);
/**************************************************************************
*
* AccessServiceController()
*
* Check we will be able to access the service controller to install
* a driver
*
* returns FALSE if we can't get access - otherwise TRUE
*
**************************************************************************/
BOOL AccessServiceController(void)
{
SC_HANDLE SCManagerHandle;
SCManagerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCManagerHandle == NULL) {
return FALSE;
}
CloseServiceHandle(SCManagerHandle);
return TRUE;
}
/**************************************************************************
*
* mmAddNewDriver() - only exported function in this file.
*
* This function installs (copies) a driver
*
* returns FALSE if no drivers could be installed.
* TRUE if at least one driver installation was sucessful.
* All added types in lpszNewTypes buffer.
*
**************************************************************************/
BOOL mmAddNewDriver( LPTSTR lpstrDriver, LPTSTR lpstrNewTypes, PIDRIVER pIDriver )
{
PINF pinf;
if ((pinf = FindInstallableDriversSection(NULL)) == NULL)
return FALSE;
return mmAddInstallableDriver(pinf, lpstrDriver, lpstrNewTypes, pIDriver);
}
/**************************************************************************
* mmAddInstallableDriver() - Do the dirty work looking for VxD's copying them
* looking for drivers, copying them, and returning the best type names.
*
*
**************************************************************************/
BOOL mmAddInstallableDriver( PINF pInfIDrivers,
LPTSTR pstrDriver,
LPTSTR lpstrNewTypes,
PIDRIVER pIDriver)
{
LPTSTR pstr, pstrSection;
static TCHAR szTemp[10];
PINF pInfSection= pInfIDrivers;
int i;
TCHAR szBuffer[MAX_INF_LINE_LEN],
szFilename[MAXSTR],
szType[MAX_SECT_NAME_LEN];
/*
* format of a line in [installable.drivers] of setup.inf:
* driver profile = [0]
* filename, [1]
* "type(s)", [2]
* "description", [3]
* "VxD and .sys filename(s)",[4]
* "default config params" [5]
* "Related drivers" [6]
*
* find the driver profile line in szMDrivers we are installing
*/
while ( TRUE )
{
infParseField( pInfIDrivers, 0, szBuffer );
if ( lstrcmpi( szBuffer, pstrDriver ) == 0 )
break;
else if ( ! (pInfIDrivers = infNextLine( pInfIDrivers )) )
return FALSE;
}
/*
* copy the driver file and add driver type(s) to the installable
* driver section
*/
if ( !infParseField( pInfIDrivers, 1, szFilename ))
return FALSE;
/*
* Ignore the disk number
*/
wcscpy(szDrv, RemoveDiskId(szFilename));
/*
* Cache whether it's a kernel driver
*/
pIDriver->KernelDriver = IsFileKernelDriver(szFilename);
/*
* Can't install kernel drivers if don't have privilege
*/
if (pIDriver->KernelDriver && !AccessServiceController()) {
TCHAR szMesg[MAXSTR];
TCHAR szMesg2[MAXSTR];
TCHAR szTitle[50];
LoadString(myInstance, IDS_INSUFFICIENT_PRIVILEGE, szMesg, sizeof(szMesg)/sizeof(TCHAR));
LoadString(myInstance, IDS_CONFIGURE_DRIVER, szTitle, sizeof(szTitle)/sizeof(TCHAR));
wsprintf(szMesg2, szMesg, szDrv);
MessageBox(hMesgBoxParent, szMesg2, szTitle, MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
return FALSE;
}
/*
* Do the file copying
*/
if (FileCopy( szFilename,
szSystem,
(FPFNCOPY)wsCopySingleStatus,
FC_FILE ) != NO_ERROR) {
return FALSE;
}
/*
* Add options
*/
if (infParseField (pInfIDrivers,5,szBuffer+1))
{
szBuffer[0]=TEXT(' ');
lstrcat(szFilename,szBuffer);
}
/*
* copy filename and options
*/
wcsncpy(pIDriver->szFile, FileName(szFilename), sizeof(pIDriver->szFile)/sizeof(TCHAR));
pIDriver->szFile[sizeof(pIDriver->szFile)/sizeof(TCHAR) - 1] = 0;
/*
* copy description
*/
infParseField( pInfIDrivers, 3, pIDriver->szDesc );
/*
* determine the section from the description. A kernel driver
* will appear as a driver of type 'KERNEL' in system.ini
*
* If the description contains [MCI] then it's MCI.
*/
if (wcsstr(pIDriver->szDesc, TEXT("MCI")))
pstrSection = szMCI;
else
pstrSection = szDrivers;
/*
* Copy name plus parameters to our driver data
*/
wcsncpy(pIDriver->szSection, pstrSection, sizeof(pIDriver->szSection)/sizeof(TCHAR));
pIDriver->szSection[sizeof(pIDriver->szSection)/sizeof(TCHAR) - 1] = TEXT('\0');
wcscpy(pIDriver->wszSection, pIDriver->szSection);
/*
* We return all types in a parseable, contcatentated string
*/
for ( i = 1, infParseField( pInfIDrivers, 2, szBuffer );
infParseField( szBuffer, i, szType );
i++ )
{
pstr = &(szType[lstrlen(szType)]);
*pstr++ = TEXT(',');
*pstr = 0;
lstrcat(lpstrNewTypes, szType );
}
if (!*lpstrNewTypes)
/*
* We weren't able to return any types.
*/
return FALSE;
/*
* copy an associated file list (if it exists) to windows system dir
*/
if (FileCopy(pstrDriver,
szSystem,
(FPFNCOPY)wsCopySingleStatus,
FC_SECTION) != ERROR_SUCCESS)
return(FALSE);
/*
* if there are system driver files copy them to the system
* drivers directory.
*
* NOTE that it is assumed here that any installation and
* configuration for these drivers is performed by the main
* (.drv) driver being installed.
*
*/
if (infParseField( pInfIDrivers, 4, szBuffer ) && szBuffer[0])
{
for ( i = 1; infParseField( szBuffer, i, szFilename ); i++ )
{
wcscpy(szDrv, RemoveDiskId(szFilename));
/*
* FileCopy will adjust the 'system' directory to
* system\drivers. It's done this way because FileCopy
* must anyway look for old files in the same directory.
*/
if (FileCopy(szFilename,
szSystem,
(FPFNCOPY)wsCopySingleStatus,
FC_FILE )
!= ERROR_SUCCESS)
{
return FALSE;
}
}
}
#ifdef DOBOOT // Don't do boot section on NT
infParseField(pInfIDrivers, 7, szTemp);
if (!_strcmpi(szTemp, szBoot))
bInstallBootLine = TRUE;
#endif // DOBOOT
/*
* Read the related drivers list (drivers which must/can also be
* be installed).
*/
if (bRelated == FALSE)
{
infParseField(pInfIDrivers, 6, pIDriver->szRelated);
if (wcslen(pIDriver->szRelated))
{
GetDrivers(pInfSection, pIDriver->szRelated, pIDriver->szRemove);
pIDriver->bRelated = TRUE;
bRelated = TRUE;
}
}
return TRUE;
}
/*
* Used to get the list of the related driver filenames
*
* pInfIDrivers - Pointer to the [installable.drivers] section or equivalent
* szAliasList - List of driver aliases (ie key values - eg msalib).
* szDriverList - List of drivers file names found
*/
void GetDrivers(PINF pInfIDrivers, LPTSTR szAliasList, LPTSTR szDriverList)
{
TCHAR szBuffer[50];
TCHAR szAlias[50];
TCHAR szFileName[50];
PINF pInfILocal;
BOOL bEnd;
int i;
for ( i = 1; infParseField(szAliasList, i, szAlias); i++ )
{
pInfILocal = pInfIDrivers;
bEnd = FALSE;
while (!bEnd)
{
infParseField( pInfILocal, 0, szBuffer);
if (lstrcmpi( szBuffer, szAlias) == 0 )
{
if (infParseField(pInfILocal, 1, szFileName))
{
lstrcat(szDriverList, RemoveDiskId(szFileName));
lstrcat(szDriverList, TEXT(","));
}
break;
}
else
if ( ! (pInfILocal = infNextLine( pInfILocal )) )
bEnd = TRUE;
}
}
}