741 lines
20 KiB
C
741 lines
20 KiB
C
/*++
|
|
|
|
Copyright (c) 1995-97 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Win95.c
|
|
|
|
Abstract:
|
|
|
|
Routines for installing win95 driver files
|
|
|
|
Author:
|
|
|
|
Muhunthan Sivapragasam (MuhuntS) 30-Nov-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
const TCHAR cszPrtupg9x[] = TEXT("prtupg9x.inf");
|
|
const TCHAR cszPrinterDriverMapping[] = TEXT("Printer Driver Mapping");
|
|
const TCHAR cszPrinterDriverMappingNT[] = TEXT("Printer Driver Mapping WINNT");
|
|
|
|
void
|
|
CutLastDirFromPath(LPTSTR pszPath)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Cuts of the last directory from a path, e.g. c:\a\b\c\f.x -> c:\a\b\f.x
|
|
|
|
Arguments:
|
|
pszPath : the path to operate on
|
|
|
|
Return Value:
|
|
none
|
|
|
|
--*/
|
|
{
|
|
LPTSTR pLastWhack, pSecondButLastWhack;
|
|
|
|
pLastWhack = _tcsrchr(pszPath, _T('\\'));
|
|
if (!pLastWhack)
|
|
{
|
|
return;
|
|
}
|
|
|
|
*pLastWhack = 0;
|
|
pSecondButLastWhack = _tcsrchr(pszPath, _T('\\'));
|
|
if (!pSecondButLastWhack)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_tcscpy(pSecondButLastWhack+1, pLastWhack+1);
|
|
}
|
|
|
|
BOOL
|
|
CopyDriverFileAndModPath(LPTSTR pszPath)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Copies a driver file from the original location one dir up and modifies the
|
|
path name accordingly
|
|
|
|
Arguments:
|
|
pszPath : the path of the file to copy and to operate on
|
|
|
|
Return Value:
|
|
TRUE if OK, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
BOOL bRes = TRUE;
|
|
TCHAR *pszTmp = NULL;
|
|
|
|
if (!pszPath)
|
|
{
|
|
goto Cleanup; // nothing to copy
|
|
}
|
|
|
|
pszTmp = AllocStr( pszPath );
|
|
if (!pszTmp)
|
|
{
|
|
bRes = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
CutLastDirFromPath(pszPath);
|
|
bRes = CopyFile(pszTmp, pszPath, FALSE);
|
|
|
|
Cleanup:
|
|
|
|
LocalFreeMem( pszTmp );
|
|
return bRes;
|
|
}
|
|
|
|
BOOL
|
|
CopyDependentFiles(LPTSTR pszzDepFiles)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Copies the dependent files one directory up and modifies the name buffers.
|
|
|
|
Arguments:
|
|
pszzDepFiles : the multi-sz string containing the pathes of the files to
|
|
copy and to operate on
|
|
|
|
Return Value:
|
|
TRUE if OK, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
LPTSTR pCur = pszzDepFiles, pBuf = NULL, pCurCopy;
|
|
DWORD ccBufLen;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (pszzDepFiles == NULL)
|
|
{
|
|
bRet = TRUE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// count the total length of the buffer
|
|
//
|
|
for (ccBufLen = 0;
|
|
*(pszzDepFiles + ccBufLen) != 0;
|
|
ccBufLen += _tcslen(pszzDepFiles + ccBufLen) + 1)
|
|
;
|
|
|
|
ccBufLen +=2; // for the two terminating zeros
|
|
|
|
pBuf = LocalAllocMem(ccBufLen * sizeof(TCHAR));
|
|
if (!pBuf)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// go through the source buffer file by file, modify names and copy files
|
|
//
|
|
for (pCur = pszzDepFiles, pCurCopy = pBuf;
|
|
*pCur != 0;
|
|
pCur += _tcslen(pCur) +1, pCurCopy += _tcslen(pCurCopy) +1)
|
|
{
|
|
_tcscpy(pCurCopy, pCur);
|
|
CutLastDirFromPath(pCurCopy);
|
|
if (!CopyFile(pCur, pCurCopy, FALSE))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// 00-terminate the new buffer
|
|
//
|
|
*pCurCopy = 0;
|
|
*(++pCurCopy) = 0;
|
|
|
|
//
|
|
// copy it back - the new version is always shorter than the original
|
|
//
|
|
CopyMemory(pszzDepFiles, pBuf, (pCurCopy - pBuf + 1) * sizeof(TCHAR));
|
|
|
|
bRet = TRUE;
|
|
|
|
Cleanup:
|
|
if (pBuf)
|
|
{
|
|
LocalFreeMem(pBuf);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL
|
|
SetPreviousNamesSection(LPCTSTR pszServer, LPCTSTR pszModelName,
|
|
LPCTSTR pszAddPrevName)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
Adds a printer name to the list of previous names of a W2k/NT4 driver.
|
|
This makes the driver usable under that name for point-and-print.
|
|
To change the previous name section, do another call to AddPrinterDriver
|
|
with all the files in place
|
|
|
|
Arguments:
|
|
pszServer : the machine we're operating on.
|
|
pszModelName : the model name of the native driver
|
|
pszAddPrevName : the name of the Win9x driver to be added to the previous
|
|
names entry.
|
|
|
|
Return Value:
|
|
TRUE if OK, FALSE on error.
|
|
|
|
--*/
|
|
{
|
|
PBYTE pBuf = NULL;
|
|
DRIVER_INFO_6 *pDrvInfo6 = NULL;
|
|
DWORD cbNeeded, cReceived, i;
|
|
BOOL bRet = FALSE;
|
|
LPTSTR pTmp;
|
|
TCHAR pArch[MAX_PATH];
|
|
|
|
//
|
|
// previous names section only supported from Whistler upwards
|
|
//
|
|
if (!IsWhistlerOrAbove(pszServer))
|
|
{
|
|
bRet = TRUE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
cbNeeded = COUNTOF(pArch);
|
|
|
|
if(!GetArchitecture( pszServer, pArch, &cbNeeded ))
|
|
{
|
|
_tcsncpy( pArch, PlatformEnv[MyPlatform].pszName, COUNTOF(pArch) );
|
|
}
|
|
|
|
//
|
|
// Check whether the name is different in the first place
|
|
//
|
|
if (!_tcscmp(pszModelName, pszAddPrevName))
|
|
{
|
|
bRet = TRUE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Get the DRIVER_INFO_6 of the W2k driver
|
|
//
|
|
EnumPrinterDrivers((LPTSTR) pszServer, pArch, 6, pBuf,
|
|
0, &cbNeeded, &cReceived);
|
|
|
|
pBuf = LocalAllocMem(cbNeeded);
|
|
if (!pBuf)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
if (!EnumPrinterDrivers((LPTSTR) pszServer, pArch, 6, pBuf,
|
|
cbNeeded, &cbNeeded, &cReceived))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
for (i = 0; i < cReceived ; i++)
|
|
{
|
|
pDrvInfo6 = (DRIVER_INFO_6 *) (pBuf + i*sizeof(DRIVER_INFO_6));
|
|
if (!_tcscmp(pszModelName, pDrvInfo6->pName))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// was the corresponding W2k driver found ?
|
|
//
|
|
if (i == cReceived)
|
|
{
|
|
//
|
|
// Couldn't find the W2k driver to set the previous names section on.
|
|
// This must be the AddPrinterDriver wizard, else there would be one.
|
|
// Just let the user install this driver.
|
|
//
|
|
bRet = TRUE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// check whether the name to add is already in the list
|
|
//
|
|
if (pDrvInfo6->pszzPreviousNames)
|
|
{
|
|
for (pTmp = pDrvInfo6->pszzPreviousNames; *pTmp; pTmp += _tcslen(pTmp) +1)
|
|
{
|
|
if (!_tcscmp(pTmp, pszAddPrevName))
|
|
{
|
|
bRet = TRUE;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Copy all the files into the driver dir
|
|
//
|
|
if (!CopyDriverFileAndModPath(pDrvInfo6->pDriverPath) ||
|
|
!CopyDriverFileAndModPath(pDrvInfo6->pConfigFile) ||
|
|
!CopyDriverFileAndModPath(pDrvInfo6->pDataFile) ||
|
|
!CopyDriverFileAndModPath(pDrvInfo6->pHelpFile) ||
|
|
!CopyDependentFiles(pDrvInfo6->pDependentFiles))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Modify the PreviousNames section.
|
|
// No reallocation since string lives in the same buffer as the DrvInfo6 !
|
|
// +2 for the psz terminating zero and the second zero for the whole
|
|
//
|
|
pDrvInfo6->pszzPreviousNames = LocalAllocMem((_tcslen(pszAddPrevName) + 2) * sizeof(TCHAR));
|
|
|
|
if (!pDrvInfo6->pszzPreviousNames)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
_tcscpy(pDrvInfo6->pszzPreviousNames, pszAddPrevName);
|
|
|
|
//
|
|
// write the driver info 6 back
|
|
//
|
|
bRet = AddPrinterDriver((LPTSTR) pszServer, 6, (LPBYTE) pDrvInfo6);
|
|
|
|
LocalFreeMem (pDrvInfo6->pszzPreviousNames);
|
|
|
|
Cleanup:
|
|
if (pBuf)
|
|
{
|
|
LocalFreeMem (pBuf);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
DWORD
|
|
InstallWin95Driver(
|
|
IN HWND hwnd,
|
|
IN LPCTSTR pszModel,
|
|
IN LPCTSTR pszzPreviousNames,
|
|
IN BOOL bPreviousNamesSection,
|
|
IN LPCTSTR pszServerName,
|
|
IN OUT LPTSTR pszInfPath,
|
|
IN LPCTSTR pszDiskName,
|
|
IN DWORD dwInstallFlags,
|
|
IN DWORD dwAddDrvFlags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
List all the printer drivers from Win95 INF files and install the
|
|
printer driver selected by the user
|
|
|
|
Arguments:
|
|
hwnd : Window handle that owns the UI
|
|
pszModel : Printer driver model
|
|
pszzPreviousNames : Multi-sz string giving other names for the driver
|
|
bPreviousNamesSection : If TRUE the NT inf had a Previous Names section
|
|
pszServerName : Server for which driver is to be installed
|
|
(NULL : local)
|
|
pszInfPath : Default path for inf. Prompt will have this name
|
|
for user
|
|
pszDiskName : Name of the disk to prompt for and use in title
|
|
dwInstallFlags : Installation flags given by caller
|
|
dwAddDrvFlags : Flags for AddPrinterDriverEx
|
|
|
|
Return Value:
|
|
On succesfully installing files ERROR_SUCCESS, else the error code
|
|
|
|
--*/
|
|
{
|
|
BOOL bFreeDriverName=FALSE, bFirstTime=TRUE;
|
|
DWORD dwNeeded, dwRet = ERROR_CANCELLED;
|
|
TCHAR szTargetPath[MAX_PATH];
|
|
LPDRIVER_INFO_6 pDriverInfo6 = NULL;
|
|
PPSETUP_LOCAL_DATA pLocalData = NULL;
|
|
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
|
|
|
|
Retry:
|
|
//
|
|
// If we get here second time that means default path has INFs but not the
|
|
// model we are looking for. Ex. an OEM driver in the previous names section
|
|
// that is not on Win2K CD. So make sure we prompt
|
|
//
|
|
if ( !bFirstTime )
|
|
{
|
|
dwInstallFlags |= DRVINST_ALT_PLATFORM_INSTALL;
|
|
if (pszInfPath)
|
|
{
|
|
*pszInfPath = 0;
|
|
}
|
|
}
|
|
|
|
hDevInfo = GetInfAndBuildDrivers(hwnd,
|
|
IDS_DRIVERS_FOR_WIN95,
|
|
IDS_PROMPT_ALT_PLATFORM_DRIVER,
|
|
pszInfPath,
|
|
dwInstallFlags, PlatformWin95, 0,
|
|
NULL, NULL, NULL);
|
|
|
|
if ( hDevInfo == INVALID_HANDLE_VALUE ||
|
|
!SetSelectDevParams(hDevInfo, NULL, TRUE, pszModel) ) {
|
|
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// First look for an exact model match.
|
|
//
|
|
// If previous name is found then we will allow one retry since now we
|
|
// have some previous names with no driver on CD (since it is an OEM driver)
|
|
// If previous name is not found ask user to select a model
|
|
//
|
|
if ( !(pDriverInfo6 = Win95DriverInfo6FromName(hDevInfo,
|
|
&pLocalData,
|
|
pszModel,
|
|
pszzPreviousNames)) ) {
|
|
|
|
if ( bPreviousNamesSection ) {
|
|
|
|
if ( bFirstTime == TRUE ) {
|
|
|
|
ASSERT(pLocalData == NULL);
|
|
DestroyOnlyPrinterDeviceInfoList(hDevInfo);
|
|
hDevInfo = INVALID_HANDLE_VALUE;
|
|
bFirstTime = FALSE;
|
|
goto Retry;
|
|
}
|
|
}
|
|
|
|
if ( (dwInstallFlags & DRVINST_PROMPTLESS) == 0)
|
|
{
|
|
PVOID pDSInfo = NULL; // Holds pointer to the driver signing class that C can't understand.
|
|
HSPFILEQ CopyQueue;
|
|
SP_DEVINSTALL_PARAMS DevInstallParams = {0};
|
|
|
|
DevInstallParams.cbSize = sizeof(DevInstallParams);
|
|
|
|
DestroyOnlyPrinterDeviceInfoList(hDevInfo);
|
|
|
|
hDevInfo = CreatePrinterDeviceInfoList(hwnd);
|
|
|
|
if ( hDevInfo == INVALID_HANDLE_VALUE ||
|
|
!SetDevInstallParams(hDevInfo, NULL, pszInfPath))
|
|
{
|
|
DWORD dwLastError;
|
|
dwLastError = GetLastError();
|
|
DestroyOnlyPrinterDeviceInfoList(hDevInfo);
|
|
hDevInfo = INVALID_HANDLE_VALUE;
|
|
SetLastError(dwLastError);
|
|
goto Cleanup;
|
|
}
|
|
|
|
CopyQueue = SetupOpenFileQueue();
|
|
if ( CopyQueue == INVALID_HANDLE_VALUE )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// associate the queue with the HDEVINFO
|
|
//
|
|
|
|
if ( SetupDiGetDeviceInstallParams(hDevInfo,
|
|
NULL,
|
|
&DevInstallParams) )
|
|
{
|
|
DevInstallParams.Flags |= DI_NOVCP;
|
|
DevInstallParams.FileQueue = CopyQueue;
|
|
|
|
SetupDiSetDeviceInstallParams(hDevInfo, NULL, &DevInstallParams);
|
|
}
|
|
|
|
if (NULL == (pDSInfo = SetupDriverSigning(hDevInfo, pszServerName, NULL,
|
|
pszInfPath, PlatformWin95, 0, CopyQueue, FALSE)))
|
|
{
|
|
SetupCloseFileQueue(CopyQueue);
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( BuildClassDriverList(hDevInfo) &&
|
|
PSetupSelectDriver(hDevInfo) &&
|
|
(pLocalData = BuildInternalData(hDevInfo, NULL)) &&
|
|
ParseInf(hDevInfo, pLocalData, PlatformWin95,
|
|
pszServerName, dwInstallFlags) )
|
|
{
|
|
|
|
LPCTSTR pDriverName;
|
|
|
|
pDriverInfo6 = CloneDriverInfo6(&pLocalData->InfInfo.DriverInfo6,
|
|
pLocalData->InfInfo.cbDriverInfo6);
|
|
|
|
//
|
|
// if setup selected a "compatible" driver:
|
|
// pre-Whistler: rename the compatible driver to the requested model name
|
|
// on Whistler: set the driver name to the compatible one and set the previous names section accordingly
|
|
//
|
|
if (IsWhistlerOrAbove(pszServerName))
|
|
{
|
|
pDriverName = pLocalData->DrvInfo.pszModelName;
|
|
}
|
|
else
|
|
{
|
|
pDriverName = pszModel;
|
|
}
|
|
|
|
if ( pDriverInfo6 && (pDriverInfo6->pName = AllocStr(pDriverName)) )
|
|
{
|
|
bFreeDriverName = TRUE;
|
|
}
|
|
|
|
}
|
|
//
|
|
// disassociate the queue before deleting it
|
|
//
|
|
|
|
DevInstallParams.Flags &= ~DI_NOVCP;
|
|
DevInstallParams.FlagsEx &= ~DI_FLAGSEX_ALTPLATFORM_DRVSEARCH;
|
|
DevInstallParams.FileQueue = INVALID_HANDLE_VALUE;
|
|
|
|
SetupDiSetDeviceInstallParams(hDevInfo, NULL, &DevInstallParams);
|
|
|
|
SetupCloseFileQueue(CopyQueue);
|
|
|
|
CleanupDriverSigning(pDSInfo);
|
|
}
|
|
}
|
|
else if (lstrcmp(pDriverInfo6->pName, pszModel))
|
|
{
|
|
//
|
|
// if the driver was selected because of an entry in the previous names section
|
|
// then on anything before Whistler we need to rename the driver to the queue driver's name
|
|
//
|
|
if (!IsWhistlerOrAbove(pszServerName))
|
|
{
|
|
if (pDriverInfo6->pName = AllocStr(pszModel) )
|
|
{
|
|
bFreeDriverName = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if ( !pDriverInfo6 || !pDriverInfo6->pName )
|
|
goto Cleanup;
|
|
|
|
pDriverInfo6->pEnvironment = PlatformEnv[PlatformWin95].pszName;
|
|
|
|
|
|
//
|
|
// For Win95 driver pszzPreviousNames does not make sense
|
|
//
|
|
ASSERT(pDriverInfo6->pszzPreviousNames == NULL);
|
|
|
|
if ( GetPrinterDriverDirectory((LPTSTR)pszServerName,
|
|
pDriverInfo6->pEnvironment,
|
|
1,
|
|
(LPBYTE)szTargetPath,
|
|
sizeof(szTargetPath),
|
|
&dwNeeded) &&
|
|
CopyPrinterDriverFiles(pDriverInfo6,
|
|
pLocalData->DrvInfo.pszInfName,
|
|
pszInfPath,
|
|
pszDiskName,
|
|
szTargetPath,
|
|
hwnd,
|
|
dwInstallFlags,
|
|
TRUE) &&
|
|
SetPreviousNamesSection(pszServerName, pszModel,
|
|
(LPCTSTR) pLocalData->DrvInfo.pszModelName) &&
|
|
AddPrinterDriverUsingCorrectLevel(pszServerName,
|
|
pDriverInfo6,
|
|
dwAddDrvFlags)
|
|
)
|
|
|
|
{
|
|
dwRet = ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
Cleanup:
|
|
|
|
if (pLocalData)
|
|
{
|
|
DestroyLocalData(pLocalData);
|
|
pLocalData = NULL;
|
|
}
|
|
|
|
if ( dwRet != ERROR_SUCCESS )
|
|
dwRet = GetLastError();
|
|
|
|
if ( hDevInfo != INVALID_HANDLE_VALUE )
|
|
DestroyOnlyPrinterDeviceInfoList(hDevInfo);
|
|
|
|
if ( pDriverInfo6 ) {
|
|
|
|
if ( bFreeDriverName )
|
|
LocalFreeMem(pDriverInfo6->pName);
|
|
PSetupDestroyDriverInfo3((LPDRIVER_INFO_3)pDriverInfo6);
|
|
}
|
|
|
|
CleanupScratchDirectory(pszServerName, PlatformWin95);
|
|
CleanupScratchDirectory(pszServerName, PlatformX86);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
|
|
PSetupFindMappedDriver
|
|
|
|
Routine Description:
|
|
|
|
Find the remapped NT printer driver name for the given driver name. If the
|
|
function does not find a remapped driver, it simply returns the name that was
|
|
passed in. This looks in the [Printer Driver Mapping] and
|
|
[Printer Driver Mapping WINNT] sections of prtupg9x.inf.
|
|
|
|
Arguments:
|
|
|
|
bWinNT - If TRUE, find this from the WINNT section.
|
|
pszDriverName - The driver name to be remapped.
|
|
ppszRemappedDriverName - The remapped driver name, allocated and returned
|
|
to the caller. (Free with PSetupFreeMem).
|
|
pbDriverFound - If TRUE, the driver was remapped. Otherwise, the
|
|
output is simpy a copy of the input.
|
|
|
|
Return Value:
|
|
|
|
If there is an unexpected error, FALSE, otherwise TRUE. Last Error has the
|
|
error code.
|
|
|
|
--*/
|
|
BOOL
|
|
PSetupFindMappedDriver(
|
|
IN BOOL bWinNT,
|
|
IN LPCTSTR pszDriverName,
|
|
OUT LPTSTR *ppszRemappedDriverName,
|
|
OUT BOOL *pbDriverFound
|
|
)
|
|
{
|
|
HINF hInf = INVALID_HANDLE_VALUE;
|
|
BOOL bRet = FALSE;
|
|
BOOL bFound = FALSE;
|
|
LPTSTR pszRemappedDriverName = NULL;
|
|
INFCONTEXT InfContext;
|
|
TCHAR szNtName[LINE_LEN];
|
|
|
|
bRet = pszDriverName && ppszRemappedDriverName && pbDriverFound;
|
|
|
|
if (ppszRemappedDriverName)
|
|
{
|
|
*ppszRemappedDriverName = NULL;
|
|
}
|
|
|
|
if (pbDriverFound)
|
|
{
|
|
*pbDriverFound = FALSE;
|
|
}
|
|
|
|
if (!bRet)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Open ntprint.inf, it should be in the %windir%\inf directory.
|
|
//
|
|
if (bRet)
|
|
{
|
|
hInf = SetupOpenInfFile(cszPrtupg9x, NULL, INF_STYLE_WIN4, NULL);
|
|
|
|
bRet = hInf != INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
//
|
|
// Find the driver in the appropriate Printer Driver Mapping section of the
|
|
// inf.
|
|
//
|
|
if (bRet)
|
|
{
|
|
bFound = SetupFindFirstLine(hInf, bWinNT ? cszPrinterDriverMappingNT : cszPrinterDriverMapping, pszDriverName, &InfContext);
|
|
|
|
//
|
|
// Get the name of the in-box driver.
|
|
//
|
|
if (bFound)
|
|
{
|
|
bRet = SetupGetStringField(&InfContext, 1, szNtName, COUNTOF(szNtName), NULL);
|
|
}
|
|
else if (ERROR_LINE_NOT_FOUND != GetLastError())
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we found the driver, return it. Otherwise, just allocate and return the
|
|
// string that was passed in.
|
|
//
|
|
if (bRet)
|
|
{
|
|
if (bFound)
|
|
{
|
|
pszRemappedDriverName = AllocStr(szNtName);
|
|
|
|
*pbDriverFound = pszRemappedDriverName != NULL;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// The remapped driver is not in the inf. Return the one we were passed in.
|
|
//
|
|
pszRemappedDriverName = AllocStr(pszDriverName);
|
|
}
|
|
|
|
bRet = pszRemappedDriverName != NULL;
|
|
}
|
|
|
|
if (bRet)
|
|
{
|
|
*ppszRemappedDriverName = pszRemappedDriverName;
|
|
pszRemappedDriverName = NULL;
|
|
}
|
|
|
|
if (hInf != INVALID_HANDLE_VALUE)
|
|
{
|
|
SetupCloseInfFile(hInf);
|
|
}
|
|
|
|
if (pszRemappedDriverName)
|
|
{
|
|
LocalFreeMem(pszRemappedDriverName);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|