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

286 lines
5.6 KiB

  1. #include "hwdev.h"
  2. #include "setupapi.h"
  3. #include "dtctreg.h"
  4. #include "reg.h"
  5. #include "namellst.h"
  6. #include "sfstr.h"
  7. #include "str.h"
  8. #include "cmmn.h"
  9. #include "misc.h"
  10. #include "dbg.h"
  11. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  12. ///////////////////////////////////////////////////////////////////////////////
  13. //
  14. HRESULT CHWDeviceInst::Init(DEVINST devinst)
  15. {
  16. _devinst = devinst;
  17. return S_OK;
  18. }
  19. HRESULT CHWDeviceInst::InitInterfaceGUID(const GUID* pguidInterface)
  20. {
  21. _guidInterface = *pguidInterface;
  22. return S_OK;
  23. }
  24. HRESULT CHWDeviceInst::GetDeviceInstance(DEVINST* pdevinst)
  25. {
  26. HRESULT hr;
  27. if (_devinst)
  28. {
  29. *pdevinst = _devinst;
  30. hr = S_OK;
  31. }
  32. else
  33. {
  34. *pdevinst = 0;
  35. hr = S_FALSE;
  36. }
  37. return hr;
  38. }
  39. HRESULT CHWDeviceInst::GetPnpID(LPWSTR pszPnpID, DWORD cchPnpID)
  40. {
  41. HRESULT hr = _InitPnpInfo();
  42. if (SUCCEEDED(hr) && (S_FALSE != hr))
  43. {
  44. hr = SafeStrCpyN(pszPnpID, _szPnpID, cchPnpID);
  45. }
  46. else
  47. {
  48. hr = S_FALSE;
  49. }
  50. return hr;
  51. }
  52. HRESULT CHWDeviceInst::GetPnpInstID(LPWSTR pszPnpInstID, DWORD cchPnpInstID)
  53. {
  54. HRESULT hr = _InitPnpInfo();
  55. if (SUCCEEDED(hr) && (S_FALSE != hr))
  56. {
  57. hr = SafeStrCpyN(pszPnpInstID, _szPnpInstID, cchPnpInstID);
  58. }
  59. else
  60. {
  61. hr = S_FALSE;
  62. }
  63. return hr;
  64. }
  65. HRESULT CHWDeviceInst::GetInterfaceGUID(GUID* pguidInterface)
  66. {
  67. ASSERT(guidInvalid != _guidInterface);
  68. *pguidInterface = _guidInterface;
  69. return S_OK;
  70. }
  71. HRESULT CHWDeviceInst::IsRemovableDevice(BOOL* pfRemovable)
  72. {
  73. return _DeviceInstIsRemovable(_devinst, pfRemovable);
  74. }
  75. HRESULT CHWDeviceInst::ShouldAutoplayOnSpecialInterface(
  76. const GUID* pguidInterface, BOOL* pfShouldAutoplay)
  77. {
  78. WCHAR szGUID[MAX_GUIDSTRING];
  79. HRESULT hr = _StringFromGUID(pguidInterface, szGUID,
  80. ARRAYSIZE(szGUID));
  81. *pfShouldAutoplay = FALSE;
  82. if (SUCCEEDED(hr))
  83. {
  84. WCHAR szGUIDFromReg[MAX_GUIDSTRING];
  85. DWORD dwType;
  86. hr = _GetDevicePropertyGeneric(this,
  87. TEXT("AutoplayOnSpecialInterface"), FALSE, &dwType, (PBYTE)szGUIDFromReg,
  88. sizeof(szGUIDFromReg));
  89. if (SUCCEEDED(hr) && (S_FALSE != hr))
  90. {
  91. if (REG_SZ == dwType)
  92. {
  93. if (!lstrcmpi(szGUIDFromReg, szGUID))
  94. {
  95. *pfShouldAutoplay = TRUE;
  96. }
  97. }
  98. }
  99. if (*pfShouldAutoplay)
  100. {
  101. DIAGNOSTIC((TEXT("[0314]Autoplay on Special Interface %s -> Autoplay!"), szGUID));
  102. }
  103. else
  104. {
  105. DIAGNOSTIC((TEXT("[0315]*NO* Autoplay on Special Interface %s -> No Autoplay!"), szGUID));
  106. }
  107. }
  108. return hr;
  109. }
  110. ///////////////////////////////////////////////////////////////////////////////
  111. //
  112. CHWDeviceInst::CHWDeviceInst() : _devinst(0), _guidInterface(guidInvalid),
  113. _fFriendlyNameInited(FALSE)
  114. {}
  115. CHWDeviceInst::~CHWDeviceInst()
  116. {}
  117. ///////////////////////////////////////////////////////////////////////////////
  118. //
  119. HRESULT CHWDeviceInst::_InitPnpInfo()
  120. {
  121. HRESULT hres;
  122. // This require the _devinst to be set
  123. if (0 != _devinst)
  124. {
  125. hres = _InitPnpIDAndPnpInstID();
  126. if (FAILED(hres))
  127. {
  128. // Probably not a removable device
  129. hres = S_FALSE;
  130. }
  131. hres = _InitFriendlyName();
  132. }
  133. else
  134. {
  135. hres = S_FALSE;
  136. }
  137. return hres;
  138. }
  139. HRESULT CHWDeviceInst::_InitFriendlyName()
  140. {
  141. HRESULT hres;
  142. if (!_fFriendlyNameInited)
  143. {
  144. hres = S_FALSE;
  145. DWORD cb = sizeof(_szFriendlyName);
  146. CONFIGRET cr = CM_Get_DevNode_Registry_Property_Ex(_devinst,
  147. CM_DRP_FRIENDLYNAME, NULL, _szFriendlyName, &cb, 0, NULL);
  148. if (CR_SUCCESS == cr)
  149. {
  150. hres = S_OK;
  151. }
  152. else
  153. {
  154. cb = sizeof(_szFriendlyName);
  155. cr = CM_Get_DevNode_Registry_Property_Ex(_devinst,
  156. CM_DRP_DEVICEDESC, NULL, _szFriendlyName, &cb, 0, NULL);
  157. if (CR_SUCCESS == cr)
  158. {
  159. hres = S_OK;
  160. }
  161. else
  162. {
  163. _szFriendlyName[0] = 0;
  164. }
  165. }
  166. _fFriendlyNameInited = TRUE;
  167. }
  168. else
  169. {
  170. if (!_szFriendlyName[0])
  171. {
  172. hres = S_FALSE;
  173. }
  174. else
  175. {
  176. hres = S_OK;
  177. }
  178. }
  179. return hres;
  180. }
  181. HRESULT _FindInstID(LPWSTR pszPnpID, DWORD* pcch)
  182. {
  183. DWORD cToFind = 2;
  184. LPWSTR psz = pszPnpID;
  185. *pcch = 0;
  186. while (*psz && cToFind)
  187. {
  188. if ((TEXT('\\') == *psz))
  189. {
  190. --cToFind;
  191. }
  192. if (cToFind)
  193. {
  194. ++psz;
  195. }
  196. }
  197. if (*psz)
  198. {
  199. *pcch = (DWORD)(psz - pszPnpID);
  200. }
  201. return S_OK;
  202. }
  203. HRESULT _GetPnpIDHelper(DEVINST devinst, LPWSTR pszPnpID, DWORD cchPnpID)
  204. {
  205. HRESULT hres = S_FALSE;
  206. HMACHINE hMachine = NULL;
  207. CONFIGRET cr = CM_Get_Device_ID_Ex(devinst, pszPnpID,
  208. cchPnpID, 0, hMachine);
  209. if (CR_SUCCESS == cr)
  210. {
  211. hres = S_OK;
  212. }
  213. return hres;
  214. }
  215. HRESULT CHWDeviceInst::_InitPnpIDAndPnpInstID()
  216. {
  217. HRESULT hres = _GetPnpIDHelper(_devinst, _szPnpID, ARRAYSIZE(_szPnpID));
  218. if (SUCCEEDED(hres) && (S_FALSE != hres))
  219. {
  220. DWORD cchInstIDOffset;
  221. hres = _FindInstID(_szPnpID, &cchInstIDOffset);
  222. if (SUCCEEDED(hres))
  223. {
  224. *(_szPnpID + cchInstIDOffset) = 0;
  225. hres = SafeStrCpyN(_szPnpInstID, _szPnpID + cchInstIDOffset + 1,
  226. ARRAYSIZE(_szPnpInstID));
  227. }
  228. }
  229. return hres;
  230. }