Leaked source code of windows server 2003
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.

985 lines
29 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. Module Name:
  4. CDriver.cpp
  5. Abstract:
  6. This module implements CDriver and CService classes
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "devmgr.h"
  12. #include "cdriver.h"
  13. const TCHAR* tszStringFileInfo = TEXT("StringFileInfo\\%04X%04X\\");
  14. const TCHAR* tszFileVersion = TEXT("FileVersion");
  15. const TCHAR* tszLegalCopyright = TEXT("LegalCopyright");
  16. const TCHAR* tszCompanyName = TEXT("CompanyName");
  17. const TCHAR* tszTranslation = TEXT("VarFileInfo\\Translation");
  18. const TCHAR* tszStringFileInfoDefault = TEXT("StringFileInfo\\040904B0\\");
  19. BOOL
  20. CDriver::Create(
  21. CDevice* pDevice
  22. )
  23. {
  24. HKEY hKey;
  25. TCHAR InfName[MAX_PATH];
  26. ASSERT(pDevice);
  27. m_pDevice = pDevice;
  28. m_OnLocalMachine = pDevice->m_pMachine->IsLocal();
  29. CMachine* pMachine = m_pDevice->m_pMachine;
  30. ASSERT(pMachine);
  31. //
  32. // We can't get the driver list on remote machines
  33. //
  34. if (!m_OnLocalMachine) {
  35. return TRUE;
  36. }
  37. m_hSDBDrvMain = SdbInitDatabase(SDB_DATABASE_MAIN_DRIVERS, NULL);
  38. //
  39. // Open drvice's driver registry key to get the InfPath
  40. //
  41. hKey = pMachine->DiOpenDevRegKey(*m_pDevice, DICS_FLAG_GLOBAL,
  42. 0, DIREG_DRV, KEY_READ);
  43. if (INVALID_HANDLE_VALUE != hKey) {
  44. DWORD regType;
  45. DWORD Len = sizeof(InfName);
  46. CSafeRegistry regDrv(hKey);
  47. //
  48. // Get the inf path from the driver key
  49. //
  50. if (regDrv.GetValue(REGSTR_VAL_INFPATH,
  51. &regType,
  52. (PBYTE)InfName,
  53. &Len)) {
  54. String strInfPath;
  55. if (strInfPath.GetSystemWindowsDirectory()) {
  56. //
  57. // Tack on an extra back slash if one is needed
  58. //
  59. if (_T('\\') != strInfPath[strInfPath.GetLength() - 1]) {
  60. strInfPath += (LPCTSTR)TEXT("\\");
  61. }
  62. strInfPath += (LPCTSTR)TEXT("INF\\");
  63. strInfPath += (LPCTSTR)InfName;
  64. pMachine->GetInfDigitalSigner((LPCTSTR)strInfPath, m_DigitalSigner);
  65. }
  66. }
  67. }
  68. return TRUE;
  69. }
  70. BOOL
  71. CDriver::BuildDriverList(
  72. BOOL bFunctionAndFiltersOnly
  73. )
  74. {
  75. SP_DRVINFO_DATA DrvInfoData;
  76. HSPFILEQ hFileQueue = INVALID_HANDLE_VALUE;
  77. SP_DEVINSTALL_PARAMS DevInstParams;
  78. //
  79. // If we already built up the list of driver files then we don't need
  80. // to do it again.
  81. //
  82. if (m_DriverListBuilt) {
  83. return m_listDriverFile.GetCount();
  84. }
  85. ASSERT(m_pDevice);
  86. if (!m_OnLocalMachine) {
  87. AddFunctionAndFilterDrivers(m_pDevice);
  88. return m_listDriverFile.GetCount();
  89. }
  90. CMachine* pMachine = m_pDevice->m_pMachine;
  91. ASSERT(pMachine);
  92. hFileQueue = SetupOpenFileQueue();
  93. //
  94. // Only build up the list of files from the INF if bFunctionAndFiltersOnly
  95. // is not TRUE.
  96. //
  97. if (!bFunctionAndFiltersOnly) {
  98. DevInstParams.cbSize = sizeof(DevInstParams);
  99. pMachine->DiGetDeviceInstallParams(*m_pDevice, &DevInstParams);
  100. //
  101. // Set the DI_FLAGSEX_INSTALLEDDRIVER flag before calling SetupDiBuildDriverInfoList.
  102. // This will have it only put the installed driver into the list.
  103. //
  104. DevInstParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER |
  105. DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
  106. if (pMachine->DiSetDeviceInstallParams(*m_pDevice,
  107. &DevInstParams) &&
  108. pMachine->DiBuildDriverInfoList(*m_pDevice,
  109. SPDIT_CLASSDRIVER)) {
  110. DrvInfoData.cbSize = sizeof(DrvInfoData);
  111. //
  112. // There should only be one driver in this list. If there isn't any
  113. // drivers in this list then there must not be a driver currently
  114. // installed on this device.
  115. //
  116. if (pMachine->DiEnumDriverInfo(*m_pDevice, SPDIT_CLASSDRIVER, 0, &DrvInfoData)) {
  117. //
  118. // Set this as the selected driver
  119. //
  120. if (pMachine->DiSetSelectedDriver(*m_pDevice, &DrvInfoData)) {
  121. //
  122. // Get a list of all the files installed for this device
  123. //
  124. if (INVALID_HANDLE_VALUE != hFileQueue) {
  125. DevInstParams.FileQueue = hFileQueue;
  126. DevInstParams.Flags |= DI_NOVCP;
  127. if (pMachine->DiSetDeviceInstallParams(*m_pDevice, &DevInstParams) &&
  128. pMachine->DiCallClassInstaller(DIF_INSTALLDEVICEFILES, *m_pDevice)) {
  129. //
  130. // Dereference the file queue so that we can close it
  131. //
  132. DevInstParams.FileQueue = NULL;
  133. DevInstParams.Flags &= ~DI_NOVCP;
  134. pMachine->DiSetDeviceInstallParams(*m_pDevice, &DevInstParams);
  135. }
  136. }
  137. }
  138. } else {
  139. //
  140. // We did not find a match...so just destroy it.
  141. //
  142. pMachine->DiDestroyDriverInfoList(*m_pDevice,
  143. SPDIT_CLASSDRIVER);
  144. }
  145. }
  146. }
  147. //
  148. // Add the funtion and device and class upper and lower filters, sometimes
  149. // these aren't added via the INF file directly so this makes sure they
  150. // show up in the list.
  151. //
  152. AddFunctionAndFilterDrivers(m_pDevice, hFileQueue);
  153. if (hFileQueue != INVALID_HANDLE_VALUE) {
  154. //
  155. // Scan the file queue.
  156. //
  157. DWORD ScanResult;
  158. SetupScanFileQueue(hFileQueue,
  159. SPQ_SCAN_USE_CALLBACK_SIGNERINFO,
  160. NULL,
  161. ScanQueueCallback,
  162. (PVOID)this,
  163. &ScanResult
  164. );
  165. //
  166. // Close the file queue
  167. //
  168. SetupCloseFileQueue(hFileQueue);
  169. }
  170. m_DriverListBuilt = TRUE;
  171. return m_listDriverFile.GetCount();
  172. }
  173. void
  174. CDriver::AddDriverFile(
  175. CDriverFile* pNewDrvFile
  176. )
  177. {
  178. //
  179. // Check to see if this driver already exists in the list.
  180. //
  181. POSITION pos = m_listDriverFile.GetHeadPosition();
  182. while (NULL != pos) {
  183. CDriverFile* pDrvFile = m_listDriverFile.GetNext(pos);
  184. if (lstrcmpi(pDrvFile->GetFullPathName(), pNewDrvFile->GetFullPathName()) == 0) {
  185. //
  186. // This file already exists in the list so just return without
  187. // adding it.
  188. //
  189. return;
  190. }
  191. }
  192. m_listDriverFile.AddTail(pNewDrvFile);
  193. }
  194. void
  195. CDriver::AddFunctionAndFilterDrivers(
  196. CDevice* pDevice,
  197. HSPFILEQ hFileQueue
  198. )
  199. {
  200. TCHAR ServiceName[MAX_PATH];
  201. ULONG BufferLen;
  202. HKEY hKey;
  203. DWORD regType;
  204. //
  205. // Get the function driver
  206. //
  207. if (pDevice->m_pMachine->DiGetDeviceRegistryProperty(*pDevice,
  208. SPDRP_SERVICE,
  209. NULL,
  210. (PBYTE)ServiceName,
  211. sizeof(ServiceName),
  212. NULL
  213. )) {
  214. CreateFromService(pDevice, ServiceName, hFileQueue);
  215. }
  216. //
  217. // Add the upper and lower device filters
  218. //
  219. for (int i = 0; i<2; i++) {
  220. BufferLen = 0;
  221. pDevice->m_pMachine->DiGetDeviceRegistryProperty(
  222. *pDevice,
  223. i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS,
  224. NULL,
  225. NULL,
  226. BufferLen,
  227. &BufferLen
  228. );
  229. if (BufferLen != 0) {
  230. PTSTR Buffer = new TCHAR[BufferLen+2];
  231. if (Buffer) {
  232. ZeroMemory(Buffer, BufferLen+2);
  233. if (pDevice->m_pMachine->DiGetDeviceRegistryProperty(
  234. *pDevice,
  235. i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS,
  236. NULL,
  237. (PBYTE)Buffer,
  238. BufferLen,
  239. &BufferLen
  240. )) {
  241. for (PTSTR SingleItem = Buffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) {
  242. CreateFromService(pDevice, SingleItem, hFileQueue);
  243. }
  244. }
  245. delete [] Buffer;
  246. }
  247. }
  248. }
  249. //
  250. // Add the upper and lower class filters
  251. //
  252. GUID ClassGuid;
  253. pDevice->ClassGuid(ClassGuid);
  254. hKey = m_pDevice->m_pMachine->DiOpenClassRegKey(&ClassGuid, KEY_READ, DIOCR_INSTALLER);
  255. if (INVALID_HANDLE_VALUE != hKey) {
  256. CSafeRegistry regClass(hKey);
  257. for (int i = 0; i<2; i++) {
  258. BufferLen = 0;
  259. regClass.GetValue(i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS,
  260. &regType,
  261. NULL,
  262. &BufferLen
  263. );
  264. if (BufferLen != 0) {
  265. PTSTR Buffer = new TCHAR[BufferLen+2];
  266. if (Buffer) {
  267. ZeroMemory(Buffer, BufferLen+2);
  268. if (regClass.GetValue(i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS,
  269. &regType,
  270. (PBYTE)Buffer,
  271. &BufferLen
  272. )) {
  273. for (PTSTR SingleItem = Buffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) {
  274. CreateFromService(pDevice, SingleItem, hFileQueue);
  275. }
  276. }
  277. delete [] Buffer;
  278. }
  279. }
  280. }
  281. }
  282. }
  283. void
  284. CDriver::CreateFromService(
  285. CDevice* pDevice,
  286. PCTSTR ServiceName,
  287. HSPFILEQ hFileQueue
  288. )
  289. {
  290. SC_HANDLE hscManager = NULL;
  291. SC_HANDLE hscService = NULL;
  292. if (!ServiceName) {
  293. return;
  294. }
  295. try
  296. {
  297. BOOL ComposePathNameFromServiceName = TRUE;
  298. hscManager = OpenSCManager(m_OnLocalMachine ? NULL : pDevice->m_pMachine->GetMachineFullName(),
  299. NULL, GENERIC_READ);
  300. if (NULL != hscManager)
  301. {
  302. hscService = OpenService(hscManager, ServiceName, GENERIC_READ);
  303. if (NULL != hscService)
  304. {
  305. DWORD BytesRequired;
  306. // first, probe for buffer size
  307. if (!QueryServiceConfig(hscService, NULL, 0, &BytesRequired) &&
  308. ERROR_INSUFFICIENT_BUFFER == GetLastError())
  309. {
  310. TCHAR FullPath[MAX_PATH];
  311. BufferPtr<BYTE> BufPtr(BytesRequired);
  312. LPQUERY_SERVICE_CONFIG pqsc;
  313. pqsc = (LPQUERY_SERVICE_CONFIG)(PBYTE)BufPtr;
  314. DWORD Size;
  315. if (QueryServiceConfig(hscService, pqsc, BytesRequired, &Size) &&
  316. pqsc->lpBinaryPathName &&
  317. (TEXT('\0') != pqsc->lpBinaryPathName[0]))
  318. {
  319. ComposePathNameFromServiceName = FALSE;
  320. //
  321. // Make sure we have a valid full path.
  322. //
  323. if (GetFullPathFromImagePath(pqsc->lpBinaryPathName,
  324. FullPath,
  325. ARRAYLEN(FullPath))) {
  326. if (hFileQueue != INVALID_HANDLE_VALUE) {
  327. //
  328. // Add the file to the queue.
  329. //
  330. TCHAR TargetPath[MAX_PATH];
  331. StringCchCopy(TargetPath, ARRAYLEN(TargetPath), FullPath);
  332. PTSTR p = (PTSTR)StrRChr(TargetPath, NULL, TEXT('\\'));
  333. if (p) {
  334. *p = TEXT('\0');
  335. }
  336. SetupQueueCopy(hFileQueue,
  337. NULL,
  338. NULL,
  339. pSetupGetFileTitle(FullPath),
  340. NULL,
  341. NULL,
  342. TargetPath,
  343. NULL,
  344. 0
  345. );
  346. } else {
  347. //
  348. // No file queue was passed in so just manually
  349. // add this to our list of driver files.
  350. //
  351. SafePtr<CDriverFile> DrvFilePtr;
  352. CDriverFile* pDrvFile = new CDriverFile();
  353. DrvFilePtr.Attach(pDrvFile);
  354. //
  355. // We will set the GetWin32Error to 0xFFFFFFFF which will
  356. // cause the UI to say 'not available' for the
  357. // signature.
  358. //
  359. if (pDrvFile->Create(FullPath,
  360. m_OnLocalMachine,
  361. 0xFFFFFFFF,
  362. NULL,
  363. m_hSDBDrvMain))
  364. {
  365. AddDriverFile(pDrvFile);
  366. DrvFilePtr.Detach();
  367. }
  368. }
  369. }
  370. }
  371. }
  372. CloseServiceHandle(hscService);
  373. hscService = NULL;
  374. }
  375. CloseServiceHandle(hscManager);
  376. hscManager = NULL;
  377. }
  378. if (ComposePathNameFromServiceName)
  379. {
  380. String strFullPathName;
  381. strFullPathName.GetSystemDirectory();
  382. strFullPathName += (LPCTSTR)TEXT("\\drivers\\");
  383. strFullPathName += (LPCTSTR)ServiceName;
  384. strFullPathName += (LPCTSTR)TEXT(".sys");
  385. if (hFileQueue != INVALID_HANDLE_VALUE) {
  386. //
  387. // Add the file to the queue.
  388. //
  389. String strTargetPath;
  390. strTargetPath = strFullPathName;
  391. PTSTR p = (PTSTR)StrRChr((LPCTSTR)strTargetPath, NULL, TEXT('\\'));
  392. if (p) {
  393. *p = TEXT('\0');
  394. }
  395. SetupQueueCopy(hFileQueue,
  396. NULL,
  397. NULL,
  398. pSetupGetFileTitle((LPCTSTR)strFullPathName),
  399. NULL,
  400. NULL,
  401. strTargetPath,
  402. NULL,
  403. 0
  404. );
  405. } else {
  406. //
  407. // No file queue was passed in so just manually
  408. // add this to our list of driver files.
  409. //
  410. SafePtr<CDriverFile> DrvFilePtr;
  411. CDriverFile* pDrvFile = new CDriverFile();
  412. DrvFilePtr.Attach(pDrvFile);
  413. //
  414. // We will set the GetWin32Error to 0xFFFFFFFF which will
  415. // cause the UI to say 'not available' for the
  416. // signature.
  417. //
  418. if (pDrvFile->Create((LPCTSTR)strFullPathName,
  419. m_OnLocalMachine,
  420. 0xFFFFFFFF,
  421. NULL,
  422. m_hSDBDrvMain))
  423. {
  424. AddDriverFile(pDrvFile);
  425. DrvFilePtr.Detach();
  426. }
  427. }
  428. }
  429. }
  430. catch (CMemoryException* e)
  431. {
  432. UNREFERENCED_PARAMETER(e);
  433. if (hscService)
  434. {
  435. CloseServiceHandle(hscService);
  436. }
  437. if (hscManager)
  438. {
  439. CloseServiceHandle(hscManager);
  440. }
  441. throw;
  442. }
  443. }
  444. CDriver::~CDriver()
  445. {
  446. if (!m_listDriverFile.IsEmpty())
  447. {
  448. POSITION pos = m_listDriverFile.GetHeadPosition();
  449. while (NULL != pos) {
  450. CDriverFile* pDrvFile = m_listDriverFile.GetNext(pos);
  451. delete pDrvFile;
  452. }
  453. m_listDriverFile.RemoveAll();
  454. }
  455. if (m_hSDBDrvMain) {
  456. SdbReleaseDatabase(m_hSDBDrvMain);
  457. }
  458. }
  459. //
  460. // Can not throw a exception from this function because it is a callback
  461. //
  462. UINT
  463. CDriver::ScanQueueCallback(
  464. PVOID Context,
  465. UINT Notification,
  466. UINT_PTR Param1,
  467. UINT_PTR Param2
  468. )
  469. {
  470. UNREFERENCED_PARAMETER(Param2);
  471. try
  472. {
  473. if (SPFILENOTIFY_QUEUESCAN_SIGNERINFO == Notification && Param1)
  474. {
  475. CDriver* pDriver = (CDriver*)Context;
  476. if (pDriver)
  477. {
  478. SafePtr<CDriverFile> DrvFilePtr;
  479. CDriverFile* pDrvFile = new CDriverFile();
  480. DrvFilePtr.Attach(pDrvFile);
  481. //
  482. // When creating the CDriver set the Win32Error to 0xFFFFFFFF
  483. // if the user is loged in as a guest. This is because we
  484. // cannot tell if a file is digitally signed if the user is
  485. // a guest. If the user is not a guest then use the Win32Error
  486. // returned from setupapi.
  487. //
  488. if (pDrvFile->Create((LPCTSTR)((PFILEPATHS_SIGNERINFO)Param1)->Target,
  489. pDriver->IsLocal(),
  490. pDriver->m_pDevice->m_pMachine->IsUserAGuest()
  491. ? 0xFFFFFFFF
  492. : ((PFILEPATHS_SIGNERINFO)Param1)->Win32Error,
  493. ((PFILEPATHS_SIGNERINFO)Param1)->DigitalSigner,
  494. pDriver->m_hSDBDrvMain
  495. ))
  496. {
  497. pDriver->AddDriverFile(pDrvFile);
  498. DrvFilePtr.Detach();
  499. }
  500. }
  501. }
  502. }
  503. catch (CMemoryException* e)
  504. {
  505. e->Delete();
  506. return ERROR_NOT_ENOUGH_MEMORY;
  507. }
  508. return NO_ERROR;
  509. }
  510. BOOL
  511. CDriver::GetFirstDriverFile(
  512. CDriverFile** ppDrvFile,
  513. PVOID& Context
  514. )
  515. {
  516. ASSERT(ppDrvFile);
  517. if (!m_listDriverFile.IsEmpty())
  518. {
  519. POSITION pos = m_listDriverFile.GetHeadPosition();
  520. *ppDrvFile = m_listDriverFile.GetNext(pos);
  521. Context = pos;
  522. return TRUE;
  523. }
  524. Context = NULL;
  525. *ppDrvFile = NULL;
  526. return FALSE;
  527. }
  528. BOOL
  529. CDriver::GetNextDriverFile(
  530. CDriverFile** ppDrvFile,
  531. PVOID& Context
  532. )
  533. {
  534. ASSERT(ppDrvFile);
  535. POSITION pos = (POSITION)Context;
  536. if (NULL != pos)
  537. {
  538. *ppDrvFile = m_listDriverFile.GetNext(pos);
  539. Context = pos;
  540. return TRUE;
  541. }
  542. *ppDrvFile = NULL;
  543. return FALSE;
  544. }
  545. void
  546. CDriver::GetDriverSignerString(
  547. String& strDriverSigner
  548. )
  549. {
  550. if (m_DigitalSigner.IsEmpty()) {
  551. strDriverSigner.LoadString(g_hInstance, IDS_NO_DIGITALSIGNATURE);
  552. } else {
  553. strDriverSigner = m_DigitalSigner;
  554. }
  555. }
  556. BOOL
  557. CDriver::GetFullPathFromImagePath(
  558. LPCTSTR ImagePath,
  559. LPTSTR FullPath,
  560. UINT FullPathLength
  561. )
  562. {
  563. TCHAR OriginalCurrentDirectory[MAX_PATH];
  564. LPTSTR pRelativeString;
  565. LPTSTR lpFilePart;
  566. if (!ImagePath || (ImagePath[0] == TEXT('\0'))) {
  567. return FALSE;
  568. }
  569. //
  570. // If we aren't on a local machine then just return the file name and not
  571. // the full path.
  572. //
  573. if (!m_OnLocalMachine) {
  574. if (SUCCEEDED(StringCchCopy(FullPath, FullPathLength, pSetupGetFileTitle(ImagePath)))) {
  575. return TRUE;
  576. } else {
  577. return FALSE;
  578. }
  579. }
  580. //
  581. // First check if the ImagePath happens to be a valid full path.
  582. //
  583. if (GetFileAttributes(ImagePath) != 0xFFFFFFFF) {
  584. ::GetFullPathName(ImagePath, FullPathLength, FullPath, &lpFilePart);
  585. return TRUE;
  586. }
  587. pRelativeString = (LPTSTR)ImagePath;
  588. //
  589. // If the ImagePath starts with "\SystemRoot" or "%SystemRoot%" then
  590. // remove those values.
  591. //
  592. if (StrCmpNI(ImagePath, TEXT("\\SystemRoot\\"), lstrlen(TEXT("\\SystemRoot\\"))) == 0) {
  593. pRelativeString += lstrlen(TEXT("\\SystemRoot\\"));
  594. } else if (StrCmpNI(ImagePath, TEXT("%SystemRoot%\\"), lstrlen(TEXT("%SystemRoot%\\"))) == 0) {
  595. pRelativeString += lstrlen(TEXT("%SystemRoot%\\"));
  596. }
  597. //
  598. // At this point pRelativeString should point to the image path relative to
  599. // the windows directory.
  600. //
  601. if (!GetSystemWindowsDirectory(FullPath, FullPathLength)) {
  602. return FALSE;
  603. }
  604. if (!GetCurrentDirectory(ARRAYLEN(OriginalCurrentDirectory), OriginalCurrentDirectory)) {
  605. OriginalCurrentDirectory[0] = TEXT('\0');
  606. }
  607. if (!SetCurrentDirectory(FullPath)) {
  608. return FALSE;
  609. }
  610. ::GetFullPathName(pRelativeString, FullPathLength, FullPath, &lpFilePart);
  611. if (OriginalCurrentDirectory[0] != TEXT('\0')) {
  612. SetCurrentDirectory(OriginalCurrentDirectory);
  613. }
  614. return TRUE;
  615. }
  616. BOOL
  617. CDriverFile::Create(
  618. LPCTSTR ServiceName,
  619. BOOL LocalMachine,
  620. DWORD Win32Error,
  621. LPCTSTR DigitalSigner,
  622. HSDB hSDBDrvMain
  623. )
  624. {
  625. if (!ServiceName || (TEXT('\0') == ServiceName[0]))
  626. {
  627. return FALSE;
  628. }
  629. m_Win32Error = Win32Error;
  630. if (DigitalSigner) {
  631. m_strDigitalSigner = DigitalSigner;
  632. }
  633. //
  634. // For remote machine, we can not verify if the driver file exits.
  635. // we only show the driver name.
  636. //
  637. if (LocalMachine) {
  638. m_Attributes = GetFileAttributes(ServiceName);
  639. if (0xFFFFFFFF != m_Attributes) {
  640. m_strFullPathName = ServiceName;
  641. } else {
  642. //
  643. // The driver is a service. Do not search for the current director --
  644. // GetFullPathName is useless here.
  645. // Search for Windows dir and System directory
  646. //
  647. String strBaseDir;
  648. if (strBaseDir.GetSystemWindowsDirectory()) {
  649. if (_T('\\') != strBaseDir[strBaseDir.GetLength() - 1]) {
  650. strBaseDir += (LPCTSTR)TEXT("\\");
  651. }
  652. strBaseDir += (LPCTSTR)pSetupGetFileTitle(ServiceName);
  653. m_Attributes = GetFileAttributes((LPCTSTR)strBaseDir);
  654. if (0xFFFFFFFF == m_Attributes)
  655. {
  656. if (strBaseDir.GetSystemDirectory()) {
  657. if (_T('\\') != strBaseDir[strBaseDir.GetLength() - 1]) {
  658. strBaseDir += (LPCTSTR)TEXT("\\");
  659. }
  660. strBaseDir += (LPCTSTR)pSetupGetFileTitle(ServiceName);
  661. m_Attributes = GetFileAttributes(strBaseDir);
  662. }
  663. }
  664. //
  665. // hopeless, we could find the path
  666. //
  667. if (0xFFFFFFFF == m_Attributes)
  668. {
  669. return FALSE;
  670. }
  671. m_strFullPathName = strBaseDir;
  672. } else {
  673. return FALSE;
  674. }
  675. }
  676. m_HasVersionInfo = GetVersionInfo();
  677. }
  678. else {
  679. m_strFullPathName = ServiceName;
  680. //
  681. //we do not have version info
  682. //
  683. m_HasVersionInfo = FALSE;
  684. }
  685. if (!m_strFullPathName.IsEmpty() && hSDBDrvMain != NULL) {
  686. TAGREF tagref = TAGREF_NULL;
  687. HAPPHELPINFOCONTEXT hAppHelpInfoContext = NULL;
  688. SDBENTRYINFO entryinfo;
  689. DWORD cbSize;
  690. tagref = SdbGetDatabaseMatch(hSDBDrvMain,
  691. (LPTSTR)m_strFullPathName,
  692. INVALID_HANDLE_VALUE,
  693. NULL,
  694. 0
  695. );
  696. if (tagref != TAGREF_NULL) {
  697. //
  698. // This driver is in the database.
  699. //
  700. m_IsDriverBlocked = TRUE;
  701. //
  702. // Call SdbReadDriverInformation to get the database GUID and the
  703. // driver GUID for this entry.
  704. //
  705. ZeroMemory(&entryinfo, sizeof(entryinfo));
  706. if (SdbReadDriverInformation(hSDBDrvMain,
  707. tagref,
  708. &entryinfo)) {
  709. //
  710. // Open up the App help information database and query for the
  711. // html link.
  712. //
  713. hAppHelpInfoContext = SdbOpenApphelpInformation(&(entryinfo.guidDB),
  714. &(entryinfo.guidID));
  715. if (hAppHelpInfoContext) {
  716. cbSize = 0;
  717. PBYTE pBuffer = NULL;
  718. cbSize = SdbQueryApphelpInformation(hAppHelpInfoContext,
  719. ApphelpHelpCenterURL,
  720. NULL,
  721. 0);
  722. if (cbSize &&
  723. ((pBuffer = new BYTE[cbSize]) != NULL)) {
  724. cbSize = SdbQueryApphelpInformation(hAppHelpInfoContext,
  725. ApphelpHelpCenterURL,
  726. (LPVOID)pBuffer,
  727. cbSize);
  728. if (cbSize) {
  729. m_strHtmlHelpID = (LPTSTR)pBuffer;
  730. }
  731. delete [] pBuffer;
  732. }
  733. SdbCloseApphelpInformation(hAppHelpInfoContext);
  734. }
  735. }
  736. }
  737. }
  738. return TRUE;
  739. }
  740. BOOL
  741. CDriverFile::GetVersionInfo()
  742. {
  743. DWORD Size, dwHandle;
  744. Size = GetFileVersionInfoSize((LPTSTR)(LPCTSTR)m_strFullPathName, &dwHandle);
  745. if (!Size)
  746. {
  747. return FALSE;
  748. }
  749. BufferPtr<BYTE> BufPtr(Size);
  750. PVOID pVerInfo = BufPtr;
  751. if (GetFileVersionInfo((LPTSTR)(LPCTSTR)m_strFullPathName, dwHandle, Size,
  752. pVerInfo))
  753. {
  754. // get VarFileInfo\Translation
  755. PVOID pBuffer;
  756. UINT Len;
  757. String strStringFileInfo;
  758. if (!VerQueryValue(pVerInfo, (LPTSTR)tszTranslation, &pBuffer, &Len))
  759. {
  760. strStringFileInfo = tszStringFileInfoDefault;
  761. }
  762. else
  763. {
  764. strStringFileInfo.Format(tszStringFileInfo, *((WORD*)pBuffer),
  765. *(((WORD*)pBuffer) + 1));
  766. }
  767. String str;
  768. str = strStringFileInfo + tszFileVersion;
  769. if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len))
  770. {
  771. m_strVersion = (LPTSTR)pBuffer;
  772. str = strStringFileInfo + tszLegalCopyright;
  773. if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len))
  774. {
  775. m_strCopyright = (LPTSTR)pBuffer;
  776. str = strStringFileInfo + tszCompanyName;
  777. if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len))
  778. {
  779. m_strProvider = (LPTSTR)pBuffer;
  780. }
  781. }
  782. }
  783. }
  784. return TRUE;
  785. }
  786. BOOL
  787. CDriverFile::operator ==(
  788. CDriverFile& OtherDrvFile
  789. )
  790. {
  791. return \
  792. m_HasVersionInfo == OtherDrvFile.HasVersionInfo() &&
  793. (GetFullPathName() == OtherDrvFile.GetFullPathName() ||
  794. (GetFullPathName() && OtherDrvFile.GetFullPathName() &&
  795. !lstrcmpi(GetFullPathName(), OtherDrvFile.GetFullPathName())
  796. )
  797. ) &&
  798. (GetProvider() == OtherDrvFile.GetProvider() ||
  799. (GetProvider() && OtherDrvFile.GetProvider() &&
  800. !lstrcmpi(GetProvider(), OtherDrvFile.GetProvider())
  801. )
  802. ) &&
  803. (GetCopyright() == OtherDrvFile.GetCopyright() ||
  804. (GetCopyright() && OtherDrvFile.GetCopyright() &&
  805. !lstrcmpi(GetCopyright(), OtherDrvFile.GetCopyright())
  806. )
  807. ) &&
  808. (GetVersion() == OtherDrvFile.GetVersion() ||
  809. (GetVersion() && OtherDrvFile.GetVersion() &&
  810. !lstrcmpi(GetVersion(), OtherDrvFile.GetVersion())
  811. )
  812. );
  813. }