Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

949 lines
25 KiB

/******************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORP., 2000
*
* TITLE: Util.cpp
*
* VERSION: 1.0
*
* AUTHOR: KeisukeT
*
* DATE: 27 Mar, 2000
*
* DESCRIPTION:
* Utility function for WIA class installer.
*
* NOTE:
* All of string buffers dealt in these functions must have at least
* MAX_DESCRIPTION size. Since it doesn't have size check of buffer, it assumes
* all string size is unfer MAX_DESCRIPTION, which must be OK to be used only
* for WIA class installer.
*
*******************************************************************************/
//
// Precompiled header
//
#include "precomp.h"
#pragma hdrstop
//
// Include
//
#include "sti_ci.h"
#include <regstr.h>
#include <cfgmgr32.h>
//
// Extern
//
extern HINSTANCE g_hDllInstance;
//
// Function
//
BOOL
GetInfInforamtionFromSelectedDevice(
HDEVINFO hDevInfo,
LPTSTR pInfFileName,
LPTSTR pInfSectionName
)
{
BOOL bRet;
SP_DEVINFO_DATA DeviceInfoData;
SP_DRVINFO_DATA DriverInfoData;
SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
HINF hInf;
TCHAR szInfFileName[MAX_DESCRIPTION];
TCHAR szInfSectionName[MAX_DESCRIPTION];
DebugTrace(TRACE_PROC_ENTER,(("GetInfInforamtionFromSelectedDevice: Enter... \r\n")));
hInf = INVALID_HANDLE_VALUE;
bRet = FALSE;
//
// Check arguments.
//
if( (NULL == hDevInfo)
|| (NULL == pInfFileName)
|| (NULL == pInfSectionName) )
{
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! Invalid argument. \r\n")));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Initialize locals.
//
memset (&DeviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
memset (&DriverInfoData, 0, sizeof(SP_DRVINFO_DATA));
memset (&DriverInfoDetailData, 0, sizeof(SP_DRVINFO_DETAIL_DATA));
memset (szInfFileName, 0, sizeof(szInfFileName));
memset (szInfSectionName, 0, sizeof(szInfSectionName));
DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
//
// Get selected device element.
//
if (!SetupDiGetSelectedDevice (hDevInfo, &DeviceInfoData)) {
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetSelectedDevice Failed. Err=0x%lX\r\n"), GetLastError()));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Get selected device driver information.
//
if (!SetupDiGetSelectedDriver(hDevInfo, &DeviceInfoData, &DriverInfoData)) {
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetSelectedDriver Failed. Err=0x%lX\r\n"), GetLastError()));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Get detailed data of selected device driver.
//
if(!SetupDiGetDriverInfoDetail(hDevInfo,
&DeviceInfoData,
&DriverInfoData,
&DriverInfoDetailData,
sizeof(DriverInfoDetailData),
NULL) )
{
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetDriverInfoDetail Failed.Er=0x%lX\r\n"),GetLastError()));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Copy INF filename.
//
_tcsncpy(szInfFileName, DriverInfoDetailData.InfFileName, sizeof(szInfFileName)/sizeof(TCHAR));
//
// Open INF file of selected driver.
//
hInf = SetupOpenInfFile(szInfFileName,
NULL,
INF_STYLE_WIN4,
NULL);
if (hInf == INVALID_HANDLE_VALUE) {
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupOpenInfFile Failed.Er=0x%lX\r\n"),GetLastError()));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Get actual INF section name to be installed.
//
if (!SetupDiGetActualSectionToInstall(hInf,
DriverInfoDetailData.SectionName,
szInfSectionName,
sizeof(szInfSectionName)/sizeof(TCHAR),
NULL,
NULL) )
{
DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetActualSectionToInstall Failed.Er=0x%lX\r\n"),GetLastError()));
bRet = FALSE;
goto GetInfInforamtionFromSelectedDevice_return;
}
//
// Copy strings to given buffer.
//
_tcsncpy(pInfFileName, szInfFileName, sizeof(szInfFileName)/sizeof(TCHAR));
_tcsncpy(pInfSectionName, szInfSectionName, sizeof(szInfSectionName)/sizeof(TCHAR));
//
// Operation succeeded.
//
bRet = TRUE;
GetInfInforamtionFromSelectedDevice_return:
if(INVALID_HANDLE_VALUE != hInf){
SetupCloseInfFile(hInf);
}
DebugTrace(TRACE_PROC_LEAVE,(("GetInfInforamtionFromSelectedDevice: Leaving... Ret=0x%x\n"), bRet));
return bRet;
}
BOOL
GetStringFromRegistry(
HKEY hkRegistry,
LPCTSTR szValueName,
LPTSTR pBuffer
)
{
BOOL bRet;
LONG lError;
DWORD dwSize;
DWORD dwType;
TCHAR szString[MAX_DESCRIPTION];
//
// Initialize local.
//
bRet = FALSE;
lError = ERROR_SUCCESS;
dwSize = sizeof(szString);
memset(szString, 0, sizeof(szString));
//
// Check arguments.
//
if( (NULL == hkRegistry)
|| (NULL == szValueName)
|| (NULL == pBuffer) )
{
DebugTrace(TRACE_ERROR,(("GetStringFromRegistry: ERROR!! Invalid argument\r\n")));
bRet = FALSE;
goto GetStringFromRegistry_return;
}
//
// Get specified string from registry.
//
lError = RegQueryValueEx(hkRegistry,
szValueName,
NULL,
&dwType,
(LPBYTE)szString,
&dwSize);
if(ERROR_SUCCESS != lError){
DebugTrace(TRACE_ERROR,(("GetStringFromRegistry: ERROR!! RegQueryValueEx failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE;
goto GetStringFromRegistry_return;
}
//
// Make sure NULL termination.
//
szString[ARRAYSIZE(szString)-1] = TEXT('\0');
//
// Copy acquired string to given buffer. This function assume max-string/bufer size is MAX_DESCRIPTION.
//
_tcsncpy(pBuffer, szString, MAX_DESCRIPTION);
//
// Operation succeeded.
//
bRet = TRUE;
GetStringFromRegistry_return:
return bRet;
}
BOOL
GetDwordFromRegistry(
HKEY hkRegistry,
LPCTSTR szValueName,
LPDWORD pdwValue
)
{
BOOL bRet;
LONG lError;
DWORD dwSize;
DWORD dwType;
DWORD dwValue;
//
// Initialize local.
//
bRet = FALSE;
lError = ERROR_SUCCESS;
dwSize = sizeof(dwValue);
dwValue = 0;
//
// Check arguments.
//
if( (NULL == hkRegistry)
|| (NULL == szValueName)
|| (NULL == pdwValue) )
{
DebugTrace(TRACE_ERROR,(("GetDwordFromRegistry: ERROR!! Invalid argument\r\n")));
bRet = FALSE;
goto GetDwordFromRegistry_return;
}
//
// Get specified string from registry.
//
lError = RegQueryValueEx(hkRegistry,
szValueName,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwSize);
if(ERROR_SUCCESS != lError){
DebugTrace(TRACE_ERROR,(("GetDwordFromRegistry: ERROR!! RegQueryValueEx failed. Err=0x%x. Size=0x%x, Type=0x%x\r\n"), lError, dwSize, dwType));
bRet = FALSE;
goto GetDwordFromRegistry_return;
}
//
// Copy acquired DWORD value to given buffer.
//
*pdwValue = dwValue;
//
// Operation succeeded.
//
bRet = TRUE;
GetDwordFromRegistry_return:
return bRet;
} // GetDwordFromRegistry
VOID
SetRunonceKey(
LPTSTR szValue,
LPTSTR szData
)
{
HKEY hkRun;
LONG lResult;
CString csData;
//
// Initialize local.
//
hkRun = NULL;
lResult = ERROR_SUCCESS;
csData = szData;
//
// Get RUNONCE regkey.
//
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGSTR_PATH_RUNONCE,
0,
KEY_READ | KEY_WRITE,
&hkRun);
if(ERROR_SUCCESS == lResult){
csData.Store(hkRun, szValue);
RegCloseKey(hkRun);
} // if(ERROR_SUCCESS == lResult)
} // SetRunonceKey()
VOID
ShowInstallerMessage(
DWORD dwMessageId
)
{
CString csTitle;
CString csText;
csTitle.FromTable (MessageTitle);
csText.FromTable ((unsigned)dwMessageId);
if( !csTitle.IsEmpty() && !csText.IsEmpty()){
MessageBox (GetActiveWindow(),
csText,
csTitle,
MB_ICONINFORMATION | MB_OK);
} // if(csTitle.IsEmpty() || csText.IsEmpty())
} // ShowInstallerMessage()
BOOL
IsWindowsFile(
LPTSTR szFileName
)
{
BOOL bRet;
DWORD dwNumberOfChar;
TCHAR szLayoutInfpath[MAX_PATH+1];
TCHAR szReturnBuffer[MAX_PATH];
TCHAR *pszFileNameWithoutPath;
DWORD Idx;
DebugTrace(TRACE_PROC_ENTER,("IsWindowsFile: Enter... Checking %ws.\r\n", szFileName));
//
// Initialize local.
//
bRet = FALSE;
dwNumberOfChar = 0;
Idx = 0;
pszFileNameWithoutPath = NULL;
memset(szLayoutInfpath, 0, sizeof(szLayoutInfpath));
//
// Get INF filename without path.
//
while(TEXT('\0') != szFileName[Idx]){
if(TEXT('\\') == szFileName[Idx]){
pszFileNameWithoutPath = &(szFileName[Idx+1]);
} // if('\\' == szFileName[Idx])
Idx++;
} // while('\0' != szFileName[Idx])
//
// Get system directory.
//
if(0 == GetWindowsDirectory(szLayoutInfpath, sizeof(szLayoutInfpath)/sizeof(TCHAR))){
DebugTrace(TRACE_ERROR,("IsWindowsFile: ERROR!! GetWindowsDirectory failed. Err=0x%x.\r\n", GetLastError()));
bRet = FALSE;
goto IsWindowsFile_return;
} // if(0 == GetWindowsDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(TCHAR)))
//
// Create fullpath of layout.inf.
//
lstrcat(szLayoutInfpath, LAYOUT_INF_PATH);
DebugTrace(TRACE_STATUS,("IsWindowsFile: Looking for \'%ws\' in %ws.\r\n", pszFileNameWithoutPath, szLayoutInfpath));
//
// See if provided filename is in layout.inf.
//
dwNumberOfChar = GetPrivateProfileString(SOURCEDISKFILES,
pszFileNameWithoutPath,
NULL,
szReturnBuffer,
sizeof(szReturnBuffer) / sizeof(TCHAR),
szLayoutInfpath);
if(0 == dwNumberOfChar){
//
// Filename doesn't exist in layout.inf.
//
bRet = FALSE;
goto IsWindowsFile_return;
} // if(0 == dwNumberOfChar)
//
// This filename exists in layout.inf.
//
bRet = TRUE;
IsWindowsFile_return:
DebugTrace(TRACE_PROC_LEAVE,("IsWindowsFile: Leaving... Ret=0x%x\n", bRet));
return bRet;
} // IsWindowsFile()
BOOL
IsProviderMs(
LPTSTR szInfName
)
{
BOOL bRet;
DWORD dwSize;
TCHAR szProvider[MAX_PATH+1];
PSP_INF_INFORMATION pspInfInfo;
DebugTrace(TRACE_PROC_ENTER,("IsProviderMs: Enter... Checking %ws.\r\n", szInfName));
//
// Initialize local.
//
bRet = FALSE;
dwSize = 0;
pspInfInfo = NULL;
memset(szProvider, 0, sizeof(szProvider));
//
// Get INF information size.
//
SetupGetInfInformation(szInfName,
INFINFO_INF_NAME_IS_ABSOLUTE,
NULL,
0,
&dwSize);
if(0 == dwSize){
DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Enable to get required size for INF info. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE;
goto IsProviderMs_return;
} // if(0 == dwSize)
//
// Allocate buffer for INF information.
//
pspInfInfo = (PSP_INF_INFORMATION) new char[dwSize];
if(NULL == pspInfInfo){
DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Insuffisient memory.\r\n")));
bRet = FALSE;
goto IsProviderMs_return;
} // if(NULL == pspInfInfo)
//
// Get actual INF informaton.
//
if(!SetupGetInfInformation(szInfName,
INFINFO_INF_NAME_IS_ABSOLUTE,
pspInfInfo,
dwSize,
&dwSize))
{
DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Unable to get Inf info. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE;
goto IsProviderMs_return;
} // if(!SetupGetInflnformation()
//
// Query "Provider" of given INF.
//
if(!SetupQueryInfVersionInformation(pspInfInfo,
0,
PROVIDER,
szProvider,
ARRAYSIZE(szProvider)-1,
&dwSize))
{
DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! SetupQueryInfVersionInformation() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE;
goto IsProviderMs_return;
} // if(!SetupGetInflnformation()
//
// See if provider is "Microsoft"
//
DebugTrace(TRACE_STATUS,(("IsProviderMs: Provider = \'%ws\'.\r\n"), szProvider));
if(0 == MyStrCmpi(szProvider, MICROSOFT)){
//
// This INF file has 'Provider = "Microsoft"'
//
bRet = TRUE;
} // if(0 == lstrcmp(szProvider, MICROSOFT))
IsProviderMs_return:
if(NULL != pspInfInfo){
delete[] pspInfInfo;
} // if(NULL != pspInfInfo)
DebugTrace(TRACE_PROC_LEAVE,("IsProviderMs: Leaving... Ret=0x%x\n", bRet));
return bRet;
} // IsProviderMs()
BOOL
IsIhvAndInboxExisting(
HDEVINFO hDevInfo,
PSP_DEVINFO_DATA pDevInfoData
)
{
BOOL bRet;
BOOL bIhvExists;
BOOL bInboxExists;
DWORD dwLastError;
DWORD dwSize;
DWORD Idx;
SP_DRVINSTALL_PARAMS spDriverInstallParams;
SP_DRVINFO_DATA spDriverInfoData;
PSP_DRVINFO_DETAIL_DATA pspDriverInfoDetailData;
//
// Initialize local.
//
bRet = FALSE;
bIhvExists = FALSE;
bInboxExists = FALSE;
dwSize = 0;
Idx = 0;
dwLastError = ERROR_SUCCESS;
pspDriverInfoDetailData = NULL;
memset(&spDriverInstallParams, 0, sizeof(spDriverInstallParams));
//
// Get driver info.
//
memset(&spDriverInfoData, 0, sizeof(spDriverInfoData));
spDriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData); Idx++){
//
// Get driver install params.
//
memset(&spDriverInstallParams, 0, sizeof(spDriverInstallParams));
spDriverInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams)){
DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInstallParams() failed LastError=0x%x.\r\n", GetLastError()));
goto IsIhvAndInboxExisting_return;
} // if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams))
//
// Get buffer size required for driver derail data.
//
dwSize = 0;
SetupDiGetDriverInfoDetail(hDevInfo,
pDevInfoData,
&spDriverInfoData,
NULL,
0,
&dwSize);
dwLastError = GetLastError();
if(ERROR_INSUFFICIENT_BUFFER != dwLastError){
DebugTrace(TRACE_ERROR,(("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() doesn't return required size.Er=0x%x\r\n"),dwLastError));
goto IsIhvAndInboxExisting_return;
} // if(ERROR_INSUFFICIENT_BUFFER != dwLastError)
//
// Allocate required size of buffer for driver detailed data.
//
pspDriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)new char[dwSize];
if(NULL == pspDriverInfoDetailData){
DebugTrace(TRACE_ERROR,(("IsIhvAndInboxExisting: ERROR!! Unable to allocate driver detailed info buffer.\r\n")));
goto IsIhvAndInboxExisting_return;
} // if(NULL == pspDriverInfoDetailData)
//
// Initialize allocated buffer.
//
memset(pspDriverInfoDetailData, 0, dwSize);
pspDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
//
// Get detailed data of selected device driver.
//
if(!SetupDiGetDriverInfoDetail(hDevInfo,
pDevInfoData,
&spDriverInfoData,
pspDriverInfoDetailData,
dwSize,
NULL) )
{
DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() failed LastError=0x%x.\r\n", GetLastError()));
delete[] pspDriverInfoDetailData;
pspDriverInfoDetailData = NULL;
continue;
} // if(NULL == pspDriverInfoDetailData)
//
// See if INF filename is valid.
//
if(NULL == pspDriverInfoDetailData->InfFileName){
DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() returned invalid INF name.\r\n"));
delete[] pspDriverInfoDetailData;
pspDriverInfoDetailData = NULL;
continue;
} // if(NULL == pspDriverInfoDetailData->InfFileName)
//
// If it's Inbox driver, lower the lank.
//
if( IsWindowsFile(pspDriverInfoDetailData->InfFileName)
&& IsProviderMs(pspDriverInfoDetailData->InfFileName ) )
{
//
// This is inbox INF.
//
bInboxExists = TRUE;
} else { // if(IsWindowsFilw() && IsProviderMs())
//
// This is IHV INF.
//
bIhvExists = TRUE;
}
//
// Clean up.
//
delete[] pspDriverInfoDetailData;
pspDriverInfoDetailData = NULL;
} // for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData), Idx++)
IsIhvAndInboxExisting_return:
if( (TRUE == bInboxExists)
&& (TRUE == bIhvExists) )
{
bRet = TRUE;
} else { // if(bInboxExists && bIhvExists)
bRet = FALSE;
} // else // if(bInboxExists && bIhvExists)
DebugTrace(TRACE_PROC_LEAVE,("IsIhvAndInboxExisting: Leaving... Ret=0x%x\n", bRet));
return bRet;
} // IsProviderMs()
CInstallerMutex::CInstallerMutex(
HANDLE* phMutex,
LPTSTR szMutexName,
DWORD dwTimeout
)
{
m_bSucceeded = FALSE;
m_phMutex = phMutex;
_try {
*m_phMutex = CreateMutex(NULL, FALSE, szMutexName);
if(NULL != *m_phMutex){
//
// Wait until ownership is acquired.
//
switch(WaitForSingleObject(*m_phMutex, dwTimeout)){
case WAIT_ABANDONED:
DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Wait abandoned.\r\n"));
m_bSucceeded = TRUE;
break;
case WAIT_OBJECT_0:
DebugTrace(TRACE_STATUS, ("CInstallerMutex: Mutex acquired.\r\n"));
m_bSucceeded = TRUE;
break;
case WAIT_TIMEOUT:
DebugTrace(TRACE_WARNING, ("CInstallerMutex: WARNING!! Mutex acquisition timeout.\r\n"));
break;
default:
DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Unexpected error from WaitForSingleObjecct().\r\n"));
break;
} // switch(dwReturn)
} // if(NULL != *m_phMutex)
}
_except (EXCEPTION_EXECUTE_HANDLER) {
DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Unexpected exception.\r\n"));
}
} // CInstallerMutex::CInstallerMutex()
CInstallerMutex::~CInstallerMutex(
)
{
if (m_bSucceeded) {
ReleaseMutex(*m_phMutex);
DebugTrace(TRACE_STATUS, ("CInstallerMutex: Mutex released.\r\n"));
}
if(NULL != *m_phMutex){
CloseHandle(*m_phMutex);
} // if(NULL != *m_phMutex)
} // CInstallerMutex::~CInstallerMutex(
HFONT
GetIntroFont(
HWND hwnd
)
{
static HFONT _hfontIntro = NULL;
static int iDevCap = 0;
if ( !_hfontIntro ){
TCHAR szBuffer[64];
NONCLIENTMETRICS ncm = { 0 };
LOGFONT lf;
CString csSize;
HDC hDC = (HDC)NULL;
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
if(NULL != hDC){
iDevCap = GetDeviceCaps(hDC, LOGPIXELSY);
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
lf = ncm.lfMessageFont;
if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTNAME, lf.lfFaceName, (sizeof(lf.lfFaceName)/sizeof(TCHAR)))){
lf.lfWeight = FW_BOLD;
if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTSIZE, szBuffer, (sizeof(szBuffer)/sizeof(TCHAR)))){
csSize = szBuffer;
lf.lfHeight = 0 - (iDevCap * (DWORD)csSize.Decode() / 72);
_hfontIntro = CreateFontIndirect(&lf);
} // if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTSIZE, szBuffer, (sizeof(szBuffer)/sizeof(TCHAR))))
} // if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTNAME, lf.lfFaceName, (sizeof(lf.lfFaceName)/sizeof(TCHAR))))
DeleteDC(hDC);
} else { // if(NULL != hDC)
DebugTrace(TRACE_ERROR, ("GetIntroFont: ERROR!! Unable to create DC.Err=0x%x.\r\n",GetLastError()));
} // else(NULL != hDC)
}
return _hfontIntro;
} // GetIntroFont()
BOOL
IsDeviceRootEnumerated(
IN HDEVINFO hDevInfo,
IN PSP_DEVINFO_DATA pDevInfoData
)
{
CONFIGRET cmRetCode;
BOOL bRet;
ULONG ulStatus;
ULONG ulProblem;
DebugTrace(TRACE_PROC_ENTER,("IsDeviceRootEnumerated: Enter... \r\n"));
//
// Initialize local.
//
cmRetCode = CR_SUCCESS;
bRet = FALSE;
ulStatus = 0;
ulProblem = 0;
//
// Devnode Status.
//
cmRetCode = CM_Get_DevNode_Status(&ulStatus,
&ulProblem,
pDevInfoData->DevInst,
0);
if(CR_SUCCESS != cmRetCode){
//
// Unable to get devnode status.
//
DebugTrace(TRACE_ERROR,("IsDeviceRootEnumerated: ERROR!! Unable to get Devnode status. CR=0x%x.\r\n", cmRetCode));
bRet = FALSE;
goto IsDeviceRootEnumerated_return;
} // if(CD_SUCCESS != cmRetCode)
//
// See if it's root-enumerated.
//
if(DN_ROOT_ENUMERATED & ulStatus){
//
// This devnode is root-enumerated.
//
bRet = TRUE;
} // if(DN_ROOT_ENUMERATED & ulStatus)
IsDeviceRootEnumerated_return:
DebugTrace(TRACE_PROC_LEAVE,("IsDeviceRootEnumerated: Leaving... Ret=0x%x.\r\n", bRet));
return bRet;
} // IsDeviceRootEnumerated()
int
MyStrCmpi(
LPCTSTR str1,
LPCTSTR str2
)
{
int iRet;
//
// Initialize local.
//
iRet = 0;
//
// Compare string.
//
if(CSTR_EQUAL == CompareString(LOCALE_INVARIANT,
NORM_IGNORECASE,
str1,
-1,
str2,
-1) )
{
iRet = 0;
} else {
iRet = -1;
}
return iRet;
}