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

  1. /******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2000
  4. *
  5. * TITLE: Util.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: KeisukeT
  10. *
  11. * DATE: 27 Mar, 2000
  12. *
  13. * DESCRIPTION:
  14. * Utility function for WIA class installer.
  15. *
  16. * NOTE:
  17. * All of string buffers dealt in these functions must have at least
  18. * MAX_DESCRIPTION size. Since it doesn't have size check of buffer, it assumes
  19. * all string size is unfer MAX_DESCRIPTION, which must be OK to be used only
  20. * for WIA class installer.
  21. *
  22. *******************************************************************************/
  23. //
  24. // Precompiled header
  25. //
  26. #include "precomp.h"
  27. #pragma hdrstop
  28. //
  29. // Include
  30. //
  31. #include "sti_ci.h"
  32. #include <regstr.h>
  33. #include <cfgmgr32.h>
  34. //
  35. // Extern
  36. //
  37. extern HINSTANCE g_hDllInstance;
  38. //
  39. // Function
  40. //
  41. BOOL
  42. GetInfInforamtionFromSelectedDevice(
  43. HDEVINFO hDevInfo,
  44. LPTSTR pInfFileName,
  45. LPTSTR pInfSectionName
  46. )
  47. {
  48. BOOL bRet;
  49. SP_DEVINFO_DATA DeviceInfoData;
  50. SP_DRVINFO_DATA DriverInfoData;
  51. SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
  52. HINF hInf;
  53. TCHAR szInfFileName[MAX_DESCRIPTION];
  54. TCHAR szInfSectionName[MAX_DESCRIPTION];
  55. DebugTrace(TRACE_PROC_ENTER,(("GetInfInforamtionFromSelectedDevice: Enter... \r\n")));
  56. hInf = INVALID_HANDLE_VALUE;
  57. bRet = FALSE;
  58. //
  59. // Check arguments.
  60. //
  61. if( (NULL == hDevInfo)
  62. || (NULL == pInfFileName)
  63. || (NULL == pInfSectionName) )
  64. {
  65. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! Invalid argument. \r\n")));
  66. bRet = FALSE;
  67. goto GetInfInforamtionFromSelectedDevice_return;
  68. }
  69. //
  70. // Initialize locals.
  71. //
  72. memset (&DeviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
  73. memset (&DriverInfoData, 0, sizeof(SP_DRVINFO_DATA));
  74. memset (&DriverInfoDetailData, 0, sizeof(SP_DRVINFO_DETAIL_DATA));
  75. memset (szInfFileName, 0, sizeof(szInfFileName));
  76. memset (szInfSectionName, 0, sizeof(szInfSectionName));
  77. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  78. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  79. DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  80. //
  81. // Get selected device element.
  82. //
  83. if (!SetupDiGetSelectedDevice (hDevInfo, &DeviceInfoData)) {
  84. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetSelectedDevice Failed. Err=0x%lX\r\n"), GetLastError()));
  85. bRet = FALSE;
  86. goto GetInfInforamtionFromSelectedDevice_return;
  87. }
  88. //
  89. // Get selected device driver information.
  90. //
  91. if (!SetupDiGetSelectedDriver(hDevInfo, &DeviceInfoData, &DriverInfoData)) {
  92. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetSelectedDriver Failed. Err=0x%lX\r\n"), GetLastError()));
  93. bRet = FALSE;
  94. goto GetInfInforamtionFromSelectedDevice_return;
  95. }
  96. //
  97. // Get detailed data of selected device driver.
  98. //
  99. if(!SetupDiGetDriverInfoDetail(hDevInfo,
  100. &DeviceInfoData,
  101. &DriverInfoData,
  102. &DriverInfoDetailData,
  103. sizeof(DriverInfoDetailData),
  104. NULL) )
  105. {
  106. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetDriverInfoDetail Failed.Er=0x%lX\r\n"),GetLastError()));
  107. bRet = FALSE;
  108. goto GetInfInforamtionFromSelectedDevice_return;
  109. }
  110. //
  111. // Copy INF filename.
  112. //
  113. _tcsncpy(szInfFileName, DriverInfoDetailData.InfFileName, sizeof(szInfFileName)/sizeof(TCHAR));
  114. //
  115. // Open INF file of selected driver.
  116. //
  117. hInf = SetupOpenInfFile(szInfFileName,
  118. NULL,
  119. INF_STYLE_WIN4,
  120. NULL);
  121. if (hInf == INVALID_HANDLE_VALUE) {
  122. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupOpenInfFile Failed.Er=0x%lX\r\n"),GetLastError()));
  123. bRet = FALSE;
  124. goto GetInfInforamtionFromSelectedDevice_return;
  125. }
  126. //
  127. // Get actual INF section name to be installed.
  128. //
  129. if (!SetupDiGetActualSectionToInstall(hInf,
  130. DriverInfoDetailData.SectionName,
  131. szInfSectionName,
  132. sizeof(szInfSectionName)/sizeof(TCHAR),
  133. NULL,
  134. NULL) )
  135. {
  136. DebugTrace(TRACE_ERROR,(("GetInfInforamtionFromSelectedDevice: ERROR!! SetupDiGetActualSectionToInstall Failed.Er=0x%lX\r\n"),GetLastError()));
  137. bRet = FALSE;
  138. goto GetInfInforamtionFromSelectedDevice_return;
  139. }
  140. //
  141. // Copy strings to given buffer.
  142. //
  143. _tcsncpy(pInfFileName, szInfFileName, sizeof(szInfFileName)/sizeof(TCHAR));
  144. _tcsncpy(pInfSectionName, szInfSectionName, sizeof(szInfSectionName)/sizeof(TCHAR));
  145. //
  146. // Operation succeeded.
  147. //
  148. bRet = TRUE;
  149. GetInfInforamtionFromSelectedDevice_return:
  150. if(INVALID_HANDLE_VALUE != hInf){
  151. SetupCloseInfFile(hInf);
  152. }
  153. DebugTrace(TRACE_PROC_LEAVE,(("GetInfInforamtionFromSelectedDevice: Leaving... Ret=0x%x\n"), bRet));
  154. return bRet;
  155. }
  156. BOOL
  157. GetStringFromRegistry(
  158. HKEY hkRegistry,
  159. LPCTSTR szValueName,
  160. LPTSTR pBuffer
  161. )
  162. {
  163. BOOL bRet;
  164. LONG lError;
  165. DWORD dwSize;
  166. DWORD dwType;
  167. TCHAR szString[MAX_DESCRIPTION];
  168. //
  169. // Initialize local.
  170. //
  171. bRet = FALSE;
  172. lError = ERROR_SUCCESS;
  173. dwSize = sizeof(szString);
  174. memset(szString, 0, sizeof(szString));
  175. //
  176. // Check arguments.
  177. //
  178. if( (NULL == hkRegistry)
  179. || (NULL == szValueName)
  180. || (NULL == pBuffer) )
  181. {
  182. DebugTrace(TRACE_ERROR,(("GetStringFromRegistry: ERROR!! Invalid argument\r\n")));
  183. bRet = FALSE;
  184. goto GetStringFromRegistry_return;
  185. }
  186. //
  187. // Get specified string from registry.
  188. //
  189. lError = RegQueryValueEx(hkRegistry,
  190. szValueName,
  191. NULL,
  192. &dwType,
  193. (LPBYTE)szString,
  194. &dwSize);
  195. if(ERROR_SUCCESS != lError){
  196. DebugTrace(TRACE_ERROR,(("GetStringFromRegistry: ERROR!! RegQueryValueEx failed. Err=0x%x.\r\n"), GetLastError()));
  197. bRet = FALSE;
  198. goto GetStringFromRegistry_return;
  199. }
  200. //
  201. // Make sure NULL termination.
  202. //
  203. szString[ARRAYSIZE(szString)-1] = TEXT('\0');
  204. //
  205. // Copy acquired string to given buffer. This function assume max-string/bufer size is MAX_DESCRIPTION.
  206. //
  207. _tcsncpy(pBuffer, szString, MAX_DESCRIPTION);
  208. //
  209. // Operation succeeded.
  210. //
  211. bRet = TRUE;
  212. GetStringFromRegistry_return:
  213. return bRet;
  214. }
  215. BOOL
  216. GetDwordFromRegistry(
  217. HKEY hkRegistry,
  218. LPCTSTR szValueName,
  219. LPDWORD pdwValue
  220. )
  221. {
  222. BOOL bRet;
  223. LONG lError;
  224. DWORD dwSize;
  225. DWORD dwType;
  226. DWORD dwValue;
  227. //
  228. // Initialize local.
  229. //
  230. bRet = FALSE;
  231. lError = ERROR_SUCCESS;
  232. dwSize = sizeof(dwValue);
  233. dwValue = 0;
  234. //
  235. // Check arguments.
  236. //
  237. if( (NULL == hkRegistry)
  238. || (NULL == szValueName)
  239. || (NULL == pdwValue) )
  240. {
  241. DebugTrace(TRACE_ERROR,(("GetDwordFromRegistry: ERROR!! Invalid argument\r\n")));
  242. bRet = FALSE;
  243. goto GetDwordFromRegistry_return;
  244. }
  245. //
  246. // Get specified string from registry.
  247. //
  248. lError = RegQueryValueEx(hkRegistry,
  249. szValueName,
  250. NULL,
  251. &dwType,
  252. (LPBYTE)&dwValue,
  253. &dwSize);
  254. if(ERROR_SUCCESS != lError){
  255. DebugTrace(TRACE_ERROR,(("GetDwordFromRegistry: ERROR!! RegQueryValueEx failed. Err=0x%x. Size=0x%x, Type=0x%x\r\n"), lError, dwSize, dwType));
  256. bRet = FALSE;
  257. goto GetDwordFromRegistry_return;
  258. }
  259. //
  260. // Copy acquired DWORD value to given buffer.
  261. //
  262. *pdwValue = dwValue;
  263. //
  264. // Operation succeeded.
  265. //
  266. bRet = TRUE;
  267. GetDwordFromRegistry_return:
  268. return bRet;
  269. } // GetDwordFromRegistry
  270. VOID
  271. SetRunonceKey(
  272. LPTSTR szValue,
  273. LPTSTR szData
  274. )
  275. {
  276. HKEY hkRun;
  277. LONG lResult;
  278. CString csData;
  279. //
  280. // Initialize local.
  281. //
  282. hkRun = NULL;
  283. lResult = ERROR_SUCCESS;
  284. csData = szData;
  285. //
  286. // Get RUNONCE regkey.
  287. //
  288. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  289. REGSTR_PATH_RUNONCE,
  290. 0,
  291. KEY_READ | KEY_WRITE,
  292. &hkRun);
  293. if(ERROR_SUCCESS == lResult){
  294. csData.Store(hkRun, szValue);
  295. RegCloseKey(hkRun);
  296. } // if(ERROR_SUCCESS == lResult)
  297. } // SetRunonceKey()
  298. VOID
  299. ShowInstallerMessage(
  300. DWORD dwMessageId
  301. )
  302. {
  303. CString csTitle;
  304. CString csText;
  305. csTitle.FromTable (MessageTitle);
  306. csText.FromTable ((unsigned)dwMessageId);
  307. if( !csTitle.IsEmpty() && !csText.IsEmpty()){
  308. MessageBox (GetActiveWindow(),
  309. csText,
  310. csTitle,
  311. MB_ICONINFORMATION | MB_OK);
  312. } // if(csTitle.IsEmpty() || csText.IsEmpty())
  313. } // ShowInstallerMessage()
  314. BOOL
  315. IsWindowsFile(
  316. LPTSTR szFileName
  317. )
  318. {
  319. BOOL bRet;
  320. DWORD dwNumberOfChar;
  321. TCHAR szLayoutInfpath[MAX_PATH+1];
  322. TCHAR szReturnBuffer[MAX_PATH];
  323. TCHAR *pszFileNameWithoutPath;
  324. DWORD Idx;
  325. DebugTrace(TRACE_PROC_ENTER,("IsWindowsFile: Enter... Checking %ws.\r\n", szFileName));
  326. //
  327. // Initialize local.
  328. //
  329. bRet = FALSE;
  330. dwNumberOfChar = 0;
  331. Idx = 0;
  332. pszFileNameWithoutPath = NULL;
  333. memset(szLayoutInfpath, 0, sizeof(szLayoutInfpath));
  334. //
  335. // Get INF filename without path.
  336. //
  337. while(TEXT('\0') != szFileName[Idx]){
  338. if(TEXT('\\') == szFileName[Idx]){
  339. pszFileNameWithoutPath = &(szFileName[Idx+1]);
  340. } // if('\\' == szFileName[Idx])
  341. Idx++;
  342. } // while('\0' != szFileName[Idx])
  343. //
  344. // Get system directory.
  345. //
  346. if(0 == GetWindowsDirectory(szLayoutInfpath, sizeof(szLayoutInfpath)/sizeof(TCHAR))){
  347. DebugTrace(TRACE_ERROR,("IsWindowsFile: ERROR!! GetWindowsDirectory failed. Err=0x%x.\r\n", GetLastError()));
  348. bRet = FALSE;
  349. goto IsWindowsFile_return;
  350. } // if(0 == GetWindowsDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(TCHAR)))
  351. //
  352. // Create fullpath of layout.inf.
  353. //
  354. lstrcat(szLayoutInfpath, LAYOUT_INF_PATH);
  355. DebugTrace(TRACE_STATUS,("IsWindowsFile: Looking for \'%ws\' in %ws.\r\n", pszFileNameWithoutPath, szLayoutInfpath));
  356. //
  357. // See if provided filename is in layout.inf.
  358. //
  359. dwNumberOfChar = GetPrivateProfileString(SOURCEDISKFILES,
  360. pszFileNameWithoutPath,
  361. NULL,
  362. szReturnBuffer,
  363. sizeof(szReturnBuffer) / sizeof(TCHAR),
  364. szLayoutInfpath);
  365. if(0 == dwNumberOfChar){
  366. //
  367. // Filename doesn't exist in layout.inf.
  368. //
  369. bRet = FALSE;
  370. goto IsWindowsFile_return;
  371. } // if(0 == dwNumberOfChar)
  372. //
  373. // This filename exists in layout.inf.
  374. //
  375. bRet = TRUE;
  376. IsWindowsFile_return:
  377. DebugTrace(TRACE_PROC_LEAVE,("IsWindowsFile: Leaving... Ret=0x%x\n", bRet));
  378. return bRet;
  379. } // IsWindowsFile()
  380. BOOL
  381. IsProviderMs(
  382. LPTSTR szInfName
  383. )
  384. {
  385. BOOL bRet;
  386. DWORD dwSize;
  387. TCHAR szProvider[MAX_PATH+1];
  388. PSP_INF_INFORMATION pspInfInfo;
  389. DebugTrace(TRACE_PROC_ENTER,("IsProviderMs: Enter... Checking %ws.\r\n", szInfName));
  390. //
  391. // Initialize local.
  392. //
  393. bRet = FALSE;
  394. dwSize = 0;
  395. pspInfInfo = NULL;
  396. memset(szProvider, 0, sizeof(szProvider));
  397. //
  398. // Get INF information size.
  399. //
  400. SetupGetInfInformation(szInfName,
  401. INFINFO_INF_NAME_IS_ABSOLUTE,
  402. NULL,
  403. 0,
  404. &dwSize);
  405. if(0 == dwSize){
  406. DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Enable to get required size for INF info. Err=0x%x.\r\n"), GetLastError()));
  407. bRet = FALSE;
  408. goto IsProviderMs_return;
  409. } // if(0 == dwSize)
  410. //
  411. // Allocate buffer for INF information.
  412. //
  413. pspInfInfo = (PSP_INF_INFORMATION) new char[dwSize];
  414. if(NULL == pspInfInfo){
  415. DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Insuffisient memory.\r\n")));
  416. bRet = FALSE;
  417. goto IsProviderMs_return;
  418. } // if(NULL == pspInfInfo)
  419. //
  420. // Get actual INF informaton.
  421. //
  422. if(!SetupGetInfInformation(szInfName,
  423. INFINFO_INF_NAME_IS_ABSOLUTE,
  424. pspInfInfo,
  425. dwSize,
  426. &dwSize))
  427. {
  428. DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! Unable to get Inf info. Err=0x%x.\r\n"), GetLastError()));
  429. bRet = FALSE;
  430. goto IsProviderMs_return;
  431. } // if(!SetupGetInflnformation()
  432. //
  433. // Query "Provider" of given INF.
  434. //
  435. if(!SetupQueryInfVersionInformation(pspInfInfo,
  436. 0,
  437. PROVIDER,
  438. szProvider,
  439. ARRAYSIZE(szProvider)-1,
  440. &dwSize))
  441. {
  442. DebugTrace(TRACE_ERROR,(("IsProviderMs: ERROR!! SetupQueryInfVersionInformation() failed. Err=0x%x.\r\n"), GetLastError()));
  443. bRet = FALSE;
  444. goto IsProviderMs_return;
  445. } // if(!SetupGetInflnformation()
  446. //
  447. // See if provider is "Microsoft"
  448. //
  449. DebugTrace(TRACE_STATUS,(("IsProviderMs: Provider = \'%ws\'.\r\n"), szProvider));
  450. if(0 == MyStrCmpi(szProvider, MICROSOFT)){
  451. //
  452. // This INF file has 'Provider = "Microsoft"'
  453. //
  454. bRet = TRUE;
  455. } // if(0 == lstrcmp(szProvider, MICROSOFT))
  456. IsProviderMs_return:
  457. if(NULL != pspInfInfo){
  458. delete[] pspInfInfo;
  459. } // if(NULL != pspInfInfo)
  460. DebugTrace(TRACE_PROC_LEAVE,("IsProviderMs: Leaving... Ret=0x%x\n", bRet));
  461. return bRet;
  462. } // IsProviderMs()
  463. BOOL
  464. IsIhvAndInboxExisting(
  465. HDEVINFO hDevInfo,
  466. PSP_DEVINFO_DATA pDevInfoData
  467. )
  468. {
  469. BOOL bRet;
  470. BOOL bIhvExists;
  471. BOOL bInboxExists;
  472. DWORD dwLastError;
  473. DWORD dwSize;
  474. DWORD Idx;
  475. SP_DRVINSTALL_PARAMS spDriverInstallParams;
  476. SP_DRVINFO_DATA spDriverInfoData;
  477. PSP_DRVINFO_DETAIL_DATA pspDriverInfoDetailData;
  478. //
  479. // Initialize local.
  480. //
  481. bRet = FALSE;
  482. bIhvExists = FALSE;
  483. bInboxExists = FALSE;
  484. dwSize = 0;
  485. Idx = 0;
  486. dwLastError = ERROR_SUCCESS;
  487. pspDriverInfoDetailData = NULL;
  488. memset(&spDriverInstallParams, 0, sizeof(spDriverInstallParams));
  489. //
  490. // Get driver info.
  491. //
  492. memset(&spDriverInfoData, 0, sizeof(spDriverInfoData));
  493. spDriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  494. for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData); Idx++){
  495. //
  496. // Get driver install params.
  497. //
  498. memset(&spDriverInstallParams, 0, sizeof(spDriverInstallParams));
  499. spDriverInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
  500. if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams)){
  501. DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInstallParams() failed LastError=0x%x.\r\n", GetLastError()));
  502. goto IsIhvAndInboxExisting_return;
  503. } // if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams))
  504. //
  505. // Get buffer size required for driver derail data.
  506. //
  507. dwSize = 0;
  508. SetupDiGetDriverInfoDetail(hDevInfo,
  509. pDevInfoData,
  510. &spDriverInfoData,
  511. NULL,
  512. 0,
  513. &dwSize);
  514. dwLastError = GetLastError();
  515. if(ERROR_INSUFFICIENT_BUFFER != dwLastError){
  516. DebugTrace(TRACE_ERROR,(("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() doesn't return required size.Er=0x%x\r\n"),dwLastError));
  517. goto IsIhvAndInboxExisting_return;
  518. } // if(ERROR_INSUFFICIENT_BUFFER != dwLastError)
  519. //
  520. // Allocate required size of buffer for driver detailed data.
  521. //
  522. pspDriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)new char[dwSize];
  523. if(NULL == pspDriverInfoDetailData){
  524. DebugTrace(TRACE_ERROR,(("IsIhvAndInboxExisting: ERROR!! Unable to allocate driver detailed info buffer.\r\n")));
  525. goto IsIhvAndInboxExisting_return;
  526. } // if(NULL == pspDriverInfoDetailData)
  527. //
  528. // Initialize allocated buffer.
  529. //
  530. memset(pspDriverInfoDetailData, 0, dwSize);
  531. pspDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  532. //
  533. // Get detailed data of selected device driver.
  534. //
  535. if(!SetupDiGetDriverInfoDetail(hDevInfo,
  536. pDevInfoData,
  537. &spDriverInfoData,
  538. pspDriverInfoDetailData,
  539. dwSize,
  540. NULL) )
  541. {
  542. DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() failed LastError=0x%x.\r\n", GetLastError()));
  543. delete[] pspDriverInfoDetailData;
  544. pspDriverInfoDetailData = NULL;
  545. continue;
  546. } // if(NULL == pspDriverInfoDetailData)
  547. //
  548. // See if INF filename is valid.
  549. //
  550. if(NULL == pspDriverInfoDetailData->InfFileName){
  551. DebugTrace(TRACE_ERROR,("IsIhvAndInboxExisting: ERROR!! SetupDiGetDriverInfoDetail() returned invalid INF name.\r\n"));
  552. delete[] pspDriverInfoDetailData;
  553. pspDriverInfoDetailData = NULL;
  554. continue;
  555. } // if(NULL == pspDriverInfoDetailData->InfFileName)
  556. //
  557. // If it's Inbox driver, lower the lank.
  558. //
  559. if( IsWindowsFile(pspDriverInfoDetailData->InfFileName)
  560. && IsProviderMs(pspDriverInfoDetailData->InfFileName ) )
  561. {
  562. //
  563. // This is inbox INF.
  564. //
  565. bInboxExists = TRUE;
  566. } else { // if(IsWindowsFilw() && IsProviderMs())
  567. //
  568. // This is IHV INF.
  569. //
  570. bIhvExists = TRUE;
  571. }
  572. //
  573. // Clean up.
  574. //
  575. delete[] pspDriverInfoDetailData;
  576. pspDriverInfoDetailData = NULL;
  577. } // for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData), Idx++)
  578. IsIhvAndInboxExisting_return:
  579. if( (TRUE == bInboxExists)
  580. && (TRUE == bIhvExists) )
  581. {
  582. bRet = TRUE;
  583. } else { // if(bInboxExists && bIhvExists)
  584. bRet = FALSE;
  585. } // else // if(bInboxExists && bIhvExists)
  586. DebugTrace(TRACE_PROC_LEAVE,("IsIhvAndInboxExisting: Leaving... Ret=0x%x\n", bRet));
  587. return bRet;
  588. } // IsProviderMs()
  589. CInstallerMutex::CInstallerMutex(
  590. HANDLE* phMutex,
  591. LPTSTR szMutexName,
  592. DWORD dwTimeout
  593. )
  594. {
  595. m_bSucceeded = FALSE;
  596. m_phMutex = phMutex;
  597. _try {
  598. *m_phMutex = CreateMutex(NULL, FALSE, szMutexName);
  599. if(NULL != *m_phMutex){
  600. //
  601. // Wait until ownership is acquired.
  602. //
  603. switch(WaitForSingleObject(*m_phMutex, dwTimeout)){
  604. case WAIT_ABANDONED:
  605. DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Wait abandoned.\r\n"));
  606. m_bSucceeded = TRUE;
  607. break;
  608. case WAIT_OBJECT_0:
  609. DebugTrace(TRACE_STATUS, ("CInstallerMutex: Mutex acquired.\r\n"));
  610. m_bSucceeded = TRUE;
  611. break;
  612. case WAIT_TIMEOUT:
  613. DebugTrace(TRACE_WARNING, ("CInstallerMutex: WARNING!! Mutex acquisition timeout.\r\n"));
  614. break;
  615. default:
  616. DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Unexpected error from WaitForSingleObjecct().\r\n"));
  617. break;
  618. } // switch(dwReturn)
  619. } // if(NULL != *m_phMutex)
  620. }
  621. _except (EXCEPTION_EXECUTE_HANDLER) {
  622. DebugTrace(TRACE_ERROR, ("CInstallerMutex: ERROR!! Unexpected exception.\r\n"));
  623. }
  624. } // CInstallerMutex::CInstallerMutex()
  625. CInstallerMutex::~CInstallerMutex(
  626. )
  627. {
  628. if (m_bSucceeded) {
  629. ReleaseMutex(*m_phMutex);
  630. DebugTrace(TRACE_STATUS, ("CInstallerMutex: Mutex released.\r\n"));
  631. }
  632. if(NULL != *m_phMutex){
  633. CloseHandle(*m_phMutex);
  634. } // if(NULL != *m_phMutex)
  635. } // CInstallerMutex::~CInstallerMutex(
  636. HFONT
  637. GetIntroFont(
  638. HWND hwnd
  639. )
  640. {
  641. static HFONT _hfontIntro = NULL;
  642. static int iDevCap = 0;
  643. if ( !_hfontIntro ){
  644. TCHAR szBuffer[64];
  645. NONCLIENTMETRICS ncm = { 0 };
  646. LOGFONT lf;
  647. CString csSize;
  648. HDC hDC = (HDC)NULL;
  649. hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  650. if(NULL != hDC){
  651. iDevCap = GetDeviceCaps(hDC, LOGPIXELSY);
  652. ncm.cbSize = sizeof(ncm);
  653. SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  654. lf = ncm.lfMessageFont;
  655. if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTNAME, lf.lfFaceName, (sizeof(lf.lfFaceName)/sizeof(TCHAR)))){
  656. lf.lfWeight = FW_BOLD;
  657. if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTSIZE, szBuffer, (sizeof(szBuffer)/sizeof(TCHAR)))){
  658. csSize = szBuffer;
  659. lf.lfHeight = 0 - (iDevCap * (DWORD)csSize.Decode() / 72);
  660. _hfontIntro = CreateFontIndirect(&lf);
  661. } // if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTSIZE, szBuffer, (sizeof(szBuffer)/sizeof(TCHAR))))
  662. } // if(0 != LoadString(g_hDllInstance, IDS_TITLEFONTNAME, lf.lfFaceName, (sizeof(lf.lfFaceName)/sizeof(TCHAR))))
  663. DeleteDC(hDC);
  664. } else { // if(NULL != hDC)
  665. DebugTrace(TRACE_ERROR, ("GetIntroFont: ERROR!! Unable to create DC.Err=0x%x.\r\n",GetLastError()));
  666. } // else(NULL != hDC)
  667. }
  668. return _hfontIntro;
  669. } // GetIntroFont()
  670. BOOL
  671. IsDeviceRootEnumerated(
  672. IN HDEVINFO hDevInfo,
  673. IN PSP_DEVINFO_DATA pDevInfoData
  674. )
  675. {
  676. CONFIGRET cmRetCode;
  677. BOOL bRet;
  678. ULONG ulStatus;
  679. ULONG ulProblem;
  680. DebugTrace(TRACE_PROC_ENTER,("IsDeviceRootEnumerated: Enter... \r\n"));
  681. //
  682. // Initialize local.
  683. //
  684. cmRetCode = CR_SUCCESS;
  685. bRet = FALSE;
  686. ulStatus = 0;
  687. ulProblem = 0;
  688. //
  689. // Devnode Status.
  690. //
  691. cmRetCode = CM_Get_DevNode_Status(&ulStatus,
  692. &ulProblem,
  693. pDevInfoData->DevInst,
  694. 0);
  695. if(CR_SUCCESS != cmRetCode){
  696. //
  697. // Unable to get devnode status.
  698. //
  699. DebugTrace(TRACE_ERROR,("IsDeviceRootEnumerated: ERROR!! Unable to get Devnode status. CR=0x%x.\r\n", cmRetCode));
  700. bRet = FALSE;
  701. goto IsDeviceRootEnumerated_return;
  702. } // if(CD_SUCCESS != cmRetCode)
  703. //
  704. // See if it's root-enumerated.
  705. //
  706. if(DN_ROOT_ENUMERATED & ulStatus){
  707. //
  708. // This devnode is root-enumerated.
  709. //
  710. bRet = TRUE;
  711. } // if(DN_ROOT_ENUMERATED & ulStatus)
  712. IsDeviceRootEnumerated_return:
  713. DebugTrace(TRACE_PROC_LEAVE,("IsDeviceRootEnumerated: Leaving... Ret=0x%x.\r\n", bRet));
  714. return bRet;
  715. } // IsDeviceRootEnumerated()
  716. int
  717. MyStrCmpi(
  718. LPCTSTR str1,
  719. LPCTSTR str2
  720. )
  721. {
  722. int iRet;
  723. //
  724. // Initialize local.
  725. //
  726. iRet = 0;
  727. //
  728. // Compare string.
  729. //
  730. if(CSTR_EQUAL == CompareString(LOCALE_INVARIANT,
  731. NORM_IGNORECASE,
  732. str1,
  733. -1,
  734. str2,
  735. -1) )
  736. {
  737. iRet = 0;
  738. } else {
  739. iRet = -1;
  740. }
  741. return iRet;
  742. }