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.

3940 lines
118 KiB

  1. /******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2000
  4. *
  5. * TITLE: Device.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: KeisukeT
  10. *
  11. * DATE: 27 Mar, 2000
  12. *
  13. * DESCRIPTION:
  14. * Device class for WIA class installer.
  15. *
  16. *
  17. *******************************************************************************/
  18. //
  19. // Precompiled header
  20. //
  21. #include "precomp.h"
  22. #pragma hdrstop
  23. #define INITGUID
  24. #include "device.h"
  25. #include "sti.h"
  26. #include "stiregi.h"
  27. #include <stisvc.h>
  28. #include <devguid.h>
  29. #include <regstr.h>
  30. #include <icm.h>
  31. #include <ks.h>
  32. #include <aclapi.h>
  33. #include <sddl.h>
  34. //
  35. // Parsinc character used to separate field type from value in registry data section
  36. //
  37. #define FIELD_DELIMETER TEXT(',')
  38. BOOL
  39. CDevice::CollectNames(
  40. VOID
  41. )
  42. {
  43. BOOL bRet;
  44. HANDLE hDevInfo;
  45. GUID Guid;
  46. DWORD dwRequired;
  47. DWORD Idx;
  48. SP_DEVINFO_DATA spDevInfoData;
  49. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  50. TCHAR szTempBuffer[MAX_DESCRIPTION];
  51. HKEY hKeyInterface;
  52. HKEY hKeyDevice;
  53. DebugTrace(TRACE_PROC_ENTER,(("CDevice::CollectNames: Enter...\r\n")));
  54. //
  55. // Initialize local.
  56. //
  57. bRet = FALSE;
  58. hDevInfo = INVALID_HANDLE_VALUE;
  59. Guid = GUID_DEVCLASS_IMAGE;
  60. dwRequired = 0;
  61. Idx = 0;
  62. hKeyInterface = (HKEY)INVALID_HANDLE_VALUE;
  63. hKeyDevice = (HKEY)INVALID_HANDLE_VALUE;
  64. memset(szTempBuffer, 0, sizeof(szTempBuffer));
  65. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  66. memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
  67. //
  68. // Reset device name/ID array.
  69. //
  70. m_csaAllNames.Cleanup();
  71. m_csaAllId.Cleanup();
  72. //
  73. // Get all of installed WIA "devnode" device info set.
  74. //
  75. hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE);
  76. if (hDevInfo == INVALID_HANDLE_VALUE) {
  77. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! SetupDiGetClassDevs (devnodes) fails. Err=0x%x\n"), GetLastError()));
  78. bRet = FALSE;
  79. goto CollectNames_return;
  80. }
  81. //
  82. // Enum WIA devnode device friendly name and add them to array.
  83. //
  84. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Looking for DevNodes.\r\n")));
  85. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  86. for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
  87. //
  88. // Open device registry key.
  89. //
  90. hKeyDevice = SetupDiOpenDevRegKey(hDevInfo,
  91. &spDevInfoData,
  92. DICS_FLAG_GLOBAL,
  93. 0,
  94. DIREG_DRV,
  95. KEY_READ);
  96. if (INVALID_HANDLE_VALUE != hKeyDevice) {
  97. //
  98. // Get FriendlyName.
  99. //
  100. dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0')));
  101. if (RegQueryValueEx(hKeyDevice,
  102. REGSTR_VAL_FRIENDLY_NAME,
  103. NULL,
  104. NULL,
  105. (LPBYTE)szTempBuffer,
  106. &dwRequired) == ERROR_SUCCESS)
  107. {
  108. //
  109. // FriendlyName is found in this device regisgry. Add to the list if valid.
  110. //
  111. if(0 != lstrlen(szTempBuffer)) {
  112. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device name.\r\n"), szTempBuffer));
  113. m_csaAllNames.Add((LPCTSTR)szTempBuffer);
  114. } else { // if(0 != lstrlen(szTempBuffer))
  115. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid FriendleName (length=0).\r\n")));
  116. } // if(0 != lstrlen(szTempBuffer))
  117. } else { // if (RegQueryValueEx()
  118. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get FriendlyName. Err=0x%x\r\n"), GetLastError()));
  119. } // if (RegQueryValueEx()
  120. //
  121. // Get DeviceID.
  122. //
  123. dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0')));
  124. if (RegQueryValueEx(hKeyDevice,
  125. REGSTR_VAL_DEVICE_ID,
  126. NULL,
  127. NULL,
  128. (LPBYTE)szTempBuffer,
  129. &dwRequired) == ERROR_SUCCESS)
  130. {
  131. //
  132. // DeviceID is found in this device regisgry. Add to the list if valid.
  133. //
  134. if(0 != lstrlen(szTempBuffer)) {
  135. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device ID.\r\n"), szTempBuffer));
  136. m_csaAllId.Add((LPCTSTR)szTempBuffer);
  137. } else { // if(0 != lstrlen(szTempBuffer))
  138. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid DeviceID (length=0).\r\n")));
  139. } // if(0 != lstrlen(szTempBuffer))
  140. } else { // if (RegQueryValueEx()
  141. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get DeviceID. Err=0x%x\r\n"), GetLastError()));
  142. } // if (RegQueryValueEx()
  143. //
  144. // Close regkey and continue.
  145. //
  146. RegCloseKey(hKeyDevice);
  147. hKeyInterface = (HKEY)INVALID_HANDLE_VALUE;
  148. szTempBuffer[0] = TEXT('\0');
  149. } else { // if (hKeyDevice != INVALID_HANDLE_VALUE)
  150. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Unable to open Device(%d) RegKey. Err=0x%x\r\n"), Idx, GetLastError()));
  151. } // if (hKeyDevice != INVALID_HANDLE_VALUE)
  152. } // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
  153. //
  154. // Free "devnode" device info set.
  155. //
  156. SetupDiDestroyDeviceInfoList(hDevInfo);
  157. hDevInfo = INVALID_HANDLE_VALUE;
  158. //
  159. // Enum WIA interface-only device friendly name and add them to array.
  160. //
  161. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Looking for Interfaces.\r\n")));
  162. hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PROFILE);
  163. if (hDevInfo == INVALID_HANDLE_VALUE) {
  164. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! SetupDiGetClassDevs (inferfase) fails. Err=0x%x\n"), GetLastError()));
  165. bRet = FALSE;
  166. goto CollectNames_return;
  167. }
  168. spDevInterfaceData.cbSize = sizeof (spDevInterfaceData);
  169. for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
  170. hKeyInterface = SetupDiOpenDeviceInterfaceRegKey(hDevInfo,
  171. &spDevInterfaceData,
  172. 0,
  173. KEY_READ);
  174. if (hKeyInterface != INVALID_HANDLE_VALUE) {
  175. //
  176. // Get FriendlyName.
  177. //
  178. dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0')));
  179. if (RegQueryValueEx(hKeyInterface,
  180. REGSTR_VAL_FRIENDLY_NAME,
  181. NULL,
  182. NULL,
  183. (LPBYTE)szTempBuffer,
  184. &dwRequired) == ERROR_SUCCESS)
  185. {
  186. //
  187. // FriendlyName is found in this interface. Add to the list if valid.
  188. //
  189. if(0 != lstrlen(szTempBuffer)) {
  190. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device name (interface).\r\n"), szTempBuffer));
  191. m_csaAllNames.Add((LPCTSTR)szTempBuffer);
  192. } else { // if(0 != lstrlen(szTempBuffer))
  193. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid FriendleName (length=0).\r\n")));
  194. } // if(0 != lstrlen(szTempBuffer))
  195. } else { // if (RegQueryValueEx()
  196. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get FriendlyName. Err=0x%x\r\n"), GetLastError()));
  197. } // if (RegQueryValueEx()
  198. //
  199. // Get DeviceID.
  200. //
  201. dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0')));
  202. if (RegQueryValueEx(hKeyInterface,
  203. REGSTR_VAL_DEVICE_ID,
  204. NULL,
  205. NULL,
  206. (LPBYTE)szTempBuffer,
  207. &dwRequired) == ERROR_SUCCESS)
  208. {
  209. //
  210. // DeviceID is found in this interface. Add to the list if valid.
  211. //
  212. if(0 != lstrlen(szTempBuffer)) {
  213. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device ID (interface).\r\n"), szTempBuffer));
  214. m_csaAllId.Add((LPCTSTR)szTempBuffer);
  215. } else { // if(0 != lstrlen(szTempBuffer))
  216. DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid DeviceID (length=0).\r\n")));
  217. } // if(0 != lstrlen(szTempBuffer))
  218. } else { // if (RegQueryValueEx()
  219. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get DeviceID. Err=0x%x\r\n"), GetLastError()));
  220. } // if (RegQueryValueEx()
  221. //
  222. // Close registry key and continue.
  223. //
  224. RegCloseKey(hKeyInterface);
  225. hKeyInterface = (HKEY)INVALID_HANDLE_VALUE;
  226. szTempBuffer[0] = TEXT('\0');
  227. } else { // if (hKeyInterface != INVALID_HANDLE_VALUE)
  228. DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Unable to open Interface(%d) RegKey. Err=0x%x\r\n"), Idx, GetLastError()));
  229. } // if (hKeyInterface != INVALID_HANDLE_VALUE)
  230. } // for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++)
  231. //
  232. // Operation succeeded.
  233. //
  234. bRet = TRUE;
  235. CollectNames_return:
  236. //
  237. // Clean up.
  238. //
  239. if(INVALID_HANDLE_VALUE != hDevInfo){
  240. SetupDiDestroyDeviceInfoList(hDevInfo);
  241. }
  242. if(INVALID_HANDLE_VALUE != hKeyInterface){
  243. RegCloseKey(hKeyInterface);
  244. }
  245. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::CollectNames: Leaving... Ret=0x%x\n"), bRet));
  246. return bRet;
  247. } // CDevice::CollectNames()
  248. // For a device w/ devnode.
  249. CDevice::CDevice(
  250. HDEVINFO hDevInfo,
  251. PSP_DEVINFO_DATA pspDevInfoData,
  252. BOOL bIsPnP
  253. )
  254. {
  255. HKEY hkDevice;
  256. //
  257. // Initizlize local.
  258. //
  259. hkDevice = (HKEY)INVALID_HANDLE_VALUE;
  260. //
  261. // Initialize member.
  262. //
  263. m_hMutex = (HANDLE)NULL;
  264. m_hDevInfo = hDevInfo;
  265. m_pspDevInfoData = pspDevInfoData;
  266. m_bIsPnP = bIsPnP;
  267. m_bDefaultDevice = FALSE;
  268. m_bVideoDevice = FALSE;
  269. m_bInfProceeded = FALSE;
  270. m_bInterfaceOnly = FALSE;
  271. m_bIsMigration = FALSE;
  272. m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
  273. m_dwCapabilities = 0;
  274. m_dwInterfaceIndex = INVALID_DEVICE_INDEX;
  275. m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL;
  276. m_pExtraDeviceData = NULL;
  277. m_csFriendlyName.Empty();
  278. m_csInf.Empty();
  279. m_csInstallSection.Empty();
  280. m_csDriverDescription.Empty();
  281. m_csPort.Empty();
  282. m_csDeviceID.Empty();
  283. //
  284. // In case of upgrade, use original FriendlyName.
  285. //
  286. hkDevice = SetupDiOpenDevRegKey(m_hDevInfo,
  287. m_pspDevInfoData,
  288. DICS_FLAG_GLOBAL,
  289. 0,
  290. DIREG_DRV,
  291. KEY_READ);
  292. if(INVALID_HANDLE_VALUE != hkDevice){
  293. //
  294. // Device registry found. Read its FriendlyName.
  295. //
  296. m_csDriverDescription.Load(hkDevice, FRIENDLYNAME);
  297. m_csDeviceID.Load(hkDevice, REGSTR_VAL_DEVICE_ID);
  298. m_csFriendlyName.Load(hkDevice, FRIENDLYNAME);
  299. RegCloseKey(hkDevice);
  300. hkDevice = (HKEY)INVALID_HANDLE_VALUE;
  301. } // if(INVALID_HANDLE_VALUE != hkDevice)
  302. //
  303. // Get the number of installed devices.
  304. //
  305. GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
  306. } // CDevice::CDevice()
  307. // For a interface-only device.
  308. CDevice::CDevice(
  309. HDEVINFO hDevInfo,
  310. DWORD dwDeviceIndex
  311. )
  312. {
  313. //
  314. // Initialize member.
  315. //
  316. m_hMutex = (HANDLE)NULL;
  317. m_hDevInfo = hDevInfo;
  318. m_pspDevInfoData = NULL;
  319. m_bIsPnP = FALSE;
  320. m_bDefaultDevice = FALSE;
  321. m_bVideoDevice = FALSE;
  322. m_bInfProceeded = FALSE;
  323. m_bInterfaceOnly = TRUE;
  324. m_bIsMigration = FALSE;
  325. m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
  326. m_dwCapabilities = 0;
  327. m_dwInterfaceIndex = dwDeviceIndex;
  328. m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL;
  329. m_pExtraDeviceData = NULL;
  330. m_csFriendlyName.Empty();
  331. m_csInf.Empty();
  332. m_csInstallSection.Empty();
  333. m_csDriverDescription.Empty();
  334. m_csPort.Empty();
  335. m_csDeviceID.Empty();
  336. //
  337. // Get the number of installed devices.
  338. //
  339. GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
  340. } // CDevice::CDevice()
  341. // For a interface-only device.
  342. CDevice::CDevice(
  343. PDEVICE_INFO pMigratingDevice
  344. )
  345. {
  346. TCHAR StringBuffer[MAX_PATH+1];
  347. TCHAR WindowsDir[MAX_PATH+1];
  348. //
  349. // Initialize local.
  350. //
  351. memset(StringBuffer, 0, sizeof(StringBuffer));
  352. memset(WindowsDir, 0, sizeof(WindowsDir));
  353. //
  354. // Initialize member.
  355. //
  356. m_hMutex = (HANDLE)NULL;
  357. m_hDevInfo = NULL;
  358. m_pspDevInfoData = NULL;
  359. m_bIsPnP = FALSE;
  360. m_bDefaultDevice = FALSE;
  361. m_bVideoDevice = FALSE;
  362. m_bInfProceeded = FALSE;
  363. m_bInterfaceOnly = TRUE;
  364. m_bIsMigration = TRUE;
  365. m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
  366. m_dwCapabilities = 0;
  367. m_dwInterfaceIndex = INVALID_DEVICE_INDEX;
  368. m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL;
  369. //
  370. // Copy migration data.
  371. //
  372. AtoT(StringBuffer, pMigratingDevice->pszInfPath);
  373. m_csInf = StringBuffer;
  374. if(0 != GetWindowsDirectory(WindowsDir, MAX_PATH)){
  375. _sntprintf(StringBuffer, ARRAYSIZE(StringBuffer)-1, TEXT("%ws\\inf\\%ws"), WindowsDir, (LPTSTR)m_csInf);
  376. m_csInf = StringBuffer;
  377. } // if(0 != GetWindowsDirectory(WindowsDir, MAX_PATH))
  378. AtoT(StringBuffer, pMigratingDevice->pszInfSection);
  379. m_csInstallSection = StringBuffer;
  380. AtoT(StringBuffer, pMigratingDevice->pszFriendlyName);
  381. m_csDriverDescription = StringBuffer;
  382. AtoT(StringBuffer, pMigratingDevice->pszFriendlyName);
  383. m_csFriendlyName = StringBuffer;
  384. AtoT(StringBuffer, pMigratingDevice->pszCreateFileName);
  385. m_csPort = StringBuffer;
  386. m_pExtraDeviceData = pMigratingDevice->pDeviceDataParam;
  387. m_csDeviceID.Empty();
  388. //
  389. // Get the number of installed devices.
  390. //
  391. GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
  392. } // CDevice::CDevice()
  393. CDevice::~CDevice(
  394. )
  395. {
  396. HKEY hkNameStore;
  397. if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){
  398. //
  399. // Delete FriendlyName and DeviceId in name store.
  400. //
  401. RegDeleteKey(hkNameStore, m_csFriendlyName);
  402. RegDeleteKey(hkNameStore, m_csDeviceID);
  403. RegCloseKey(hkNameStore);
  404. } // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
  405. //
  406. // Make sure Mutex is released.
  407. //
  408. ReleaseInstallerMutex();
  409. } // CDevice::~CDevice()
  410. BOOL
  411. CDevice::IsSameDevice(
  412. HDEVINFO hDevInfo,
  413. PSP_DEVINFO_DATA pspDevInfoSet
  414. )
  415. {
  416. BOOL bRet;
  417. SP_DRVINFO_DATA spDrvInfoData;
  418. DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsSameDevice: Enter...\r\n")));
  419. //
  420. // Initialize local.
  421. //
  422. bRet = FALSE;
  423. memset(&spDrvInfoData, 0, sizeof(spDrvInfoData));
  424. //
  425. // Get default FriendlyName. It's used to check if it's same device or not.
  426. //
  427. spDrvInfoData.cbSize = sizeof (SP_DRVINFO_DATA);
  428. if (!SetupDiGetSelectedDriver (hDevInfo, pspDevInfoSet, &spDrvInfoData)){
  429. bRet = FALSE;
  430. goto IsSameDevice_return;
  431. } // if (SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDevInfoData))
  432. //
  433. // See if it has same description of current device. (TRUE=same)
  434. //
  435. bRet = (0 == lstrcmp((LPCTSTR)spDrvInfoData.Description, (LPCTSTR)m_csPdoDescription));
  436. IsSameDevice_return:
  437. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsSameDevice: Leaving... Ret=0x%x\n"), bRet));
  438. return bRet;
  439. } // CDevice::IsSameDevice()
  440. BOOL
  441. CDevice::IsFriendlyNameUnique(
  442. LPTSTR szFriendlyName
  443. )
  444. //
  445. // Note:
  446. // Before calling this function, caller has to make sure mutex is acquired.
  447. //
  448. {
  449. BOOL bRet;
  450. DWORD Idx;
  451. DWORD dwNumberOfName;
  452. DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsFriendlyNameUnique: Enter... \r\n")));
  453. //
  454. // Initialize local.
  455. //
  456. bRet = FALSE;
  457. Idx = 0;
  458. dwNumberOfName = m_csaAllNames.Count();
  459. //
  460. // If given name is same as generated one, it's unique.
  461. //
  462. if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName))){
  463. bRet = TRUE;
  464. goto IsFriendlyNameUnique_return;
  465. } // if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName)))
  466. //
  467. // Check any existing name matches given name.
  468. //
  469. for (Idx = 0; Idx < dwNumberOfName; Idx++) {
  470. DebugTrace(TRACE_STATUS,(("CDevice::IsFriendlyNameUnique: Name compare %ws and %ws.\r\n"),m_csaAllNames[Idx], szFriendlyName));
  471. if (0 == lstrcmpi(m_csaAllNames[Idx], szFriendlyName)){
  472. bRet = FALSE;
  473. goto IsFriendlyNameUnique_return;
  474. }
  475. } // for (Idx = 0; Idx < dwNumberOfName; Idx)
  476. //
  477. // Look in name store.
  478. //
  479. if(IsNameAlreadyStored(szFriendlyName)){
  480. bRet = FALSE;
  481. goto IsFriendlyNameUnique_return;
  482. } // if(IsNameAlreadyStored(szFriendlyName))
  483. //
  484. // This device name is unique.
  485. //
  486. bRet = TRUE;
  487. IsFriendlyNameUnique_return:
  488. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsFriendlyNameUnique: Leaving... Ret=0x%x\n"), bRet));
  489. return bRet;
  490. } // CDevice::IsFriendlyNameUnique()
  491. BOOL
  492. CDevice::IsDeviceIdUnique(
  493. LPTSTR szDeviceId
  494. )
  495. {
  496. BOOL bRet;
  497. DWORD Idx;
  498. DWORD dwNumberOfId;
  499. DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsDeviceIdUnique: Enter... \r\n")));
  500. //
  501. // Initialize local.
  502. //
  503. bRet = FALSE;
  504. Idx = 0;
  505. dwNumberOfId = m_csaAllId.Count();
  506. //
  507. // If given ID is same as generated one, it's unique.
  508. //
  509. if(0 == lstrcmp(szDeviceId, (LPTSTR)(m_csDeviceID))){
  510. bRet = TRUE;
  511. goto IsDeviceIdUnique_return;
  512. } // if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName)))
  513. //
  514. // Check any existing name matches given name.
  515. //
  516. for (Idx = 0; Idx < dwNumberOfId; Idx++) {
  517. DebugTrace(TRACE_STATUS,(("CDevice::IsDeviceIdUnique: DeviceId compare %ws and %ws.\r\n"),m_csaAllId[Idx], szDeviceId));
  518. if (0 == lstrcmpi(m_csaAllId[Idx], szDeviceId)){
  519. bRet = FALSE;
  520. goto IsDeviceIdUnique_return;
  521. } // if (0 == lstrcmpi(m_csaAllId[Idx], szFriendlyName))
  522. } // for (Idx = 0; Idx < dwNumberOfName; Idx)
  523. //
  524. // Look in name store.
  525. //
  526. if(IsNameAlreadyStored(szDeviceId)){
  527. bRet = FALSE;
  528. goto IsDeviceIdUnique_return;
  529. } // if(IsNameAlreadyStored(szFriendlyName))
  530. //
  531. // This device name is unique.
  532. //
  533. bRet = TRUE;
  534. IsDeviceIdUnique_return:
  535. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsDeviceIdUnique: Leaving... Ret=0x%x\n"), bRet));
  536. return bRet;
  537. } // CDevice::IsDeviceIdUnique()
  538. BOOL
  539. CDevice::NameDefaultUniqueName(
  540. VOID
  541. )
  542. {
  543. SP_DRVINFO_DATA spDrvInfoData;
  544. TCHAR szFriendly[MAX_DESCRIPTION];
  545. TCHAR szDescription[MAX_DESCRIPTION];
  546. UINT i;
  547. BOOL bRet;
  548. HKEY hkNameStore;
  549. DWORD dwError;
  550. DebugTrace(TRACE_PROC_ENTER,(("CDevice::NameDefaultUniqueName: Enter... \r\n")));
  551. //
  552. // Initialize local.
  553. //
  554. bRet = FALSE;
  555. hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
  556. memset(szFriendly, 0, sizeof(szFriendly));
  557. memset(szDescription, 0, sizeof(szDescription));
  558. memset(&spDrvInfoData, 0, sizeof(spDrvInfoData));
  559. //
  560. // Acquire mutex to make sure not duplicating FriendlyName/DeviceId.
  561. //
  562. dwError = AcquireInstallerMutex(MAX_MUTEXTIMEOUT);
  563. if(ERROR_SUCCESS != dwError){ // it must be done at least in 60 sec.
  564. if(WAIT_ABANDONED == dwError){
  565. DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Mutex abandoned. Continue...\r\n"));
  566. } else if(WAIT_TIMEOUT == dwError){
  567. DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to acquire mutex in 60 sec. Bail out.\r\n"));
  568. bRet = FALSE;
  569. goto NameDefaultUniqueName_return;
  570. } // else if(WAIT_TIMEOUT == dwError)
  571. } // if(ERROR_SUCCESS != AcquireInstallerMutex(60000))
  572. //
  573. // Get all installed WIA device friendly name.
  574. //
  575. CollectNames();
  576. //
  577. // Generate unique device ID.
  578. //
  579. if(m_csDeviceID.IsEmpty()){
  580. GenerateUniqueDeviceId();
  581. } // if(m_csDeviceID.IsEmpty())
  582. if(m_csFriendlyName.IsEmpty()){
  583. //
  584. // Get default FriendlyName. It's used to check if it's same device or not.
  585. //
  586. spDrvInfoData.cbSize = sizeof (SP_DRVINFO_DATA);
  587. if (!SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDrvInfoData)){
  588. bRet = FALSE;
  589. goto NameDefaultUniqueName_return;
  590. } // if (SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDevInfoData))
  591. //
  592. // Copy default Device description. (= default FriendlyName)
  593. // Also set Vnedor name.
  594. //
  595. m_csVendor = (LPCTSTR)spDrvInfoData.MfgName;
  596. m_csPdoDescription = (LPCTSTR)spDrvInfoData.Description;
  597. //
  598. // Find unique name for this device.
  599. //
  600. if(m_csDriverDescription.IsEmpty()){
  601. lstrcpyn(szDescription, m_csPdoDescription, ARRAYSIZE(szDescription)-1);
  602. m_csDriverDescription = szDescription;
  603. } else {
  604. lstrcpyn(szDescription, m_csDriverDescription, ARRAYSIZE(szDescription)-1);
  605. }
  606. lstrcpyn(szFriendly, szDescription, ARRAYSIZE(szFriendly)-1);
  607. for (i = 2; !IsFriendlyNameUnique(szFriendly); i++) {
  608. _sntprintf(szFriendly, ARRAYSIZE(szFriendly)-1, TEXT("%ws #%d"), szDescription, i);
  609. }
  610. //
  611. // Set created FriendlyName.
  612. //
  613. m_csFriendlyName = szFriendly;
  614. } // if(m_csFriendlyName.IsEmpty())
  615. //
  616. // Save FriendlyName and DeviceId in registry. It'll be deleted when installation is completed.
  617. //
  618. if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){
  619. HKEY hkTemp;
  620. hkTemp = (HKEY)INVALID_HANDLE_VALUE;
  621. //
  622. // Create FriendlyName key.
  623. //
  624. if(ERROR_SUCCESS == RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp)){
  625. RegCloseKey(hkTemp);
  626. hkTemp = (HKEY)INVALID_HANDLE_VALUE;
  627. } else {
  628. DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create %s key.\r\n", (LPTSTR)m_csFriendlyName));
  629. } // if(ERROR_SUCCESS != RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp))
  630. //
  631. // Create DeviceId key.
  632. //
  633. if(ERROR_SUCCESS == RegCreateKey(hkNameStore, (LPTSTR)m_csDeviceID, &hkTemp)){
  634. RegCloseKey(hkTemp);
  635. hkTemp = (HKEY)INVALID_HANDLE_VALUE;
  636. } else {
  637. DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create %s key.\r\n", (LPTSTR)m_csDeviceID));
  638. } // if(ERROR_SUCCESS != RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp))
  639. RegCloseKey(hkNameStore);
  640. } else { // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
  641. DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create NameStore key.\r\n"));
  642. } // else(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
  643. //
  644. // Operation succeeded.
  645. //
  646. DebugTrace(TRACE_STATUS,(("CDevice::NameDefaultUniqueName: Device default name=%ws.\r\n"), (LPTSTR)m_csFriendlyName));
  647. bRet = TRUE;
  648. NameDefaultUniqueName_return:
  649. //
  650. // Release mutex. ReleaseInstallerMutex() will handle invalid handle also, so we can call anyway.
  651. //
  652. ReleaseInstallerMutex();
  653. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::NameDefaultUniqueName: Leaving... Ret=0x%x\n"), bRet));
  654. return bRet;
  655. } // CDevice::NameDefaultUniqueName()
  656. BOOL
  657. CDevice::GenerateUniqueDeviceId(
  658. VOID
  659. )
  660. {
  661. DWORD Idx;
  662. BOOL bRet;
  663. TCHAR szDeviceId[MAX_DESCRIPTION];
  664. DebugTrace(TRACE_PROC_ENTER,(("CDevice::GenerateUniqueDeviceId: Enter... \r\n")));
  665. //
  666. // Initialize local.
  667. //
  668. bRet = FALSE;
  669. memset(szDeviceId, 0, sizeof(szDeviceId));
  670. //
  671. // Find unique name for this device.
  672. //
  673. _sntprintf(szDeviceId, ARRAYSIZE(szDeviceId)-1, TEXT("%ws\\%04d"), WIA_GUIDSTRING, 0);
  674. for (Idx = 1; !IsDeviceIdUnique(szDeviceId); Idx++) {
  675. _sntprintf(szDeviceId, ARRAYSIZE(szDeviceId)-1, TEXT("%ws\\%04d"), WIA_GUIDSTRING, Idx);
  676. }
  677. //
  678. // Set created hardwareId.
  679. //
  680. m_csDeviceID = szDeviceId;
  681. //
  682. // Operation succeeded.
  683. //
  684. DebugTrace(TRACE_STATUS,(("CDevice::GenerateUniqueDeviceId: DeviceID=%ws.\r\n"), (LPTSTR)m_csDeviceID));
  685. bRet = TRUE;
  686. // GenerateUniqueDeviceId_return:
  687. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::GenerateUniqueDeviceId: Leaving... Ret=0x%x\n"), bRet));
  688. return bRet;
  689. } // CDevice::GenerateUniqueDeviceId()
  690. BOOL
  691. CDevice::Install(
  692. )
  693. /*++
  694. Routine Description:
  695. Worker function for DIF_INSTALL setup message
  696. Arguments:
  697. none
  698. Return Value:
  699. TRUE - successful
  700. FALSE - non successful
  701. --*/
  702. {
  703. BOOL bRet;
  704. DebugTrace(TRACE_PROC_ENTER,(("CDevice::Install: Enter... \r\n")));
  705. //
  706. // Initialize local.
  707. //
  708. bRet = FALSE;
  709. //
  710. // Class installer only handles file copy.
  711. //
  712. if(IsMigration()){
  713. CreateDeviceInterfaceAndInstall();
  714. } else { // if(IsMigration())
  715. if ( !HandleFilesInstallation()){
  716. DebugTrace(TRACE_ERROR, (("CDevice::Install: HandleFilesInstallation Failed. Err=0x%x"), GetLastError()));
  717. bRet = FALSE;
  718. goto Install_return;
  719. } // if ( !HandleFilesInstallation())
  720. } // else(IsMigration())
  721. //
  722. // We are successfully finished
  723. //
  724. bRet = TRUE;
  725. Install_return:
  726. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::Install: Leaving... Ret=0x%x\n"), bRet));
  727. return bRet;
  728. }
  729. DWORD
  730. CDevice::Remove(
  731. PSP_REMOVEDEVICE_PARAMS lprdp
  732. )
  733. /*++
  734. Routine Description:
  735. Remove
  736. method which is called when device is being removed
  737. Arguments:
  738. Return Value:
  739. Side effects:
  740. --*/
  741. {
  742. CString csUninstallSection;
  743. CString csInf;
  744. CString csSubClass;
  745. DWORD dwCapabilities;
  746. PVOID pvContext;
  747. HKEY hkDrv;
  748. HKEY hkRun;
  749. GUID Guid;
  750. BOOL bIsServiceStopped;
  751. BOOL bIsSti;
  752. BOOL bSetParamRet;
  753. PSP_FILE_CALLBACK SavedCallback;
  754. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  755. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  756. DWORD dwReturn;
  757. LPTSTR pSec;
  758. DebugTrace(TRACE_PROC_ENTER,(("CDevice::Remove: Enter... \r\n")));
  759. //
  760. // Initialize local.
  761. //
  762. pvContext = NULL;
  763. hkDrv = NULL;
  764. hkRun = NULL;
  765. bSetParamRet = FALSE;
  766. SavedCallback = NULL;
  767. dwReturn = NO_ERROR;
  768. Guid = GUID_DEVCLASS_IMAGE;
  769. bIsServiceStopped = FALSE;
  770. bIsSti = FALSE;
  771. memset(&DeviceInstallParams, 0, sizeof(DeviceInstallParams));
  772. memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
  773. //
  774. // NT setup inconsistently set this bit , disable for now
  775. //
  776. #if SETUP_PROBLEM
  777. if (!(lprdp->Scope & DI_REMOVEDEVICE_GLOBAL)) {
  778. goto Remove_return;
  779. }
  780. #endif
  781. //
  782. // The name of the uninstall section was stored during installation
  783. //
  784. if(IsInterfaceOnlyDevice()){
  785. DebugTrace(TRACE_STATUS,(("CDevice::Remove: This is Interface-only device.\r\n")));
  786. //
  787. // Get interface from index.
  788. //
  789. spDevInterfaceData.cbSize = sizeof(spDevInterfaceData);
  790. if(!SetupDiEnumDeviceInterfaces(m_hDevInfo, NULL, &Guid, m_dwInterfaceIndex, &spDevInterfaceData)){
  791. DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiEnumDeviceInterfaces() failed. Err=0x%x \r\n"), GetLastError()));
  792. dwReturn = ERROR_NO_DEFAULT_DEVICE_INTERFACE;
  793. goto Remove_return;
  794. }
  795. //
  796. // Create interface reg-key.
  797. //
  798. hkDrv = SetupDiOpenDeviceInterfaceRegKey(m_hDevInfo,
  799. &spDevInterfaceData,
  800. 0,
  801. KEY_READ);
  802. } else { // if(IsInterfaceOnlyDevice())
  803. DebugTrace(TRACE_STATUS,(("CDevice::Remove: This is devnode device.\r\n")));
  804. hkDrv = SetupDiOpenDevRegKey(m_hDevInfo,
  805. m_pspDevInfoData,
  806. DICS_FLAG_GLOBAL,
  807. 0,
  808. DIREG_DRV,
  809. KEY_READ);
  810. } // if(IsInterfaceOnlyDevice())
  811. if (hkDrv == INVALID_HANDLE_VALUE) {
  812. DebugTrace(TRACE_ERROR,(("CDevice::Remove: Invalid device/interface regkey handle. Err=0x%x \r\n"), GetLastError()));
  813. dwReturn = ERROR_KEY_DOES_NOT_EXIST;
  814. goto Remove_return;
  815. }
  816. //
  817. // Retrieve the name of the .INF File
  818. //
  819. csUninstallSection.Load (hkDrv, UNINSTALLSECTION);
  820. csInf.Load (hkDrv, INFPATH);
  821. csSubClass.Load(hkDrv, SUBCLASS);
  822. GetDwordFromRegistry(hkDrv, CAPABILITIES, &dwCapabilities);
  823. //
  824. // See if we need STI/WIA specific operation.
  825. //
  826. if( (!csSubClass.IsEmpty())
  827. && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) )
  828. {
  829. //
  830. // This is STI/WIA device.
  831. //
  832. bIsSti = TRUE;
  833. //
  834. // Delete "Scanner and Camera Wizard" menu.
  835. //
  836. if( (dwCapabilities & STI_GENCAP_WIA)
  837. && (m_dwNumberOfWiaDevice <= 1) )
  838. {
  839. DeleteWiaShortcut();
  840. //
  841. // remove following key for performance improvement.
  842. //
  843. if(ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT)){
  844. DebugTrace(TRACE_ERROR,(("CDevice::Remove: RegDeleteKey() failed. Err=0x%x. \r\n"), GetLastError()));
  845. } // if(ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT))
  846. } // if( (dwCapabilities & STI_GENCAP_WIA)
  847. //
  848. // If this is the last STI/WIA device, set WIA service as Manual.
  849. //
  850. if(m_dwNumberOfStiDevice <= 1){
  851. HKEY hkeyTemp;
  852. DebugTrace(TRACE_STATUS,(("CDevice::Remove: Last WIA device being removed. Set WIA service as MANUAL.\r\n")));
  853. //
  854. // No more still image devices -- change service to Manual start
  855. //
  856. // StopWiaService();
  857. SetServiceStart(STI_SERVICE_NAME, SERVICE_DEMAND_START);
  858. bIsServiceStopped = TRUE;
  859. //
  860. //
  861. // Also remove shell's flag about WIA device presence, this should be portable
  862. // to NT
  863. //
  864. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun) == 0) {
  865. RegDeleteValue (hkRun, REGSTR_VAL_WIA_PRESENT);
  866. RegCloseKey(hkRun);
  867. hkRun = NULL;
  868. } // if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun) == 0)
  869. } // if(m_dwNumberOfStiDevice <= 1)
  870. } // if (m_dwNumberOfDevice <= 1)
  871. //
  872. // Operaion succeeded.
  873. //
  874. dwReturn = NO_ERROR;
  875. Remove_return:
  876. if(IsInterfaceOnlyDevice()){
  877. //
  878. // Remove the interface.
  879. //
  880. if(!SetupDiRemoveDeviceInterface(m_hDevInfo, &spDevInterfaceData)){
  881. DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiRemoveDeviceInterface failed. Err=0x%x \r\n"), GetLastError()));
  882. } // if(!SetupDiRemoveDeviceInterface(m_hDevInfo, &spDevInterfaceData))
  883. } else { // if(IsInterfaceOnlyDevice())
  884. //
  885. // Remove the device node anyway.
  886. //
  887. if(!SetupDiRemoveDevice(m_hDevInfo, m_pspDevInfoData)){
  888. DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiRemoveDevice failed. Err=0x%x \r\n"), GetLastError()));
  889. //
  890. // Failed to remove device instance from system. Let default installer do that.
  891. //
  892. dwReturn = ERROR_DI_DO_DEFAULT;
  893. } // if(!SetupDiRemoveDevice(m_hDevInfo, m_pspDevInfoData))
  894. } // else (IsInterfaceOnlyDevice())
  895. //
  896. // Clean up.
  897. //
  898. if(IS_VALID_HANDLE(hkDrv)){
  899. RegCloseKey (hkDrv);
  900. hkDrv = NULL;
  901. }
  902. if(IS_VALID_HANDLE(hkRun)){
  903. RegCloseKey (hkRun);
  904. hkRun = NULL;
  905. }
  906. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::Remove: Leaving... Ret=0x%x\n"), dwReturn));
  907. return dwReturn;
  908. }
  909. BOOL
  910. CDevice::PreprocessInf(
  911. VOID
  912. )
  913. {
  914. BOOL bRet;
  915. HINF hInf;
  916. CString csCapabilities;
  917. CString csDeviceType;
  918. CString csDeviceSubType;
  919. CString csDriverDescription;
  920. DebugTrace(TRACE_PROC_ENTER,(("CDevice::PreprocessInf: Enter... \r\n")));
  921. //
  922. // Initialize local.
  923. //
  924. bRet = FALSE;
  925. hInf = INVALID_HANDLE_VALUE;
  926. //
  927. // Check if INF has already been proceeded.
  928. //
  929. if(m_bInfProceeded){
  930. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: INF is already processed. \r\n")));
  931. bRet = TRUE;
  932. goto ProcessInf_return;
  933. }
  934. //
  935. // Get Inf file/section name.
  936. //
  937. if( m_csInf.IsEmpty() || m_csInstallSection.IsEmpty()){
  938. GetInfInforamtion();
  939. } // if( m_csInf.IsEmpty() || m_csInstallSection.IsEmpty())
  940. //
  941. // Open INF file.
  942. //
  943. hInf = SetupOpenInfFile(m_csInf,
  944. NULL,
  945. INF_STYLE_WIN4,
  946. NULL);
  947. if(!IS_VALID_HANDLE(hInf)){
  948. DebugTrace(TRACE_ERROR, (("CDevice::PreprocessInf: Unable to open INF(%ws). Error = 0x%x.\r\n"),m_csInf, GetLastError()));
  949. bRet = FALSE;
  950. goto ProcessInf_return;
  951. } // if(!IS_VALID_HANDLE(hInf))
  952. //
  953. // Check if WiaSection entry exists.
  954. //
  955. m_csWiaSection.Load (hInf, m_csInstallSection, WIASECTION);
  956. if(!m_csWiaSection.IsEmpty()){
  957. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: WiaSection exists. Acquire all informaiton from WiaSection..\r\n")));
  958. //
  959. // Install interface from WiaSection for MFP device.
  960. //
  961. m_csInstallSection = m_csWiaSection;
  962. m_bInterfaceOnly = TRUE;
  963. } // if(!m_csWiaSection.IsEmpty())
  964. //
  965. // Get all information required for installation from inf file.
  966. //
  967. m_csSubClass.Load (hInf, m_csInstallSection, SUBCLASS);
  968. m_csUSDClass.Load (hInf, m_csInstallSection, USDCLASS);
  969. m_csEventSection.Load (hInf, m_csInstallSection, EVENTS);
  970. m_csConnection.Load (hInf, m_csInstallSection, CONNECTION);
  971. m_csIcmProfile.Load (hInf, m_csInstallSection, ICMPROFILES);
  972. m_csPropPages.Load (hInf, m_csInstallSection, PROPERTYPAGES);
  973. m_csDataSection.Load (hInf, m_csInstallSection, DEVICESECTION);
  974. m_csUninstallSection.Load (hInf, m_csInstallSection, UNINSTALLSECTION);
  975. m_csPortSelect.Load (hInf, m_csInstallSection, PORTSELECT);
  976. if(!IsMigration()){
  977. csDriverDescription.Load(hInf, m_csInstallSection, DESCRIPTION);
  978. if(!csDriverDescription.IsEmpty()){
  979. m_csDriverDescription = csDriverDescription;
  980. if(TRUE != NameDefaultUniqueName()){
  981. //
  982. // Unable to generate FriendlyName.
  983. //
  984. bRet = FALSE;
  985. goto ProcessInf_return;
  986. } // if(TRUE != NameDefaultUniqueName())
  987. } // if(!m_csDriverDescription.IsEmpty())
  988. } // if(!IsMigration())
  989. csCapabilities.Load (hInf, m_csInstallSection, CAPABILITIES);
  990. csDeviceType.Load (hInf, m_csInstallSection, DEVICETYPE);
  991. csDeviceSubType.Load (hInf, m_csInstallSection, DEVICESUBTYPE);
  992. m_dwCapabilities = csCapabilities.Decode();
  993. m_dwDeviceType = csDeviceType.Decode();
  994. m_dwDeviceSubType = csDeviceSubType.Decode();
  995. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: --------------- INF parameters --------------- \r\n")));
  996. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Description : %ws\n"), (LPTSTR)m_csDriverDescription));
  997. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: SubClass : %ws\n"), (LPTSTR)m_csSubClass));
  998. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: USDClass : %ws\n"), (LPTSTR)m_csUSDClass));
  999. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: EventSection : %ws\n"), (LPTSTR)m_csEventSection));
  1000. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Connection : %ws\n"), (LPTSTR)m_csConnection));
  1001. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: IcmProfile : %ws\n"), (LPTSTR)m_csIcmProfile));
  1002. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: PropPages : %ws\n"), (LPTSTR)m_csPropPages));
  1003. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DataSection : %ws\n"), (LPTSTR)m_csDataSection));
  1004. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: UninstallSection : %ws\n"), (LPTSTR)m_csUninstallSection));
  1005. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Capabilities : 0x%x\n"), m_dwCapabilities));
  1006. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DeviceType : 0x%x\n"), m_dwDeviceType));
  1007. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DeviceSubType : 0x%x\n"), m_dwDeviceSubType));
  1008. //
  1009. // Set video device flag if applicable.
  1010. //
  1011. if(StiDeviceTypeStreamingVideo == m_dwDeviceType){
  1012. DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: This is video device.\r\n")));
  1013. m_bVideoDevice = TRUE;
  1014. } else {
  1015. m_bVideoDevice = FALSE;
  1016. }
  1017. //
  1018. // Operation succeeded.
  1019. //
  1020. bRet = TRUE;
  1021. m_bInfProceeded = TRUE;
  1022. ProcessInf_return:
  1023. if(IS_VALID_HANDLE(hInf)){
  1024. SetupCloseInfFile(hInf);
  1025. hInf = INVALID_HANDLE_VALUE;
  1026. } // if(IS_VALID_HANDLE(hInf))
  1027. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PreprocessInf: Leaving... Ret=0x%x \r\n"), bRet));
  1028. return bRet;
  1029. } // CDevice::PreprocessInf()
  1030. BOOL
  1031. CDevice::PreInstall(
  1032. VOID
  1033. )
  1034. {
  1035. BOOL bRet;
  1036. HKEY hkDrv;
  1037. GUID Guid;
  1038. HDEVINFO hDevInfo;
  1039. SP_DEVINFO_DATA spDevInfoData;
  1040. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  1041. PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData;
  1042. BOOL bUseDefaultDevInfoSet;
  1043. DWORD dwRequiredSize;
  1044. DebugTrace(TRACE_PROC_ENTER,(("CDevice::PreInstall: Enter... \r\n")));
  1045. //
  1046. // Initialize local.
  1047. //
  1048. bRet = FALSE;
  1049. //
  1050. // Get all INF parameter.
  1051. //
  1052. if(!PreprocessInf()){
  1053. DebugTrace(TRACE_ERROR,(("CDevice::PreInstall: ERROR!! Unable to process INF.\r\n")));
  1054. bRet = FALSE;
  1055. goto PreInstall_return;
  1056. }
  1057. /**************************************
  1058. if(!IsInterfaceOnlyDevice()){
  1059. //
  1060. // Register device if it's getting manually installed and not "interface-only" device..
  1061. //
  1062. if(!IsPnpDevice()){
  1063. if (!SetupDiRegisterDeviceInfo(m_hDevInfo, m_pspDevInfoData, 0, NULL, NULL, NULL)) {
  1064. DebugTrace(TRACE_ERROR,(("CDevice::PreInstall: SetupDiRegisterDeviceInfo failed. Err=0x%x.\r\n"),GetLastError()));
  1065. bRet = FALSE;
  1066. goto PreInstall_return;
  1067. }
  1068. } // if(!IsPnpDevice())
  1069. } // if(IsInterfaceOnlyDevice())
  1070. **************************************/
  1071. //
  1072. // Clean up.
  1073. //
  1074. //
  1075. // Operation succeeded.
  1076. //
  1077. bRet = TRUE;
  1078. PreInstall_return:
  1079. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PreInstall: Leaving... Ret=0x%x.\r\n"), bRet));
  1080. return bRet;
  1081. }
  1082. BOOL
  1083. CDevice::PostInstall(
  1084. BOOL bSucceeded
  1085. )
  1086. {
  1087. BOOL bRet;
  1088. HKEY hkRun;
  1089. HKEY hkDrv;
  1090. DWORD dwFlagPresent;
  1091. CString csInfFilename;
  1092. CString csInfSection;
  1093. GUID Guid;
  1094. HKEY hkNameStore;
  1095. DebugTrace(TRACE_PROC_ENTER,(("CDevice::PostInstall: Enter... \r\n")));
  1096. //
  1097. // Initialize local.
  1098. //
  1099. bRet = FALSE;
  1100. hkRun = NULL;
  1101. dwFlagPresent = 1;
  1102. Guid = GUID_DEVCLASS_IMAGE;
  1103. hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
  1104. if(IsFeatureInstallation()){
  1105. //
  1106. // This is a "feature" added to other class devnode and being installed by co-isntaller.
  1107. // Need to do actual installation here only for "feature", manual installed device would
  1108. // be installed through wizard. (final.cpp)
  1109. //
  1110. bRet = Install();
  1111. if(FALSE == bRet){
  1112. DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: device interface registry key creation failed. \r\n")));
  1113. bSucceeded = FALSE;
  1114. } //if(FALSE == bRet)
  1115. } // if(IsFeatureInstallation())
  1116. if(!bSucceeded){
  1117. HDEVINFO hDevInfo;
  1118. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  1119. DWORD dwIndex;
  1120. //
  1121. // Installation failed. Do clean up.
  1122. //
  1123. DebugTrace(TRACE_STATUS,(("CDevice::PostInstall: Installation failed. Do clean up.\r\n")));
  1124. //
  1125. // Delete craeted interface if any.
  1126. //
  1127. if(IsInterfaceOnlyDevice()){
  1128. hDevInfo = GetDeviceInterfaceIndex(m_csDeviceID, &dwIndex);
  1129. if(IS_VALID_HANDLE(hDevInfo)){
  1130. spDevInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
  1131. if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &Guid, dwIndex, &spDevInterfaceData)){
  1132. //
  1133. // Created Interface is found. Delete it...
  1134. //
  1135. DebugTrace(TRACE_STATUS,(("CDevice::PostInstall: Deleting created interface for %ws.\r\n"), (LPTSTR)m_csFriendlyName));
  1136. if(!SetupDiRemoveDeviceInterface(hDevInfo, &spDevInterfaceData)){
  1137. DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! Unable to delete interface for %ws. Err=0x%x\n"), m_csFriendlyName, GetLastError()));
  1138. }
  1139. } // if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &Guid, dwIndex, &spDevInterfaceData))
  1140. //
  1141. // Destroy created DevInfoSet.
  1142. //
  1143. SetupDiDestroyDeviceInfoList(hDevInfo);
  1144. } // if(NULL != hDevInfo)
  1145. } // if(IsInterfaceOnlyDevice())
  1146. bRet = TRUE;
  1147. goto PostInstall_return;
  1148. } // if(!bSucceeded)
  1149. //
  1150. // Save all Inf parameters to registry.
  1151. //
  1152. if(!UpdateDeviceRegistry()){
  1153. DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! UpdateDeviceRegistry() failed. \r\n")));
  1154. }
  1155. //
  1156. // Do WIA/STI device only process.
  1157. //
  1158. if( (!m_csSubClass.IsEmpty())
  1159. && (0 == MyStrCmpi(m_csSubClass, STILL_IMAGE)) )
  1160. {
  1161. HKEY hkeyTemp;
  1162. //
  1163. // Change service to AUTO start.
  1164. //
  1165. if(TRUE != SetServiceStart(STI_SERVICE_NAME, SERVICE_AUTO_START)){
  1166. CString csServiceName;
  1167. //
  1168. // Load ServiceName from resource.
  1169. //
  1170. csServiceName.FromTable(WiaServiceName);
  1171. //
  1172. // Service is unable to change start type, supposed to be disabled.
  1173. //
  1174. if( (!m_csFriendlyName.IsEmpty())
  1175. && (!csServiceName.IsEmpty()) )
  1176. {
  1177. LPTSTR szMsgArray[2];
  1178. szMsgArray[0] = m_csFriendlyName;
  1179. szMsgArray[1] = csServiceName;
  1180. LogSystemEvent(EVENTLOG_WARNING_TYPE, MSG_WARNING_SERVICE_DISABLED, 2, szMsgArray);
  1181. }
  1182. } // if(TRUE != SetServiceStart(STI_SERVICE_NAME, SERVICE_AUTO_START))
  1183. //
  1184. // Start WIA service.
  1185. //
  1186. if(!StartWiaService()){
  1187. // DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! Unable to start WIA service.\r\n")));
  1188. }
  1189. //
  1190. // Create "Scanner and Camera Wizard" menu if WIA.
  1191. //
  1192. if(m_dwCapabilities & STI_GENCAP_WIA){
  1193. CreateWiaShortcut();
  1194. //
  1195. // Add following value upon device arrival for performance improvement.
  1196. //
  1197. if (ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT, &hkeyTemp)) {
  1198. RegSetValue (hkeyTemp,
  1199. NULL,
  1200. REG_SZ,
  1201. REGSTR_VAL_WIASHEXT,
  1202. lstrlen(REGSTR_VAL_WIASHEXT) * sizeof(TCHAR));
  1203. RegCloseKey(hkeyTemp);
  1204. hkeyTemp = NULL;
  1205. } else {
  1206. DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! RegOpenKey(WIASHEXT) failed. Err=0x%x \r\n"), GetLastError()));
  1207. } // if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun))
  1208. } // if(m_dwCapabilities & STI_GENCAP_WIA)
  1209. //
  1210. // Also add shell's flag about WIA device presence, this should be portable
  1211. // to NT
  1212. //
  1213. if (ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun)) {
  1214. RegDeleteValue (hkRun, REGSTR_VAL_WIA_PRESENT);
  1215. RegSetValueEx (hkRun,
  1216. REGSTR_VAL_WIA_PRESENT,
  1217. 0,
  1218. REG_DWORD,
  1219. (LPBYTE)&dwFlagPresent,
  1220. sizeof(DWORD));
  1221. } else {
  1222. DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! RegOpenKey() failed. Err=0x%x \r\n"), GetLastError()));
  1223. } // if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun))
  1224. } // if(!lstrcmpi(m_csSubClass, STILL_IMAGE))
  1225. //
  1226. // ICM support
  1227. //
  1228. ProcessICMProfiles();
  1229. //
  1230. // Register interface name of Videoo device.
  1231. //
  1232. bRet = TRUE;
  1233. PostInstall_return:
  1234. //
  1235. // Clean up.
  1236. //
  1237. if(NULL != hkRun){
  1238. RegCloseKey(hkRun);
  1239. }
  1240. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PostInstall: Leaving... Ret=0x%x.\r\n"), bRet));
  1241. return bRet;
  1242. } // CDevice::PostInstall()
  1243. BOOL
  1244. CDevice::HandleFilesInstallation(
  1245. VOID
  1246. )
  1247. /*++
  1248. Routine Description:
  1249. Arguments:
  1250. Return Value:
  1251. Side effects:
  1252. --*/
  1253. {
  1254. BOOL bRet;
  1255. BOOL bSetParamRet;
  1256. PSP_FILE_CALLBACK pSavedCallback;
  1257. PVOID pvContext;
  1258. SP_DEVINSTALL_PARAMS spDeviceInstallParams;
  1259. DebugTrace(TRACE_PROC_ENTER,(("CDevice::HandleFilesInstallation: Enter... \r\n")));
  1260. //
  1261. // Initialize local.
  1262. //
  1263. bRet = FALSE;
  1264. bSetParamRet = FALSE;
  1265. pvContext = NULL;
  1266. pSavedCallback = NULL;
  1267. memset(&spDeviceInstallParams, 0, sizeof(spDeviceInstallParams));
  1268. //
  1269. // Get device install parameter.
  1270. //
  1271. spDeviceInstallParams.cbSize = sizeof (SP_DEVINSTALL_PARAMS);
  1272. if (!SetupDiGetDeviceInstallParams (m_hDevInfo, m_pspDevInfoData, &spDeviceInstallParams)) {
  1273. DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiGetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError()));
  1274. bRet = FALSE;
  1275. goto HandleFilesInstallation_return;
  1276. }
  1277. //
  1278. // Modify device installation parameters to have custom callback
  1279. //
  1280. pvContext = SetupInitDefaultQueueCallbackEx(NULL,
  1281. (HWND)((spDeviceInstallParams.Flags & DI_QUIETINSTALL) ?INVALID_HANDLE_VALUE : NULL),
  1282. 0,
  1283. 0,
  1284. NULL);
  1285. if(NULL == pvContext){
  1286. DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupInitDefaultQueueCallbackEx() failed. Err=0x%x.\r\n"), GetLastError()));
  1287. bRet = FALSE;
  1288. goto HandleFilesInstallation_return;
  1289. } // if(NULL == pvContext)
  1290. pSavedCallback = spDeviceInstallParams.InstallMsgHandler;
  1291. spDeviceInstallParams.InstallMsgHandler = StiInstallCallback;
  1292. spDeviceInstallParams.InstallMsgHandlerContext = pvContext;
  1293. bSetParamRet = SetupDiSetDeviceInstallParams (m_hDevInfo,
  1294. m_pspDevInfoData,
  1295. &spDeviceInstallParams);
  1296. if(FALSE == bSetParamRet){
  1297. DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiSetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError()));
  1298. bRet = FALSE;
  1299. goto HandleFilesInstallation_return;
  1300. } // if(FALSE == bSetParamRet)
  1301. //
  1302. // Let the default installer do its job.
  1303. //
  1304. if(IsInterfaceOnlyDevice()){
  1305. bRet = CreateDeviceInterfaceAndInstall();
  1306. } else {
  1307. bRet = SetupDiInstallDevice(m_hDevInfo, m_pspDevInfoData);
  1308. }
  1309. if(FALSE == bRet){
  1310. DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiInstallDevice() failed. Err=0x%x.\r\n"), GetLastError()));
  1311. bRet = FALSE;
  1312. goto HandleFilesInstallation_return;
  1313. } // if(FALSE == bSetParamRet)
  1314. //
  1315. // Terminate defaule queue callback
  1316. //
  1317. SetupTermDefaultQueueCallback(pvContext);
  1318. //
  1319. // Cleanup.
  1320. //
  1321. if (bSetParamRet) {
  1322. spDeviceInstallParams.InstallMsgHandler = pSavedCallback;
  1323. SetupDiSetDeviceInstallParams (m_hDevInfo, m_pspDevInfoData, &spDeviceInstallParams);
  1324. }
  1325. HandleFilesInstallation_return:
  1326. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::HandleFilesInstallation: Leaving... Ret=0x%x.\r\n"), bRet));
  1327. return bRet;
  1328. } // CDevice::HandleFilesInstallation()
  1329. BOOL
  1330. CDevice::UpdateDeviceRegistry(
  1331. VOID
  1332. )
  1333. {
  1334. BOOL bRet;
  1335. HKEY hkDrv;
  1336. DWORD dwConnectionType;
  1337. HINF hInf;
  1338. DebugTrace(TRACE_PROC_ENTER,(("CDevice::UpdateDeviceRegistry: Enter... \r\n")));
  1339. //
  1340. // Initialize Local.
  1341. //
  1342. bRet = FALSE;
  1343. hkDrv = NULL;
  1344. dwConnectionType = STI_HW_CONFIG_UNKNOWN;
  1345. //
  1346. // Open INF.
  1347. //
  1348. hInf = SetupOpenInfFile(m_csInf,
  1349. NULL,
  1350. INF_STYLE_WIN4,
  1351. NULL);
  1352. if (hInf == INVALID_HANDLE_VALUE) {
  1353. DebugTrace(TRACE_ERROR, (("CDevice::UpdateDeviceRegistry: Unable to open INF(%ws). Error = 0x%x.\r\n"),m_csInf, GetLastError()));
  1354. bRet = FALSE;
  1355. goto UpdateDeviceRegistry_return;
  1356. } // if (hInf == INVALID_HANDLE_VALUE)
  1357. //
  1358. // Create device registry key.
  1359. //
  1360. if(IsInterfaceOnlyDevice()){
  1361. DebugTrace(TRACE_STATUS,(("CDevice::UpdateDeviceRegistry: This is Interface-only device.\r\n")));
  1362. //
  1363. // Create interface reg-key.
  1364. //
  1365. hkDrv = m_hkInterfaceRegistry;
  1366. } else { // if(IsInterfaceOnlyDevice())
  1367. DebugTrace(TRACE_STATUS,(("CDevice::UpdateDeviceRegistry: This is devnode device.\r\n")));
  1368. hkDrv = SetupDiCreateDevRegKey(m_hDevInfo,
  1369. m_pspDevInfoData,
  1370. DICS_FLAG_GLOBAL,
  1371. 0,
  1372. DIREG_DRV,
  1373. NULL,
  1374. NULL);
  1375. } // if(IsInterfaceOnlyDevice())
  1376. if(hkDrv == INVALID_HANDLE_VALUE) {
  1377. DebugTrace(TRACE_ERROR,(("CDevice::UpdateDeviceRegistry: ERROR!! SetupDiCreateDevRegKey() failed. Err=0x%x.\r\n"), GetLastError()));
  1378. bRet = FALSE;
  1379. goto UpdateDeviceRegistry_return;
  1380. } //if(hkDrv == INVALID_HANDLE_VALUE)
  1381. //
  1382. // Save INF parameters to registry.
  1383. //
  1384. if(m_csPort.IsEmpty()){
  1385. if(m_bInterfaceOnly){
  1386. //
  1387. // If PortName doesn't exist for interface-only device, then use symbolic link as CraeteFile name.
  1388. //
  1389. m_csSymbolicLink.Store(hkDrv, CREATEFILENAME);
  1390. } //if(m_bInterfaceOnly)
  1391. } else { // if(m_csPort.IsEmpty())
  1392. m_csPort.Store(hkDrv, CREATEFILENAME);
  1393. } // if(m_csPort.IsEmpty())
  1394. m_csSubClass.Store(hkDrv, SUBCLASS);
  1395. m_csUSDClass.Store(hkDrv, USDCLASS);
  1396. m_csVendor.Store(hkDrv, VENDOR);
  1397. m_csFriendlyName.Store(hkDrv, FRIENDLYNAME);
  1398. m_csUninstallSection.Store(hkDrv, UNINSTALLSECTION);
  1399. m_csPropPages.Store(hkDrv, PROPERTYPAGES);
  1400. m_csIcmProfile.Store(hkDrv, ICMPROFILES);
  1401. m_csDeviceID.Store(hkDrv, REGSTR_VAL_DEVICE_ID);
  1402. m_csPortSelect.Store (hkDrv, PORTSELECT);
  1403. if(IsInterfaceOnlyDevice()){
  1404. m_csInf.Store(hkDrv, INFPATH);
  1405. m_csInstallSection.Store(hkDrv, INFSECTION);
  1406. m_csDriverDescription.Store(hkDrv, DRIVERDESC);
  1407. } // if(IsInterfaceOnlyDevice())
  1408. //
  1409. // Save DWORD values.
  1410. //
  1411. RegSetValueEx(hkDrv,
  1412. CAPABILITIES,
  1413. 0,
  1414. REG_DWORD,
  1415. (LPBYTE) &m_dwCapabilities,
  1416. sizeof(m_dwCapabilities));
  1417. RegSetValueEx(hkDrv,
  1418. DEVICETYPE,
  1419. 0,
  1420. REG_DWORD,
  1421. (LPBYTE) &m_dwDeviceType,
  1422. sizeof(m_dwDeviceType));
  1423. RegSetValueEx(hkDrv,
  1424. DEVICESUBTYPE,
  1425. 0,
  1426. REG_DWORD,
  1427. (LPBYTE) &m_dwDeviceSubType,
  1428. sizeof(m_dwDeviceSubType));
  1429. RegSetValueEx(hkDrv,
  1430. ISPNP,
  1431. 0,
  1432. REG_DWORD,
  1433. (LPBYTE) &m_bIsPnP,
  1434. sizeof(m_bIsPnP));
  1435. //
  1436. // Set HardwareConfig. (= Connection)
  1437. //
  1438. if(!m_csConnection.IsEmpty()){
  1439. m_csConnection.Store (hkDrv, CONNECTION);
  1440. if(_tcsicmp(m_csConnection, SERIAL) == 0 ){
  1441. dwConnectionType = STI_HW_CONFIG_SERIAL;
  1442. }
  1443. else if(_tcsicmp(m_csConnection, PARALLEL) == 0 ){
  1444. dwConnectionType = STI_HW_CONFIG_PARALLEL;
  1445. }
  1446. if (dwConnectionType != STI_HW_CONFIG_UNKNOWN) {
  1447. RegSetValueEx(hkDrv,
  1448. REGSTR_VAL_HARDWARE,
  1449. 0,
  1450. REG_DWORD,
  1451. (LPBYTE) &dwConnectionType,
  1452. sizeof(dwConnectionType));
  1453. }
  1454. } // if(!m_csConneciton.IsEmpty())
  1455. //
  1456. // Process DeviceData section.
  1457. //
  1458. ProcessDataSection(hInf, hkDrv);
  1459. //
  1460. // Process Event section.
  1461. //
  1462. ProcessEventsSection(hInf, hkDrv);
  1463. //
  1464. // Create registry key for video key if applicable.
  1465. //
  1466. ProcessVideoDevice(hkDrv);
  1467. //
  1468. // Operation succeeded.
  1469. //
  1470. bRet = TRUE;
  1471. UpdateDeviceRegistry_return:
  1472. //
  1473. // Cleanup.
  1474. //
  1475. if(hkDrv != INVALID_HANDLE_VALUE){
  1476. RegCloseKey(hkDrv);
  1477. m_hkInterfaceRegistry = NULL;
  1478. }
  1479. if(hInf != INVALID_HANDLE_VALUE){
  1480. SetupCloseInfFile(hInf);
  1481. }
  1482. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::UpdateDeviceRegistry: Leaving... Ret=0x%x.\r\n"), bRet));
  1483. return bRet;
  1484. } // CDevice::UpdateDeviceRegistry()
  1485. VOID
  1486. CDevice::ProcessVideoDevice(
  1487. HKEY hkDrv
  1488. )
  1489. {
  1490. GUID Guid;
  1491. HKEY hkDeviceData;
  1492. TCHAR Buffer[1024];
  1493. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  1494. PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetail;
  1495. DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessVideoDevice: Enter... \r\n")));
  1496. //
  1497. // Initialize local.
  1498. //
  1499. Guid = KSCATEGORY_CAPTURE;
  1500. pspDevInterfaceDetail = NULL;
  1501. hkDeviceData = NULL;
  1502. memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
  1503. memset(Buffer, 0, sizeof(Buffer));
  1504. //
  1505. // This is only for video devices.
  1506. //
  1507. if (!m_bVideoDevice) {
  1508. DebugTrace(TRACE_STATUS,(("CDevice::ProcessVideoDevice: This is not a video device. Do nothing.\r\n")));
  1509. goto ProcessVideoDevice_return;
  1510. }
  1511. //
  1512. // Use "AUTO" as dummy CreatFile name for Video devices.
  1513. //
  1514. RegSetValueEx( hkDrv,
  1515. CREATEFILENAME,
  1516. 0,
  1517. REG_SZ,
  1518. (LPBYTE)AUTO,
  1519. (lstrlen(AUTO)+1)*sizeof(TCHAR)
  1520. );
  1521. //
  1522. // Get device interface data of installing Video device.
  1523. //
  1524. spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  1525. if (!SetupDiEnumDeviceInterfaces (m_hDevInfo,
  1526. m_pspDevInfoData,
  1527. &Guid,
  1528. 0,
  1529. &spDevInterfaceData
  1530. ) )
  1531. {
  1532. DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!!SetupDiEnumDeviceInterfaces failed. Err=0x%x \r\n"), GetLastError()));
  1533. goto ProcessVideoDevice_return;
  1534. }
  1535. //
  1536. // Get detailed data of acquired interface.
  1537. //
  1538. pspDevInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buffer;
  1539. pspDevInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  1540. if (!SetupDiGetDeviceInterfaceDetail (m_hDevInfo,
  1541. &spDevInterfaceData,
  1542. pspDevInterfaceDetail,
  1543. sizeof(Buffer) - sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA),
  1544. NULL,
  1545. NULL) )
  1546. {
  1547. DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!!SetupDiGetDeviceInterfaceDetail failed. Err=0x%x \r\n"), GetLastError()));
  1548. goto ProcessVideoDevice_return;
  1549. }
  1550. //
  1551. // We got the device path, now write it to registry
  1552. //
  1553. if (ERROR_SUCCESS != RegOpenKey(hkDrv, DEVICESECTION, &hkDeviceData)) {
  1554. DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!! Unable to open DeviceData key. Err=0x%x \r\n"), GetLastError()));
  1555. goto ProcessVideoDevice_return;
  1556. }
  1557. RegSetValueEx(hkDeviceData,
  1558. VIDEO_PATH_ID,
  1559. 0,
  1560. REG_SZ,
  1561. (LPBYTE)pspDevInterfaceDetail->DevicePath,
  1562. (lstrlen(pspDevInterfaceDetail->DevicePath)+1)*sizeof(TCHAR) );
  1563. ProcessVideoDevice_return:
  1564. //
  1565. // Cleanup.
  1566. //
  1567. if(NULL != hkDeviceData){
  1568. RegCloseKey(hkDeviceData);
  1569. }
  1570. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessVideoDevice: Leaving... Ret=VOID.\r\n")));
  1571. return;
  1572. } // CDevice::ProcessVideoDevice()
  1573. VOID
  1574. CDevice::ProcessEventsSection(
  1575. HINF hInf,
  1576. HKEY hkDrv
  1577. )
  1578. /*++
  1579. Routine Description:
  1580. Arguments:
  1581. Return Value:
  1582. Side effects:
  1583. --*/
  1584. {
  1585. CString csFriendlyName;
  1586. CString csRegisteredApp;
  1587. CString csGuid;
  1588. HKEY hkEvents;
  1589. HKEY hkEventPod;
  1590. INFCONTEXT InfContext;
  1591. UINT uiLineIndex = 0;
  1592. BOOL fRet = TRUE;
  1593. BOOL fLooping = TRUE;
  1594. TCHAR pKeyName[LINE_LEN ];
  1595. TCHAR pField [MAX_INF_STRING_LENGTH];
  1596. TCHAR pTypeField[LINE_LEN];
  1597. DWORD dwKeySize = LINE_LEN;
  1598. DWORD dwFieldSize = MAX_INF_STRING_LENGTH;
  1599. DWORD dwError = 0;
  1600. DWORD dwFieldIndex = 0;
  1601. DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessEventsSection: Enter... \r\n")));
  1602. if (!m_csEventSection.IsEmpty()) {
  1603. // First create device data subkey
  1604. dwError = RegCreateKey(hkDrv, EVENTS, &hkEvents);
  1605. if ( NOERROR == dwError ) {
  1606. fLooping = SetupFindFirstLine(hInf,
  1607. (LPCTSTR) m_csEventSection,
  1608. NULL,
  1609. &InfContext
  1610. );
  1611. while (fLooping) {
  1612. ::ZeroMemory(pKeyName, sizeof(pKeyName));
  1613. ::ZeroMemory(pField, sizeof(pField));
  1614. ::ZeroMemory(pTypeField, sizeof(pTypeField) );
  1615. // Get key name as zero-based indexed field
  1616. dwFieldIndex = 0;
  1617. dwKeySize = sizeof(pKeyName) / sizeof(TCHAR);
  1618. fRet = SetupGetStringField(&InfContext,
  1619. dwFieldIndex,
  1620. pKeyName,
  1621. dwKeySize,
  1622. NULL);
  1623. dwError = ::GetLastError();
  1624. if (!fRet) {
  1625. // Didn't get key name - move to the next
  1626. DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get key name. Error=0x%x. \r\n"), dwError));
  1627. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1628. continue;
  1629. }
  1630. // Get friendly name field
  1631. dwFieldIndex = 1;
  1632. dwFieldSize = sizeof(pField) / sizeof(TCHAR);
  1633. fRet = SetupGetStringField(&InfContext,
  1634. dwFieldIndex,
  1635. pField,
  1636. dwFieldSize,
  1637. NULL);
  1638. dwError = ::GetLastError();
  1639. if (!fRet ) {
  1640. // Didn't get name - move to the next
  1641. DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError));
  1642. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1643. continue;
  1644. }
  1645. csFriendlyName = pField;
  1646. // Get GUID field
  1647. dwFieldIndex = 2;
  1648. dwFieldSize = sizeof(pField) / sizeof(TCHAR);
  1649. fRet = SetupGetStringField(&InfContext,
  1650. dwFieldIndex,
  1651. pField,
  1652. dwFieldSize,
  1653. NULL);
  1654. dwError = ::GetLastError();
  1655. if (!fRet ) {
  1656. // Didn't get GUID - move to the next line
  1657. DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError));
  1658. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1659. continue;
  1660. }
  1661. csGuid = pField;
  1662. // Get registered app field
  1663. dwFieldIndex = 3;
  1664. dwFieldSize = sizeof(pField) / sizeof(TCHAR);
  1665. fRet = SetupGetStringField(&InfContext,
  1666. 3,
  1667. pField,
  1668. dwFieldSize,
  1669. NULL);
  1670. dwError = ::GetLastError();
  1671. if (fRet ) {
  1672. // DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError));
  1673. csRegisteredApp = pField;
  1674. }
  1675. else {
  1676. // Didn't get key type - use widlcard by default
  1677. csRegisteredApp = TEXT("*");
  1678. }
  1679. // Now only if we have all needed values - save to the registry
  1680. if (RegCreateKey(hkEvents, pKeyName, &hkEventPod) == NO_ERROR) {
  1681. // Event friendly name store as default value
  1682. csFriendlyName.Store (hkEventPod, TEXT(""));
  1683. csGuid.Store (hkEventPod, SZ_GUID);
  1684. csRegisteredApp.Store (hkEventPod, LAUNCH_APP);
  1685. RegCloseKey (hkEventPod);
  1686. } else {
  1687. // Couldn't create event key - bad
  1688. DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Unable to create RegKey. Error=0x%x.\r\n"), GetLastError()));
  1689. }
  1690. // Move to the next line finally
  1691. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1692. }
  1693. RegCloseKey (hkEvents);
  1694. } else {
  1695. DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Unable to create event RegKey. Error=0x%x.\r\n"), GetLastError()));
  1696. }
  1697. }
  1698. // ProcessEventsSection_return:
  1699. //
  1700. // Cleanup.
  1701. //
  1702. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessEventsSection: Leaving... Ret=VOID.\r\n")));
  1703. return;
  1704. } // CDevice::ProcessEventsSection()
  1705. VOID
  1706. CDevice::ProcessDataSection(
  1707. HINF hInf,
  1708. HKEY hkDrv
  1709. )
  1710. /*++
  1711. Routine Description:
  1712. Arguments:
  1713. Return Value:
  1714. Side effects:
  1715. --*/
  1716. {
  1717. CString csTempValue;
  1718. HKEY hkDeviceData;
  1719. INFCONTEXT InfContext;
  1720. BOOL fRet;
  1721. BOOL fLooping;
  1722. TCHAR pKeyName[LINE_LEN];
  1723. TCHAR pField[MAX_INF_STRING_LENGTH];
  1724. TCHAR pTypeField[LINE_LEN];
  1725. UINT uiLineIndex;
  1726. DWORD dwKeySize;
  1727. DWORD dwFieldSize;
  1728. DWORD dwError;
  1729. DWORD dwFieldIndex;
  1730. PSECURITY_DESCRIPTOR pSecurityDescriptor;
  1731. BOOL bDaclExisting;
  1732. BOOL bDaclDefaulted;
  1733. PACL pDacl;
  1734. DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessDataSection: Enter... \r\n")));
  1735. //
  1736. // Initialize local.
  1737. //
  1738. hkDeviceData = (HKEY)INVALID_HANDLE_VALUE;
  1739. uiLineIndex = 0;
  1740. fRet = TRUE;
  1741. fLooping = TRUE;
  1742. dwKeySize = LINE_LEN;
  1743. dwFieldSize = MAX_INF_STRING_LENGTH;
  1744. dwError = 0;
  1745. dwFieldIndex = 0;
  1746. pSecurityDescriptor = NULL;
  1747. pDacl = NULL;
  1748. bDaclExisting = FALSE;
  1749. bDaclDefaulted = FALSE;
  1750. memset(&InfContext, 0, sizeof(InfContext));
  1751. memset(pKeyName, 0, sizeof(pKeyName));
  1752. memset(pField, 0, sizeof(pField));
  1753. memset(pTypeField, 0, sizeof(pTypeField));
  1754. if (!m_csDataSection.IsEmpty()) {
  1755. // First create device data subkey
  1756. dwError = RegCreateKey(hkDrv, DEVICESECTION, &hkDeviceData);
  1757. if ( NOERROR == dwError ) {
  1758. //
  1759. // Get a DACL for LS full access.
  1760. //
  1761. fRet = ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("D:(A;CIOI;GA;;;LS)"),
  1762. SDDL_REVISION_1,
  1763. &pSecurityDescriptor,
  1764. NULL);
  1765. if( (TRUE != fRet)
  1766. || (NULL == pSecurityDescriptor) )
  1767. {
  1768. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Unable to get SD. Err=0x%x.\r\n"),GetLastError()));
  1769. goto ProcessDataSection_return;
  1770. } // if( (TRUE != fRet) || (NULL == pSecurityDescriptor)
  1771. if(!GetSecurityDescriptorDacl(pSecurityDescriptor,
  1772. &bDaclExisting,
  1773. &pDacl,
  1774. &bDaclDefaulted))
  1775. {
  1776. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: GetSecurityDescriptorDacl() failed. Err=0x%x.\r\n"),GetLastError()));
  1777. goto ProcessDataSection_return;
  1778. } // if(!GetSecurityDescriptorDacl()
  1779. //
  1780. // Add LocalService to ACL.
  1781. //
  1782. dwError = SetSecurityInfo(hkDeviceData,
  1783. SE_REGISTRY_KEY,
  1784. DACL_SECURITY_INFORMATION,
  1785. NULL,
  1786. NULL,
  1787. pDacl,
  1788. NULL);
  1789. if(ERROR_SUCCESS != dwError){
  1790. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Failed to get key name. Error = 0x%x.\r\n"),dwError));
  1791. goto ProcessDataSection_return;
  1792. } // if(ERROR_SUCCESS != dwError)
  1793. // Seek to the first line of the section
  1794. fLooping = SetupFindFirstLine(hInf,
  1795. (LPCTSTR) m_csDataSection,
  1796. NULL,
  1797. &InfContext);
  1798. while (fLooping) {
  1799. dwKeySize = sizeof(pKeyName) / sizeof(TCHAR);
  1800. ::ZeroMemory(pKeyName, sizeof(pKeyName));
  1801. ::ZeroMemory(pField, sizeof(pField));
  1802. ::ZeroMemory(pTypeField, sizeof(pTypeField) );
  1803. dwFieldIndex = 0;
  1804. // Get key name as zero-indexed field
  1805. fRet = SetupGetStringField(&InfContext,
  1806. dwFieldIndex,
  1807. pKeyName,
  1808. dwKeySize,
  1809. &dwKeySize);
  1810. dwError = ::GetLastError();
  1811. if (!fRet) {
  1812. // Didn't get key name - move to the next
  1813. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Failed to get key name. Error = 0x%x.\r\n"),dwError));
  1814. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1815. continue;
  1816. }
  1817. // Get value field
  1818. dwFieldIndex = 1;
  1819. dwFieldSize = sizeof(pField) / sizeof(TCHAR);
  1820. fRet = SetupGetStringField(&InfContext,
  1821. dwFieldIndex,
  1822. pField,
  1823. dwFieldSize,
  1824. NULL);
  1825. dwError = ::GetLastError();
  1826. if (!fRet ) {
  1827. // Didn't get key name - move to the next
  1828. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Failed to get field [%d]. Error = 0x%x.\r\n"),dwFieldIndex, dwError));
  1829. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1830. continue;
  1831. }
  1832. csTempValue = pField;
  1833. // Get value field
  1834. *pTypeField = TEXT('\0');
  1835. dwFieldIndex = 2;
  1836. dwFieldSize = sizeof(pTypeField) / sizeof(TCHAR);
  1837. fRet = SetupGetStringField(&InfContext,
  1838. dwFieldIndex,
  1839. pTypeField,
  1840. dwFieldSize,
  1841. NULL);
  1842. dwError = ::GetLastError();
  1843. if (!fRet ) {
  1844. // Didn't get key type - assume string
  1845. *pTypeField = TEXT('\0');
  1846. }
  1847. // Now we have both type and value - save it in the registry
  1848. csTempValue.Store (hkDeviceData, pKeyName,pTypeField );
  1849. // Move to the next line finally
  1850. fLooping = SetupFindNextLine(&InfContext,&InfContext);
  1851. }
  1852. //
  1853. // Process migrating DeviceData section.
  1854. //
  1855. MigrateDeviceData(hkDeviceData, m_pExtraDeviceData, "");
  1856. // Now clean up
  1857. RegCloseKey (hkDeviceData);
  1858. hkDeviceData = (HKEY)INVALID_HANDLE_VALUE;
  1859. } else { // if ( NOERROR == dwError )
  1860. DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: ERROR!! Unable to create DataSection RegKey. Error = 0x%x.\r\n"), dwError));
  1861. } // if ( NOERROR == dwError )
  1862. } // if (!m_csDataSection.IsEmpty())
  1863. ProcessDataSection_return:
  1864. //
  1865. // Cleanup.
  1866. //
  1867. if(IS_VALID_HANDLE(hkDeviceData)){
  1868. RegCloseKey(hkDeviceData);
  1869. hkDeviceData = (HKEY)INVALID_HANDLE_VALUE;
  1870. } // if(IS_VALID_HANDLE(hkDeviceData))
  1871. if(NULL != pSecurityDescriptor){
  1872. LocalFree(pSecurityDescriptor);
  1873. pSecurityDescriptor = NULL;
  1874. } // if(NULL != pSecurityDescriptor))
  1875. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessDataSection: Leaving... Ret=VOID.\r\n")));
  1876. return;
  1877. } // CDevice::ProcessDataSection()
  1878. VOID
  1879. CDevice::ProcessICMProfiles(
  1880. VOID
  1881. )
  1882. /*++
  1883. Routine Description:
  1884. Arguments:
  1885. Return Value:
  1886. Side effects:
  1887. --*/
  1888. {
  1889. DWORD Idx;
  1890. CStringArray csaICMProfiles;
  1891. TCHAR szAnsiName[STI_MAX_INTERNAL_NAME_LENGTH];
  1892. DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessICMProfiles: Enter... \r\n")));
  1893. //
  1894. // Initialize Local.
  1895. //
  1896. Idx = 0;
  1897. memset(szAnsiName, 0, sizeof(szAnsiName));
  1898. //
  1899. // If section doesn't exist, just return.
  1900. //
  1901. if(m_csIcmProfile.IsEmpty()){
  1902. goto ProcessICMProfiles_return;
  1903. }
  1904. //
  1905. // Split a line to each token.
  1906. //
  1907. csaICMProfiles.Tokenize ((LPTSTR)m_csIcmProfile, FIELD_DELIMETER);
  1908. //
  1909. // Process all ICM profiles.
  1910. //
  1911. while ((LPTSTR)csaICMProfiles[Idx] != NULL) {
  1912. DebugTrace(TRACE_STATUS,(("ProcessICMProfiles: Installing ICM profile%d(%ws) for %ws.\r\n"), Idx, (LPTSTR)csaICMProfiles[Idx], (LPTSTR)m_csDeviceID));
  1913. //
  1914. // Install color profile.
  1915. //
  1916. if (!InstallColorProfile (NULL, csaICMProfiles[Idx])) {
  1917. DebugTrace(TRACE_ERROR,(("ProcessICMProfiles: ERROR!! InstallColorProfile failed. Err=0x%x \r\n"), GetLastError()));
  1918. } // if (!InstallColorProfile (NULL, csaICMProfiles[Idx]))
  1919. //
  1920. // Register color profile with installing device.
  1921. //
  1922. if (!AssociateColorProfileWithDevice (NULL, csaICMProfiles[Idx], (LPTSTR)m_csDeviceID)) {
  1923. DebugTrace(TRACE_ERROR,(("ProcessICMProfiles: ERROR!! AssociateColorProfileWithDevice failed. Err=0x%x \r\n"), GetLastError())); }
  1924. //
  1925. // Process next device.
  1926. //
  1927. Idx++;
  1928. } // while ((LPTSTR)csaICMProfiles[Idx] != NULL)
  1929. ProcessICMProfiles_return:
  1930. return;
  1931. } // CDevice::ProcessICMProfiles()
  1932. BOOL
  1933. CDevice::GetInfInforamtion(
  1934. VOID
  1935. )
  1936. {
  1937. BOOL bRet;
  1938. HINF hInf;
  1939. SP_DRVINFO_DATA DriverInfoData;
  1940. PSP_DRVINFO_DETAIL_DATA pDriverInfoDetailData;
  1941. TCHAR szInfSectionName[MAX_DESCRIPTION];
  1942. DWORD dwSize;
  1943. DWORD dwLastError;
  1944. DebugTrace(TRACE_PROC_ENTER,(("CDevice::GetInfInforamtion: Enter... \r\n")));
  1945. //
  1946. // Initialize locals.
  1947. //
  1948. dwSize = 0;
  1949. bRet = FALSE;
  1950. hInf = INVALID_HANDLE_VALUE;
  1951. dwLastError = ERROR_SUCCESS;
  1952. pDriverInfoDetailData = NULL;
  1953. memset (szInfSectionName, 0, sizeof(szInfSectionName));
  1954. memset (&DriverInfoData, 0, sizeof(SP_DRVINFO_DATA));
  1955. //
  1956. // Get selected device driver information.
  1957. //
  1958. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  1959. if (!SetupDiGetSelectedDriver(m_hDevInfo, m_pspDevInfoData, &DriverInfoData)) {
  1960. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetSelectedDriver Failed. Err=0x%x\r\n"), GetLastError()));
  1961. bRet = FALSE;
  1962. goto GetInfInforamtion_return;
  1963. }
  1964. //
  1965. // See required buffer size for driver detailed data.
  1966. //
  1967. SetupDiGetDriverInfoDetail(m_hDevInfo,
  1968. m_pspDevInfoData,
  1969. &DriverInfoData,
  1970. NULL,
  1971. 0,
  1972. &dwSize);
  1973. dwLastError = GetLastError();
  1974. if(ERROR_INSUFFICIENT_BUFFER != dwLastError){
  1975. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetDriverInfoDetail doesn't return required size.Er=0x%x\r\n"),dwLastError));
  1976. bRet = FALSE;
  1977. goto GetInfInforamtion_return;
  1978. }
  1979. //
  1980. // Allocate required size of buffer for driver detailed data.
  1981. //
  1982. pDriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)new char[dwSize];
  1983. if(NULL == pDriverInfoDetailData){
  1984. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! Unable to allocate driver detailed info buffer.\r\n")));
  1985. bRet = FALSE;
  1986. goto GetInfInforamtion_return;
  1987. }
  1988. //
  1989. // Initialize allocated buffer.
  1990. //
  1991. memset(pDriverInfoDetailData, 0, dwSize);
  1992. pDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  1993. //
  1994. // Get detailed data of selected device driver.
  1995. //
  1996. if(!SetupDiGetDriverInfoDetail(m_hDevInfo,
  1997. m_pspDevInfoData,
  1998. &DriverInfoData,
  1999. pDriverInfoDetailData,
  2000. dwSize,
  2001. NULL) )
  2002. {
  2003. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetDriverInfoDetail Failed.Er=0x%x\r\n"),GetLastError()));
  2004. bRet = FALSE;
  2005. goto GetInfInforamtion_return;
  2006. }
  2007. //
  2008. // Open INF file of selected driver.
  2009. //
  2010. hInf = SetupOpenInfFile(pDriverInfoDetailData->InfFileName,
  2011. NULL,
  2012. INF_STYLE_WIN4,
  2013. NULL);
  2014. if (hInf == INVALID_HANDLE_VALUE) {
  2015. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupOpenInfFile Failed.Er=0x%x\r\n"),GetLastError()));
  2016. bRet = FALSE;
  2017. goto GetInfInforamtion_return;
  2018. }
  2019. //
  2020. // Get actual INF section name to be installed.
  2021. //
  2022. if (!SetupDiGetActualSectionToInstall(hInf,
  2023. pDriverInfoDetailData->SectionName,
  2024. szInfSectionName,
  2025. sizeof(szInfSectionName)/sizeof(TCHAR),
  2026. NULL,
  2027. NULL) )
  2028. {
  2029. DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetActualSectionToInstall Failed.Er=0x%x\r\n"),GetLastError()));
  2030. bRet = FALSE;
  2031. goto GetInfInforamtion_return;
  2032. }
  2033. //
  2034. // Set Inf section/file name.
  2035. //
  2036. m_csInf = pDriverInfoDetailData->InfFileName;
  2037. m_csInstallSection = szInfSectionName;
  2038. DebugTrace(TRACE_STATUS,(("CDevice::GetInfInforamtion: INF Filename : %ws\n"),(LPTSTR)m_csInf));
  2039. DebugTrace(TRACE_STATUS,(("CDevice::GetInfInforamtion: INF Section name: %ws\n"),(LPTSTR)m_csInstallSection));
  2040. //
  2041. // Operation succeeded.
  2042. //
  2043. bRet = TRUE;
  2044. GetInfInforamtion_return:
  2045. //
  2046. // Clean up.
  2047. //
  2048. if(INVALID_HANDLE_VALUE != hInf){
  2049. SetupCloseInfFile(hInf);
  2050. }
  2051. if(NULL != pDriverInfoDetailData){
  2052. delete[] pDriverInfoDetailData;
  2053. }
  2054. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::GetInfInforamtion: Leaving... Ret=0x%x\n"), bRet));
  2055. return bRet;
  2056. } // CDevice::GetInfInforamtion()
  2057. VOID
  2058. CDevice::SetPort(
  2059. LPTSTR szPortName
  2060. )
  2061. {
  2062. DebugTrace(TRACE_STATUS,(("CDevice::SetPort: Current Portname=%ws\n"), szPortName));
  2063. //
  2064. // Set PortName.
  2065. //
  2066. m_csPort = szPortName;
  2067. } // CDevice::SetPort()
  2068. VOID
  2069. CDevice::SetFriendlyName(
  2070. LPTSTR szFriendlyName
  2071. )
  2072. //
  2073. // Note:
  2074. // Before calling this function, caller has to make sure mutex is acquired.
  2075. //
  2076. {
  2077. HKEY hkNameStore;
  2078. //
  2079. // Mutex must have been acquired before this call.
  2080. //
  2081. DebugTrace(TRACE_STATUS,(("CDevice::SetFriendlyName: Current CreateFileName=%ws\n"), szFriendlyName));
  2082. //
  2083. // Delete stored entry, create new one.
  2084. //
  2085. if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){
  2086. HKEY hkTemp;
  2087. hkTemp = (HKEY)INVALID_HANDLE_VALUE;
  2088. //
  2089. // Delete FriendlyName and DeviceId in name store.
  2090. //
  2091. RegDeleteKey(hkNameStore, m_csFriendlyName);
  2092. if(ERROR_SUCCESS == RegCreateKey(hkNameStore, szFriendlyName, &hkTemp)){
  2093. RegCloseKey(hkTemp);
  2094. } // if(ERROR_SUCCESS == RegCreateKey(hkNameStore, szFriendlyName, &hkTemp))
  2095. RegCloseKey(hkNameStore);
  2096. } // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
  2097. //
  2098. // Set PortName.
  2099. //
  2100. m_csFriendlyName = szFriendlyName;
  2101. } // CDevice::SetPort()
  2102. VOID
  2103. CDevice::SetDevnodeSelectCallback(
  2104. DEVNODESELCALLBACK pfnDevnodeSelCallback
  2105. )
  2106. {
  2107. DebugTrace(TRACE_STATUS,(("CDevice::SetDevnodeSelectCallback: Current PortselCallback=0x%x\n"), pfnDevnodeSelCallback));
  2108. //
  2109. // Set SetPortselCallBack.
  2110. //
  2111. m_pfnDevnodeSelCallback = pfnDevnodeSelCallback;
  2112. //
  2113. // This is "interface-only" device.
  2114. //
  2115. m_bInterfaceOnly = TRUE;
  2116. } // CDevice::SetDevnodeSelectCallback()
  2117. BOOL
  2118. CDevice::CreateDeviceInterfaceAndInstall(
  2119. VOID
  2120. )
  2121. {
  2122. BOOL bRet;
  2123. HKEY hkDrv;
  2124. GUID Guid;
  2125. HDEVINFO hDevInfo;
  2126. SP_DEVINFO_DATA spDevInfoData;
  2127. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  2128. PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData;
  2129. HINF hInf;
  2130. BOOL bUseDefaultDevInfoSet;
  2131. DWORD dwRequiredSize;
  2132. DebugTrace(TRACE_PROC_ENTER,(("CDevice::CreateDeviceInterfaceAndInstall: Enter....\r\n")));
  2133. //
  2134. // Initialize local.
  2135. //
  2136. bRet = FALSE;
  2137. hInf = INVALID_HANDLE_VALUE;
  2138. hDevInfo = INVALID_HANDLE_VALUE;
  2139. Guid = GUID_DEVCLASS_IMAGE;
  2140. bUseDefaultDevInfoSet = TRUE;
  2141. dwRequiredSize = 0;
  2142. pspDevInterfaceDetailData = NULL;
  2143. //
  2144. // Get devnode to create interface on.
  2145. //
  2146. if(NULL != m_pfnDevnodeSelCallback){
  2147. if( (FALSE == m_pfnDevnodeSelCallback(m_csPort, &hDevInfo, &spDevInfoData))
  2148. || (INVALID_HANDLE_VALUE == hDevInfo) )
  2149. {
  2150. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: m_pfnDevnodeSelCallback failed. Err=0x%x.\r\n"),GetLastError()));
  2151. bRet = FALSE;
  2152. goto CreateDeviceInterfaceAndInstall_return;
  2153. }
  2154. //
  2155. // Devnode selector functions.
  2156. //
  2157. bUseDefaultDevInfoSet = FALSE;
  2158. } else { // if(NULL != m_pfnDevnodeSelCallback)
  2159. //
  2160. // Use default device info set if available.
  2161. //
  2162. if( (INVALID_HANDLE_VALUE == m_hDevInfo)
  2163. || (NULL == m_pspDevInfoData) )
  2164. {
  2165. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Invalid Device info and no m_pfnDevnodeSelCallback.\r\n")));
  2166. bRet = FALSE;
  2167. goto CreateDeviceInterfaceAndInstall_return;
  2168. } else {
  2169. hDevInfo = m_hDevInfo;
  2170. spDevInfoData = *m_pspDevInfoData;
  2171. }
  2172. } // if(NULL != m_pfnDevnodeSelCallback)
  2173. //
  2174. // Create Interface (SoftDevice). Use FriendlyName ad ref-string.
  2175. //
  2176. DebugTrace(TRACE_STATUS,(("CDevice::CreateDeviceInterfaceAndInstall: Creating interface for %ws.\r\n"), (LPTSTR)m_csFriendlyName));
  2177. spDevInterfaceData.cbSize = sizeof(spDevInterfaceData);
  2178. if(!SetupDiCreateDeviceInterface(hDevInfo,
  2179. &spDevInfoData,
  2180. &Guid,
  2181. m_csFriendlyName,
  2182. 0,
  2183. &spDevInterfaceData))
  2184. {
  2185. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiCreateInterface failed. Err=0x%x.\r\n"),GetLastError()));
  2186. bRet = FALSE;
  2187. goto CreateDeviceInterfaceAndInstall_return;
  2188. }
  2189. //
  2190. // Get symbolic link of created interface.
  2191. //
  2192. SetupDiGetDeviceInterfaceDetail(hDevInfo,
  2193. &spDevInterfaceData,
  2194. NULL,
  2195. 0,
  2196. &dwRequiredSize,
  2197. NULL);
  2198. if(0 == dwRequiredSize){
  2199. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Unable to get required size for InterfaceDetailedData. Err=0x%x.\r\n"),GetLastError()));
  2200. bRet = FALSE;
  2201. goto CreateDeviceInterfaceAndInstall_return;
  2202. } // if(0 == dwRequiredSize)
  2203. pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)new BYTE[dwRequiredSize];
  2204. if(NULL == pspDevInterfaceDetailData){
  2205. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Unable to allocate buffer.\r\n")));
  2206. bRet = FALSE;
  2207. goto CreateDeviceInterfaceAndInstall_return;
  2208. } // if(NULL == pspDevInterfaceDetailData)
  2209. pspDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  2210. if(!SetupDiGetDeviceInterfaceDetail(hDevInfo,
  2211. &spDevInterfaceData,
  2212. pspDevInterfaceDetailData,
  2213. dwRequiredSize,
  2214. &dwRequiredSize,
  2215. NULL))
  2216. {
  2217. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiGetDeviceInterfaceDetail() failed. Err=0x%x.\r\n"),GetLastError()));
  2218. bRet = FALSE;
  2219. goto CreateDeviceInterfaceAndInstall_return;
  2220. } // if(!SetupDiGetDeviceInterfaceDetail(
  2221. m_csSymbolicLink = pspDevInterfaceDetailData->DevicePath;
  2222. //
  2223. // Open INF file handle for registry creation.
  2224. //
  2225. hInf = SetupOpenInfFile(m_csInf,
  2226. NULL,
  2227. INF_STYLE_WIN4,
  2228. NULL);
  2229. if(INVALID_HANDLE_VALUE == hInf){
  2230. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupOpenInfFile failed. Err=0x%x.\r\n"),GetLastError()));
  2231. bRet = FALSE;
  2232. goto CreateDeviceInterfaceAndInstall_return;
  2233. } // if(INVALID_HANDLE_VALUE == hInf)
  2234. if(!SetupOpenAppendInfFile(NULL, hInf, NULL)){
  2235. DebugTrace(TRACE_WARNING,(("CDevice::CreateDeviceInterfaceAndInstall: SetupOpenAppendInfFile() failed. Err=0x%x.\r\n"),GetLastError()));
  2236. } // if(!SetupOpenAppendInfFile(NULL, hInf, NULL))
  2237. //
  2238. // Create Interface Registry and keep its handle, it's hard to find it later.
  2239. //
  2240. m_hkInterfaceRegistry = SetupDiCreateDeviceInterfaceRegKey(hDevInfo,
  2241. &spDevInterfaceData,
  2242. 0,
  2243. KEY_ALL_ACCESS,
  2244. // NULL,
  2245. // NULL);
  2246. hInf,
  2247. (LPCTSTR)m_csInstallSection);
  2248. if(INVALID_HANDLE_VALUE == m_hkInterfaceRegistry){
  2249. DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiCreateDeviceInterfaceRegKey failed. Err=0x%x.\r\n"),GetLastError()));
  2250. bRet = FALSE;
  2251. goto CreateDeviceInterfaceAndInstall_return;
  2252. } // if(INVALID_HANDLE_VALUE == m_hkInterfaceRegistry)
  2253. //
  2254. // Operation succeeded.
  2255. //
  2256. bRet = TRUE;
  2257. CreateDeviceInterfaceAndInstall_return:
  2258. //
  2259. // Clean up.
  2260. //
  2261. if(INVALID_HANDLE_VALUE != hDevInfo){
  2262. if(FALSE == bUseDefaultDevInfoSet){
  2263. //
  2264. // Destroy created DevInfoSet.
  2265. //
  2266. SetupDiDestroyDeviceInfoList(hDevInfo);
  2267. } // if(FALSE == bUseDefaultDevInfoSet)
  2268. } // if(INVALID_HANDLE_VALUE != hDevInfo)
  2269. if(INVALID_HANDLE_VALUE != hInf){
  2270. SetupCloseInfFile(hInf);
  2271. } // if(INVALID_HANDLE_VALUE != hInf)
  2272. if(NULL != pspDevInterfaceDetailData){
  2273. delete[] pspDevInterfaceDetailData;
  2274. } // if(NULL != pspDevInterfaceDetailData)
  2275. DebugTrace(TRACE_PROC_LEAVE,(("CDevice::CreateDeviceInterfaceAndInstall: Leaving... Ret=0x%x.\r\n"), bRet));
  2276. return bRet;
  2277. } // CDevice::CreateDeviceInterfaceAndInstall()
  2278. DWORD
  2279. CDevice::GetPortSelectMode(
  2280. VOID
  2281. )
  2282. {
  2283. DWORD dwRet;
  2284. //
  2285. // Initialize local.
  2286. //
  2287. dwRet = PORTSELMODE_NORMAL;
  2288. //
  2289. // Make sure INF is processed.
  2290. //
  2291. if(!PreprocessInf()){
  2292. DebugTrace(TRACE_ERROR,(("CDevice::GetPortSelectMode: ERROR!! Unable to process INF.\r\n")));
  2293. dwRet = PORTSELMODE_NORMAL;
  2294. goto GetPortSelectMode_return;
  2295. }
  2296. //
  2297. // If "PortSelect" is empty, use default.
  2298. //
  2299. if(m_csPortSelect.IsEmpty()){
  2300. dwRet = PORTSELMODE_NORMAL;
  2301. goto GetPortSelectMode_return;
  2302. } // if(m_csPortSelect.IsEmpty())
  2303. //
  2304. // See if "PortSelect" directive is "no".
  2305. //
  2306. if(0 == MyStrCmpi(m_csPortSelect, NO)){
  2307. //
  2308. // Port Selection page should be skipped.
  2309. //
  2310. dwRet = PORTSELMODE_SKIP;
  2311. } else if(0 == MyStrCmpi(m_csPortSelect, MESSAGE1)){
  2312. //
  2313. // System supplied message should be shown.
  2314. //
  2315. dwRet = PORTSELMODE_MESSAGE1;
  2316. } else {
  2317. //
  2318. // Unsupported PortSel option.
  2319. //
  2320. dwRet = PORTSELMODE_NORMAL;
  2321. }
  2322. GetPortSelectMode_return:
  2323. return dwRet;
  2324. } // CDevice::GetPortSelectMode()
  2325. DWORD
  2326. CDevice::AcquireInstallerMutex(
  2327. DWORD dwTimeout
  2328. )
  2329. {
  2330. DWORD dwReturn;
  2331. //
  2332. // Initialize local.
  2333. //
  2334. dwReturn = ERROR_SUCCESS;
  2335. if(NULL != m_hMutex){
  2336. //
  2337. // Mutex is already acquired.
  2338. //
  2339. DebugTrace(TRACE_WARNING,("WARNING!! AcquireInstallerMutex: Mutex acquired twice.\r\n"));
  2340. dwReturn = ERROR_SUCCESS;
  2341. goto AcquireInstallerMutex_return;
  2342. } // if(INVALID_HANDLE_VALUE != m_hMutex)
  2343. //
  2344. // Acquire Mutex.
  2345. //
  2346. m_hMutex = CreateMutex(NULL, FALSE, WIAINSTALLERMUTEX);
  2347. dwReturn = GetLastError();
  2348. if(NULL == m_hMutex){
  2349. //
  2350. // CreteMutex() failed.
  2351. //
  2352. DebugTrace(TRACE_ERROR,("ERROR!! AcquireInstallerMutex: CraeteMutex() failed. Err=0x%x.\r\n", dwReturn));
  2353. goto AcquireInstallerMutex_return;
  2354. } // if(NULL == hMutex)
  2355. //
  2356. // Wait until ownership is acquired.
  2357. //
  2358. dwReturn = WaitForSingleObject(m_hMutex, dwTimeout);
  2359. switch(dwReturn){
  2360. case WAIT_ABANDONED:
  2361. DebugTrace(TRACE_ERROR, ("CDevice::AcquireInstallerMutex: ERROR!! Wait abandoned.\r\n"));
  2362. break;
  2363. case WAIT_OBJECT_0:
  2364. DebugTrace(TRACE_STATUS, ("CDevice::AcquireInstallerMutex: Mutex acquired.\r\n"));
  2365. dwReturn = ERROR_SUCCESS;
  2366. break;
  2367. case WAIT_TIMEOUT:
  2368. DebugTrace(TRACE_WARNING, ("CDevice::AcquireInstallerMutex: WARNING!! Mutex acquisition timeout.\r\n"));
  2369. break;
  2370. default:
  2371. DebugTrace(TRACE_ERROR, ("CDevice::AcquireInstallerMutex: ERROR!! Unexpected error from WaitForSingleObjecct(). Err=0x%x.\r\n", dwReturn));
  2372. break;
  2373. } // switch(dwReturn)
  2374. AcquireInstallerMutex_return:
  2375. DebugTrace(TRACE_PROC_LEAVE,("CDevice::AcquireInstallerMutex: Leaving... Ret=0x%x\n", dwReturn));
  2376. return dwReturn;
  2377. } // CDevice::AcquireInstallerMutex()
  2378. VOID
  2379. CDevice::ReleaseInstallerMutex(
  2380. )
  2381. {
  2382. if(NULL != m_hMutex){
  2383. if(!ReleaseMutex(m_hMutex)){
  2384. DebugTrace(TRACE_ERROR, ("CDevice::ReleaseInstallerMutex: ERROR!! Releasing mutex which not owned..\r\n"));
  2385. } // if(!ReleaseMutex(m_hMutex))
  2386. CloseHandle(m_hMutex);
  2387. m_hMutex = NULL;
  2388. DebugTrace(TRACE_STATUS, ("CDevice::ReleaseInstallerMutex: Mutex released.\r\n"));
  2389. } // if(NULL != m_hMutex)
  2390. } // CDevice::ReleaseInstallerMutex()
  2391. UINT
  2392. CALLBACK
  2393. StiInstallCallback (
  2394. PVOID Context,
  2395. UINT Notification,
  2396. UINT_PTR Param1,
  2397. UINT_PTR Param2
  2398. )
  2399. /*++
  2400. Routine Description:
  2401. StiInstallCallback
  2402. Callback routine used when calling SetupAPI file copying/installation functions
  2403. Arguments:
  2404. Context - our context
  2405. Notification - notification message
  2406. Return Value:
  2407. SetupAPI return code
  2408. Side effects:
  2409. None
  2410. --*/
  2411. {
  2412. UINT uRet = FILEOP_COPY;
  2413. DebugTrace(TRACE_PROC_ENTER,(("StiInstallCallback: Enter... \r\n")));
  2414. //
  2415. // Initialize local.
  2416. //
  2417. uRet = FILEOP_COPY;
  2418. //
  2419. // Dispatch notification code.
  2420. //
  2421. switch(Notification){
  2422. case SPFILENOTIFY_ENDCOPY:
  2423. {
  2424. PFILEPATHS pFilePathInfo;
  2425. HKEY hKey;
  2426. DWORD dwDisposition;
  2427. DWORD dwRefCount;
  2428. DWORD dwType;
  2429. UINT uSize;
  2430. LONG Status;
  2431. uSize = sizeof(dwRefCount);
  2432. pFilePathInfo = (PFILEPATHS)Param1;
  2433. DebugTrace(TRACE_STATUS,(("StiInstallCallback:ENDCOPY FileTarget %ws\r\n"), pFilePathInfo->Target));
  2434. //
  2435. // Open HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls
  2436. //
  2437. Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  2438. REGSTR_PATH_SHAREDDLL,
  2439. 0,
  2440. NULL,
  2441. REG_OPTION_NON_VOLATILE,
  2442. KEY_ALL_ACCESS,
  2443. NULL,
  2444. &hKey,
  2445. &dwDisposition);
  2446. if(ERROR_SUCCESS != Status)
  2447. {
  2448. DebugTrace(TRACE_ERROR,(("StiInstallCallback: RegCreateKeyEx failed. Err=0x%x\r\n"), Status));
  2449. break;
  2450. }
  2451. //
  2452. // Retrieve reference count of this file
  2453. //
  2454. Status = RegQueryValueEx(hKey,
  2455. pFilePathInfo->Target,
  2456. NULL,
  2457. &dwType,
  2458. (LPBYTE)&dwRefCount,
  2459. (LPDWORD)&uSize);
  2460. if(ERROR_SUCCESS != Status)
  2461. {
  2462. //
  2463. // Value for this file hasn't been created, or error
  2464. //
  2465. DebugTrace(TRACE_ERROR,(("StiInstallCallback: Value for Ref-count doesn't exist\r\n")));
  2466. dwRefCount = 0;
  2467. }
  2468. //
  2469. // Increment reference count and set value
  2470. //
  2471. dwRefCount++;
  2472. uSize = sizeof(dwRefCount);
  2473. Status = RegSetValueEx(hKey,
  2474. pFilePathInfo->Target,
  2475. NULL,
  2476. REG_DWORD,
  2477. (CONST BYTE *)&dwRefCount,
  2478. uSize);
  2479. if(ERROR_SUCCESS != Status)
  2480. {
  2481. DebugTrace(TRACE_ERROR,(("StiInstallCallback: RegSetValueEx. Err=0x%x.\r\n"), Status));
  2482. }
  2483. DebugTrace(TRACE_STATUS,(("StiInstallCallback: ref-count of %ws is now 0x%x.\r\n"), pFilePathInfo->Target, dwRefCount));
  2484. //
  2485. // Close Registry key
  2486. //
  2487. RegCloseKey(hKey);
  2488. Report(( TEXT("StiInstallCallback:%ws copied.\r\n"), pFilePathInfo->Target));
  2489. } // case SPFILENOTIFY_ENDCOPY
  2490. default:
  2491. ;
  2492. }
  2493. uRet = SetupDefaultQueueCallback(Context,
  2494. Notification,
  2495. Param1,
  2496. Param2);
  2497. DebugTrace(TRACE_PROC_LEAVE,(("StiInstallCallback: Leaving... Ret=0x%x\n"), uRet));
  2498. return uRet;
  2499. }
  2500. VOID
  2501. GetDeviceCount(
  2502. DWORD *pdwWiaCount,
  2503. DWORD *pdwStiCount
  2504. )
  2505. /*++
  2506. Routine Description:
  2507. GetDeviceCount
  2508. Verifes if there is at least one STI device installed in a system
  2509. Arguments:
  2510. bWia - TRUE: Count WIA device
  2511. Return Value:
  2512. Number of WIA device
  2513. FALSE
  2514. --*/
  2515. {
  2516. DWORD dwWiaCount;
  2517. DWORD dwStiCount;
  2518. BOOL fRet;
  2519. CString csSubClass;
  2520. DWORD dwCapabilities;
  2521. GUID Guid;
  2522. UINT Idx;
  2523. DWORD dwRequired;
  2524. DWORD dwError;
  2525. HKEY hkThis;
  2526. HKEY hkRun;
  2527. HANDLE hDevInfo;
  2528. SP_DEVINFO_DATA spDevInfoData;
  2529. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  2530. DebugTrace(TRACE_PROC_ENTER,(("GetDeviceCount: Enter... \r\n")));
  2531. //
  2532. // Initialize local.
  2533. //
  2534. dwWiaCount = 0;
  2535. dwStiCount = 0;
  2536. fRet = FALSE;
  2537. Idx = 0;
  2538. dwRequired = 0;
  2539. dwError = 0;
  2540. hkThis = NULL;
  2541. hkRun = NULL;
  2542. hDevInfo = NULL;
  2543. dwCapabilities = 0;
  2544. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  2545. memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
  2546. //
  2547. // Get WIA class guid.
  2548. //
  2549. SetupDiClassGuidsFromName (CLASSNAME, &Guid, sizeof(GUID), &dwRequired);
  2550. //
  2551. // Get device info set of all WIA devices (devnode).
  2552. //
  2553. hDevInfo = SetupDiGetClassDevs (&Guid,
  2554. NULL,
  2555. NULL,
  2556. DIGCF_PROFILE
  2557. );
  2558. if (hDevInfo != INVALID_HANDLE_VALUE) {
  2559. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  2560. for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
  2561. #if DEBUG
  2562. CHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
  2563. ULONG cbData;
  2564. fRet = SetupDiGetDeviceRegistryProperty (hDevInfo,
  2565. &spDevInfoData,
  2566. SPDRP_DRIVER,
  2567. NULL,
  2568. (UCHAR *)szDevDriver, sizeof (szDevDriver),
  2569. &cbData);
  2570. DebugTrace(TRACE_STATUS,(("GetDeviceCount: Checking device No%d(%ws)\r\n"), Idx, szDevDriver));
  2571. #endif
  2572. //
  2573. // Verify device is not being removed
  2574. //
  2575. spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  2576. spDevInterfaceData.InterfaceClassGuid = GUID_DEVCLASS_IMAGE;
  2577. fRet = SetupDiEnumDeviceInterfaces (hDevInfo,
  2578. NULL,
  2579. &Guid,
  2580. Idx,
  2581. &spDevInterfaceData);
  2582. dwError = GetLastError();
  2583. if (fRet) {
  2584. if (spDevInterfaceData.Flags & SPINT_REMOVED) {
  2585. continue;
  2586. }
  2587. }
  2588. hkThis = SetupDiOpenDevRegKey(hDevInfo,
  2589. &spDevInfoData,
  2590. DICS_FLAG_GLOBAL,
  2591. 0,
  2592. DIREG_DRV,
  2593. KEY_READ );
  2594. if (hkThis != INVALID_HANDLE_VALUE) {
  2595. csSubClass.Load(hkThis, SUBCLASS);
  2596. GetDwordFromRegistry(hkThis, CAPABILITIES, &dwCapabilities);
  2597. DebugTrace(TRACE_STATUS,(("GetDeviceCount: Capabilities=0x%x\n"), dwCapabilities));
  2598. RegCloseKey(hkThis);
  2599. if( (!csSubClass.IsEmpty())
  2600. && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) )
  2601. {
  2602. //
  2603. // STI device found. Increse the counter.
  2604. //
  2605. dwStiCount++;
  2606. if(dwCapabilities & STI_GENCAP_WIA){
  2607. //
  2608. // WIA device found.
  2609. //
  2610. dwWiaCount++;
  2611. } // if(dwCapabilities & STI_GENCAP_WIA){
  2612. } // if (!csSubClass.IsEmpty() && !lstrcmpi(csSubClass, STILL_IMAGE))
  2613. } // if (hkThis != INVALID_HANDLE_VALUE)
  2614. } // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
  2615. SetupDiDestroyDeviceInfoList(hDevInfo);
  2616. } else {
  2617. DebugTrace(TRACE_ERROR,(("GetDeviceCount: ERROR!! Unable to get device info set.\r\n")));
  2618. } // if (hDevInfo != INVALID_HANDLE_VALUE)
  2619. //
  2620. // Get device info set of all WIA devices (interface).
  2621. //
  2622. hDevInfo = SetupDiGetClassDevs (&Guid,
  2623. NULL,
  2624. NULL,
  2625. DIGCF_PROFILE |
  2626. DIGCF_DEVICEINTERFACE
  2627. );
  2628. if (hDevInfo != INVALID_HANDLE_VALUE) {
  2629. spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  2630. for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
  2631. DebugTrace(TRACE_STATUS,(("GetDeviceCount: Checking interface No%d.\r\n"), Idx));
  2632. //
  2633. // Verify device is not being removed
  2634. //
  2635. if (spDevInterfaceData.Flags & SPINT_REMOVED) {
  2636. continue;
  2637. }
  2638. hkThis = SetupDiOpenDeviceInterfaceRegKey(hDevInfo,
  2639. &spDevInterfaceData,
  2640. 0,
  2641. KEY_READ );
  2642. if (hkThis != INVALID_HANDLE_VALUE) {
  2643. csSubClass.Load(hkThis, SUBCLASS);
  2644. GetDwordFromRegistry(hkThis, CAPABILITIES, &dwCapabilities);
  2645. RegCloseKey(hkThis);
  2646. if( (!csSubClass.IsEmpty())
  2647. && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) )
  2648. {
  2649. //
  2650. // STI device found. Increse the counter.
  2651. //
  2652. dwStiCount++;
  2653. if(dwCapabilities & STI_GENCAP_WIA){
  2654. //
  2655. // WIA device found.
  2656. //
  2657. dwWiaCount++;
  2658. } // if(dwCapabilities & STI_GENCAP_WIA){
  2659. } // if (!csSubClass.IsEmpty() && !lstrcmpi(csSubClass, STILL_IMAGE))
  2660. } // if (hkThis != INVALID_HANDLE_VALUE)
  2661. } // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
  2662. SetupDiDestroyDeviceInfoList(hDevInfo);
  2663. } else { // if (hDevInfo != INVALID_HANDLE_VALUE)
  2664. DebugTrace(TRACE_ERROR,(("GetDeviceCount: ERROR!! Unable to get device info set.\r\n")));
  2665. } // if (hDevInfo != INVALID_HANDLE_VALUE)
  2666. //
  2667. // Copy the result.
  2668. //
  2669. *pdwWiaCount = dwWiaCount;
  2670. *pdwStiCount = dwStiCount;
  2671. DebugTrace(TRACE_PROC_LEAVE,(("GetDeviceCount: Leaving... STI=0x%x, WIA=0x%x.\r\n"), dwStiCount, dwWiaCount));
  2672. return;
  2673. } // GetDeviceCount()
  2674. HANDLE
  2675. ExecCommandLine(
  2676. LPTSTR szCommandLine,
  2677. DWORD dwDirectory
  2678. )
  2679. {
  2680. HANDLE hRet;
  2681. BOOL bSucceeded;
  2682. CString csCommandLine;
  2683. TCHAR szAppendDirectory[MAX_PATH+1];
  2684. UINT uiDirSize;
  2685. PROCESS_INFORMATION pi;
  2686. STARTUPINFO si = {
  2687. sizeof(si), // cb
  2688. NULL, // lpReserved;
  2689. NULL, // lpDesktop;
  2690. NULL, // lpTitle;
  2691. 0, // dwX;
  2692. 0, // dwY;
  2693. 0, // dwXSize;
  2694. 0, // dwYSize;
  2695. 0, // dwXCountChars;
  2696. 0, // dwYCountChars;
  2697. 0, // dwFillAttribute;
  2698. STARTF_FORCEONFEEDBACK, // dwFlags;
  2699. SW_SHOWNORMAL, // wShowWindow;
  2700. 0, // cbReserved2;
  2701. NULL, // lpReserved2;
  2702. NULL, // hStdInput;
  2703. NULL, // hStdOutput;
  2704. NULL // hStdError;
  2705. };
  2706. hRet = INVALID_HANDLE_VALUE;
  2707. //
  2708. // Get appending directory as needed.
  2709. //
  2710. memset(szAppendDirectory, 0, sizeof(szAppendDirectory));
  2711. switch(dwDirectory){
  2712. case EXECDIR_SYSTEM32:
  2713. {
  2714. uiDirSize = GetSystemDirectory(szAppendDirectory, ARRAYSIZE(szAppendDirectory)-1);
  2715. if( (0 == uiDirSize)
  2716. || (MAX_PATH < uiDirSize) )
  2717. {
  2718. DebugTrace(TRACE_ERROR,(("ExecCommandLine: ERROR!! Unable to get system directory. Err=0x%x.\r\n"), GetLastError()));
  2719. hRet = INVALID_HANDLE_VALUE;
  2720. goto ExecCommandLine_return;
  2721. }
  2722. break;
  2723. } // case EXECDIR_SYSTEM32:
  2724. default:
  2725. {
  2726. DebugTrace(TRACE_ERROR,(("ExecCommandLine: WARNING!! no valid directory (0x%x) specified.\r\n"), dwDirectory));
  2727. hRet = INVALID_HANDLE_VALUE;
  2728. goto ExecCommandLine_return;
  2729. } // default:
  2730. // case EXECDIR_WINDOWS:
  2731. // case EXECDIR_SYSTEM:
  2732. } // switch(dwDirectory)
  2733. csCommandLine = szAppendDirectory;
  2734. csCommandLine = csCommandLine + TEXT("\\");
  2735. csCommandLine = csCommandLine + szCommandLine;
  2736. bSucceeded = CreateProcess(NULL, // Application name
  2737. (LPTSTR)csCommandLine, // Command line
  2738. NULL, // Process attributes
  2739. NULL, // Thread attributes
  2740. FALSE, // Handle inheritance
  2741. NORMAL_PRIORITY_CLASS, // Creation flags
  2742. NULL, // Environment
  2743. NULL, // Current directory
  2744. &si,
  2745. &pi);
  2746. if (bSucceeded) {
  2747. hRet = pi.hProcess;
  2748. CloseHandle(pi.hThread);
  2749. } else {
  2750. DebugTrace(TRACE_ERROR,(("ExecCommandLine: ERROR!! CreateProcess failed. Err=0x%x.\r\n"), GetLastError()));
  2751. }
  2752. ExecCommandLine_return:
  2753. return hRet;
  2754. }
  2755. PPARAM_LIST
  2756. MigrateDeviceData(
  2757. HKEY hkDeviceData,
  2758. PPARAM_LIST pExtraDeviceData,
  2759. LPSTR pszKeyName
  2760. )
  2761. {
  2762. BOOL bDone;
  2763. PPARAM_LIST pCurrent;
  2764. PPARAM_LIST pReturn;
  2765. DWORD dwType;
  2766. DWORD dwSize;
  2767. PCHAR pOrginalBuffer;
  2768. CHAR pCopyBuffer[MAX_PATH*3];
  2769. CHAR pDataBuffer[MAX_PATH];
  2770. DWORD Idx;
  2771. //
  2772. // Initialize local.
  2773. //
  2774. bDone = FALSE;
  2775. pCurrent = pExtraDeviceData;
  2776. pReturn = NULL;
  2777. //
  2778. // Loop until it gets "END".
  2779. //
  2780. while(!bDone){
  2781. if(NULL == pCurrent){
  2782. //
  2783. // Hit the end of list.
  2784. //
  2785. bDone = TRUE;
  2786. pReturn =NULL;
  2787. continue;
  2788. } // if(NULL == pTemp)
  2789. //
  2790. // If "KeyName = END" is found, return.
  2791. //
  2792. if( (CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam1, -1,pszKeyName,-1))
  2793. && (CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam2, -1,NAME_END_A,-1)) )
  2794. {
  2795. bDone = TRUE;
  2796. pReturn = (PPARAM_LIST)pCurrent->pNext;
  2797. continue;
  2798. }
  2799. //
  2800. // If 2nd parameter is "BEGIN", create subkey and call this function recursively.
  2801. //
  2802. if(CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam2, -1,NAME_BEGIN_A,-1)){
  2803. HKEY hkSubKey;
  2804. LONG lError;
  2805. lError = RegCreateKeyA(hkDeviceData, pCurrent->pParam1, &hkSubKey);
  2806. if(ERROR_SUCCESS != lError){
  2807. //
  2808. // Unable to create subkey.
  2809. //
  2810. DebugTrace(TRACE_ERROR,(("MigrateDeviceData: ERROR!! Unable to create subkey..\r\n")));
  2811. pReturn = NULL;
  2812. goto MigrateDeviceData_return;
  2813. } // if(ERROR_SUCCESS != lError)
  2814. pCurrent = MigrateDeviceData(hkSubKey, (PPARAM_LIST)pCurrent->pNext, pCurrent->pParam1);
  2815. RegCloseKey(hkSubKey);
  2816. continue;
  2817. } // if(0 == lstrcmpiA(pCurrent->pParam2, NAME_BEGIN_A))
  2818. //
  2819. // This is a set of value and data.
  2820. //
  2821. lstrcpyA(pCopyBuffer, pCurrent->pParam2);
  2822. pOrginalBuffer = pCopyBuffer;
  2823. //
  2824. // Get key type.
  2825. //
  2826. pOrginalBuffer[8] = '\0';
  2827. dwType = DecodeHexA(pOrginalBuffer);
  2828. //
  2829. // Get data.
  2830. //
  2831. Idx = 0;
  2832. pOrginalBuffer+=9;
  2833. while('\0' != *pOrginalBuffer){
  2834. if('\0' != pOrginalBuffer[2]){
  2835. pOrginalBuffer[2] = '\0';
  2836. pDataBuffer[Idx++] = (CHAR)DecodeHexA(pOrginalBuffer);
  2837. pOrginalBuffer+=3;
  2838. } else {
  2839. pDataBuffer[Idx++] = (CHAR)DecodeHexA(pOrginalBuffer);
  2840. break;
  2841. }
  2842. } // while('\0' != pCurrent->pParam2[Idx])
  2843. //
  2844. // Create this value.
  2845. //
  2846. RegSetValueExA(hkDeviceData,
  2847. pCurrent->pParam1,
  2848. 0,
  2849. dwType,
  2850. (PBYTE)pDataBuffer,
  2851. Idx);
  2852. //
  2853. // Process next line.
  2854. //
  2855. pCurrent = (PPARAM_LIST)pCurrent->pNext;
  2856. } // while(!bDone)
  2857. MigrateDeviceData_return:
  2858. return pReturn;
  2859. } // MigrateDeviceData()
  2860. DWORD
  2861. DecodeHexA(
  2862. LPSTR lpstr
  2863. )
  2864. {
  2865. DWORD dwReturn;
  2866. //
  2867. // Initialize local.
  2868. //
  2869. dwReturn = 0;
  2870. if(NULL == lpstr){
  2871. dwReturn = 0;
  2872. goto DecodeHexA_return;
  2873. } // if(NULL == lpstr)
  2874. //
  2875. // Skip spaces.
  2876. //
  2877. for (LPSTR lpstrThis = lpstr;
  2878. *lpstrThis && *lpstrThis == TEXT(' ');
  2879. lpstrThis++)
  2880. ;
  2881. while (*lpstrThis) {
  2882. switch (*lpstrThis) {
  2883. case '0':
  2884. case '1':
  2885. case '2':
  2886. case '3':
  2887. case '4':
  2888. case '5':
  2889. case '6':
  2890. case '7':
  2891. case '8':
  2892. case '9':
  2893. dwReturn <<= 4;
  2894. dwReturn += ((*lpstrThis) - '0');
  2895. break;
  2896. case 'a':
  2897. case 'b':
  2898. case 'c':
  2899. case 'd':
  2900. case 'e':
  2901. case 'f':
  2902. dwReturn <<= 4;
  2903. dwReturn += 10 + (*lpstrThis - 'a');
  2904. break;
  2905. case 'A':
  2906. case 'B':
  2907. case 'C':
  2908. case 'D':
  2909. case 'E':
  2910. case 'F':
  2911. dwReturn <<= 4;
  2912. dwReturn += 10 + (*lpstrThis - 'A');
  2913. break;
  2914. default:
  2915. return dwReturn;
  2916. }
  2917. lpstrThis++;
  2918. } // while (*lpstrThis)
  2919. DecodeHexA_return:
  2920. return dwReturn;
  2921. } // DWORD CString::DecodeHex()
  2922. BOOL
  2923. IsNameAlreadyStored(
  2924. LPTSTR szName
  2925. )
  2926. {
  2927. BOOL bRet;
  2928. HKEY hkNameStore;
  2929. DebugTrace(TRACE_PROC_ENTER,(("IsNameAlreadyStored: Enter... \r\n")));
  2930. //
  2931. // Initialize local.
  2932. //
  2933. bRet = FALSE;
  2934. hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
  2935. //
  2936. // Open name store regkey.
  2937. //
  2938. if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){
  2939. HKEY hkTemp;
  2940. hkTemp = (HKEY)INVALID_HANDLE_VALUE;
  2941. //
  2942. // See if specified name exists in name store.
  2943. //
  2944. if(ERROR_SUCCESS == RegOpenKey(hkNameStore, szName, &hkTemp)){
  2945. //
  2946. // Specified name already exists in name store.
  2947. //
  2948. bRet = TRUE;
  2949. RegCloseKey(hkTemp);
  2950. } // if(ERROR_SUCCESS == RegOpenKey(hkNameStore, szName, &hkTemp))
  2951. RegCloseKey(hkNameStore);
  2952. } // if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
  2953. // IsNameAlreadyStored_return:
  2954. DebugTrace(TRACE_PROC_LEAVE,(("IsNameAlreadyStored: Leaving... Ret=0x%x\n"), bRet));
  2955. return bRet;
  2956. } // IsFriendlyNameUnique()
  2957. #if DEAD_CODE
  2958. #ifdef USE_STIMON
  2959. //
  2960. // For the time being always load and start the monitor
  2961. //
  2962. HKEY hkRun;
  2963. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUN, &hkRun) == NO_ERROR) {
  2964. CString csCmdLine;
  2965. csCmdLine.MakeSystemPath(MONITOR_NAME);
  2966. csCmdLine.Store (hkRun, REGSTR_VAL_MONITOR);
  2967. Report(( TEXT("Monitor Command Line %ws\r\n"), (LPCTSTR)csCmdLine));
  2968. // Launch it...
  2969. WinExec(csCmdLine, SW_SHOWNOACTIVATE);
  2970. RegCloseKey(hkRun);
  2971. }
  2972. #endif
  2973. #endif