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.

458 lines
11 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module ForceFeatures.cpp |
  5. *
  6. * Implements CForceFeatures to use msgame's HID features.
  7. *
  8. * History
  9. * ----------------------------------------------------------
  10. * Mitchell Dernis Original
  11. *
  12. * (c) 1986-1998 Microsoft Corporation. All right reserved.
  13. *
  14. * @topic ForceFeatures |
  15. * CForceFeatures opens a handle to msgame in the context of
  16. * a particular device on construction.
  17. * The public members expose the feature interface for msgame.
  18. *
  19. * Will work with NT5 as is. For Win98 we need a different
  20. * scheme for getting HID path. DI promises to fix somehow.
  21. **********************************************************************///
  22. #include <windows.h>
  23. #define DIRECTINPUT_VERSION 0x050a
  24. #include <dinput.h>
  25. #include <dinputd.h>
  26. extern "C" {
  27. #include <hidsdi.h>
  28. }
  29. #include "FFeature.h"
  30. /***********************************************************************************
  31. **
  32. ** CForceFeatures::CForceFeatures(UINT uJoystickId)
  33. **
  34. ** @mfunc C'tor gets Hid Path from Joystick and opens path to driver
  35. **
  36. ** @rdesc None since this is c'tor. However at the end of this routine
  37. ** m_hDevice will contain a handle for the driver on success, or
  38. ** will contain NULL on failure. All routines will check the
  39. ** value of m_hDevice before proceeding.
  40. **
  41. *************************************************************************************/
  42. CForceFeatures::CForceFeatures() :
  43. m_hDevice(NULL)
  44. {
  45. }
  46. /***********************************************************************************
  47. **
  48. ** CForceFeatures::~CForceFeatures()
  49. **
  50. ** @mfunc D'tor closes handle to driver, if it was open
  51. **
  52. *************************************************************************************/
  53. CForceFeatures::~CForceFeatures()
  54. {
  55. if(m_hDevice)
  56. {
  57. CloseHandle(m_hDevice);
  58. }
  59. }
  60. /***********************************************************************************
  61. **
  62. ** HRESULT CForceFeatures::Initialize(UINT uJoystickId, HINSTANCE hinstModule)
  63. **
  64. ** @mfunc Calls to MsGame to GetId using MSGAME_FEATURE_GETID
  65. **
  66. ** @rdesc S_OK on success
  67. ** E_FAIL for other problems
  68. **
  69. *************************************************************************************/
  70. HRESULT CForceFeatures::Initialize
  71. (
  72. UINT uJoystickId, //@parm Joystick Id as used by winmm
  73. HINSTANCE hinstModule //@parm Instance of the DLL for Creating DirectInput
  74. )
  75. {
  76. if (m_hDevice != NULL) {
  77. return S_OK; // No need to reinitialize
  78. }
  79. HRESULT hr;
  80. //**
  81. //** Get HidPath
  82. //**
  83. //**
  84. //
  85. // Get IDirectInput interface
  86. //
  87. IDirectInput *pDirectInput = NULL;
  88. IDirectInputJoyConfig *pDirectInputJoyConfig = NULL;
  89. hr = DirectInputCreate(
  90. hinstModule,
  91. DIRECTINPUT_VERSION,
  92. &pDirectInput,
  93. NULL
  94. );
  95. if( FAILED(hr) ) return hr;
  96. //
  97. // Get IDirectInputJoyConfig
  98. //
  99. hr=pDirectInput->QueryInterface(IID_IDirectInputJoyConfig, (LPVOID *)&pDirectInputJoyConfig);
  100. if( FAILED(hr) )
  101. {
  102. pDirectInput->Release();
  103. return hr;
  104. }
  105. //
  106. // GetConfig for JoyId
  107. //
  108. DIJOYCONFIG DiJoyConfig;
  109. DiJoyConfig.dwSize=sizeof(DIJOYCONFIG);
  110. hr = pDirectInputJoyConfig->GetConfig(
  111. uJoystickId,
  112. &DiJoyConfig,
  113. DIJC_GUIDINSTANCE
  114. );
  115. //
  116. // Done with pDirectInputJoyConfig
  117. //
  118. pDirectInputJoyConfig->Release();
  119. pDirectInputJoyConfig = NULL;
  120. if( FAILED(hr) )
  121. {
  122. pDirectInput->Release();
  123. return hr;
  124. }
  125. //
  126. // Get IDirectInputDevice interface
  127. //
  128. IDirectInputDevice *pDirectInputDevice;
  129. hr = pDirectInput->CreateDevice(DiJoyConfig.guidInstance, &pDirectInputDevice, NULL);
  130. //
  131. // Done pDirectInput
  132. //
  133. pDirectInput->Release();
  134. pDirectInput = NULL;
  135. if( FAILED(hr) ) return hr;
  136. //
  137. // Get HidPath
  138. //
  139. DIPROPGUIDANDPATH DiPropGuidAndPath;
  140. DiPropGuidAndPath.diph.dwSize = sizeof(DIPROPGUIDANDPATH);
  141. DiPropGuidAndPath.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  142. DiPropGuidAndPath.diph.dwObj = 0;
  143. DiPropGuidAndPath.diph.dwHow = DIPH_DEVICE;
  144. hr=pDirectInputDevice->GetProperty( DIPROP_GUIDANDPATH, &DiPropGuidAndPath.diph);
  145. //
  146. // Done with pDirectInputDevice
  147. //
  148. pDirectInputDevice->Release();
  149. pDirectInputDevice = NULL;
  150. if( FAILED(hr) ) return hr;
  151. //**
  152. //** Open Path to Driver
  153. //**
  154. m_hDevice = CreateFileW(
  155. DiPropGuidAndPath.wszPath,
  156. GENERIC_READ | GENERIC_WRITE,
  157. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  158. NULL,
  159. OPEN_EXISTING,
  160. 0,
  161. NULL
  162. );
  163. if (m_hDevice == INVALID_HANDLE_VALUE)
  164. {
  165. m_hDevice = NULL;
  166. }
  167. if (m_hDevice == NULL)
  168. {
  169. DWORD err = ::GetLastError();
  170. return E_FAIL;
  171. }
  172. PHIDP_PREPARSED_DATA pHidPreparsedData;
  173. if (HidD_GetPreparsedData(m_hDevice, &pHidPreparsedData) == FALSE)
  174. {
  175. ::CloseHandle(m_hDevice);
  176. m_hDevice = NULL;
  177. return E_FAIL;
  178. }
  179. HIDP_CAPS hidpCaps;
  180. HidP_GetCaps(pHidPreparsedData, &hidpCaps);
  181. m_uiMaxFeatureLength = hidpCaps.FeatureReportByteLength;
  182. HidD_FreePreparsedData(pHidPreparsedData);
  183. //
  184. // On success, m_hDevice now contains a handle to the device
  185. //
  186. return S_OK;
  187. }
  188. /***********************************************************************************
  189. **
  190. ** HRESULT CForceFeatures::GetId(PRODUCT_ID_REPORT& rProductId)
  191. **
  192. ** @mfunc Calls to MsGame to GetId using MSGAME_FEATURE_GETID
  193. **
  194. ** @rdesc S_OK on success
  195. ** ERROR_OPEN_FAILED if no drive connection
  196. ** E_FAIL for other problems
  197. **
  198. *************************************************************************************/
  199. HRESULT CForceFeatures::GetId
  200. (
  201. PRODUCT_ID_REPORT& rProductId // @parm Reference to PRODUCT_ID_REPORT to get from driver
  202. )
  203. {
  204. if(!m_hDevice)
  205. {
  206. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  207. }
  208. BOOLEAN fSuccess;
  209. //
  210. // Fill in ReportID for feature
  211. //
  212. rProductId.bReportId = MSGAME_FEATURE_GETID;
  213. //
  214. // Call Get Feature on driver
  215. //
  216. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&rProductId), m_uiMaxFeatureLength);
  217. // -- HIDPI.H
  218. // HIDP_GetData(Report Type, Data, Lenght, Preparse Data, Report, ReportLength);
  219. //
  220. // Return proper error code
  221. //
  222. if( !fSuccess )
  223. {
  224. return E_FAIL;
  225. }
  226. return S_OK;
  227. }
  228. /***********************************************************************************
  229. **
  230. ** HRESULT CForceFeatures::GetStatus(JOYCHANNELSTATUS_REPORT& rJoyChannelStatus)
  231. **
  232. ** @mfunc Get the JoyChannel Status from msgame's MSGAME_FEATURE_GETSTATUS
  233. **
  234. ** @rdesc S_OK on success
  235. ** ERROR_OPEN_FAILED if no drive connection
  236. ** E_FAIL for other problems
  237. **
  238. *************************************************************************************/
  239. HRESULT CForceFeatures::GetStatus
  240. (
  241. JOYCHANNELSTATUS_REPORT& rJoyChannelStatus // @parm Reference to JOYCHANNELSTATUS_REPORT to be filled by driver
  242. )
  243. {
  244. if(!m_hDevice)
  245. {
  246. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  247. }
  248. BOOLEAN fSuccess;
  249. //
  250. // Fill in ReportID for feature
  251. //
  252. rJoyChannelStatus.bReportId = MSGAME_FEATURE_GETSTATUS;
  253. //
  254. // Call Get Feature on driver
  255. //
  256. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&rJoyChannelStatus), m_uiMaxFeatureLength);
  257. //
  258. // Return proper error code
  259. //
  260. if( !fSuccess )
  261. {
  262. DWORD err = GetLastError();
  263. return HRESULT_FROM_WIN32(err);
  264. // return E_FAIL;
  265. }
  266. return S_OK;
  267. }
  268. /***********************************************************************************
  269. **
  270. ** HRESULT CForceFeatures::GetAckNak(ULONG_REPORT& rulAckNak)
  271. **
  272. ** @mfunc Returns an AckNak by using msgame's GetAckNak Featue
  273. **
  274. ** @rdesc S_OK on success
  275. ** ERROR_OPEN_FAILED if no drive connection
  276. ** E_FAIL for other problems
  277. **
  278. *************************************************************************************/
  279. HRESULT CForceFeatures::GetAckNak
  280. (
  281. ULONG_REPORT& rulAckNak // @parm REFERENCE to ULONG_REPORT to be filled by driver with AckNak
  282. )
  283. {
  284. if(!m_hDevice)
  285. {
  286. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  287. }
  288. BOOLEAN fSuccess;
  289. //
  290. // Fill in ReportID for feature
  291. //
  292. rulAckNak.bReportId = MSGAME_FEATURE_GETACKNAK;
  293. //
  294. // Call Get Feature on driver
  295. //
  296. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&rulAckNak), m_uiMaxFeatureLength);
  297. //
  298. // Return proper error code
  299. //
  300. if( !fSuccess )
  301. {
  302. return E_FAIL;
  303. }
  304. return S_OK;
  305. }
  306. /***********************************************************************************
  307. **
  308. ** HRESULT CForceFeatures::GetNackAck(ULONG_REPORT& rulNakAck)
  309. **
  310. ** @mfunc Returns an AckNak by using msgame's MSGAME_FEATURE_NAKACK
  311. **
  312. ** @rdesc S_OK on success
  313. ** ERROR_OPEN_FAILED if no drive connection
  314. ** E_FAIL for other problems
  315. **
  316. *************************************************************************************/
  317. HRESULT CForceFeatures::GetNakAck(
  318. ULONG_REPORT& rulNakAck // @parm REFERENCE to ULONG_REPORT to be filled by driver with NakAck
  319. )
  320. {
  321. if(!m_hDevice)
  322. {
  323. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  324. }
  325. BOOLEAN fSuccess;
  326. //
  327. // Fill in ReportID for feature
  328. //
  329. rulNakAck.bReportId = MSGAME_FEATURE_GETNAKACK;
  330. //
  331. // Call Get Feature on driver
  332. //
  333. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&rulNakAck), m_uiMaxFeatureLength);
  334. //
  335. // Return proper error code
  336. //
  337. if( !fSuccess )
  338. {
  339. return E_FAIL;
  340. }
  341. return S_OK;
  342. }
  343. /***********************************************************************************
  344. **
  345. ** HRESULT CForceFeatures::GetSync(ULONG_REPORT& rulGameport)
  346. **
  347. ** @mfunc Get Sync information from MSGAME's MSGAME_FEATURE_GETSYNC
  348. **
  349. ** @rdesc S_OK on success
  350. ** ERROR_OPEN_FAILED if no drive connection
  351. ** E_FAIL for other problems
  352. **
  353. *************************************************************************************/
  354. HRESULT CForceFeatures::GetSync
  355. (
  356. ULONG_REPORT& rulGameport // @parm REFERENCE to ULONG_REPORT to be filled by driver with Gameport
  357. )
  358. {
  359. if(!m_hDevice)
  360. {
  361. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  362. }
  363. BOOLEAN fSuccess;
  364. //
  365. // Fill in ReportID for feature
  366. //
  367. rulGameport.bReportId = MSGAME_FEATURE_GETSYNC;
  368. //
  369. // Call Get Feature on driver
  370. //
  371. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&rulGameport), m_uiMaxFeatureLength);
  372. //
  373. // Return proper error code
  374. //
  375. if( !fSuccess )
  376. {
  377. return HRESULT_FROM_WIN32(GetLastError());
  378. }
  379. return S_OK;
  380. }
  381. /***********************************************************************************
  382. **
  383. ** HRESULT CForceFeatures::DoReset()
  384. **
  385. ** @mfunc Does Reset via MSGAME's MSGAME_FEATURE_DORESET
  386. **
  387. ** @rdesc S_OK on success
  388. ** ERROR_OPEN_FAILED if no drive connection
  389. ** E_FAIL for other problems
  390. **
  391. *************************************************************************************/
  392. HRESULT CForceFeatures::DoReset()
  393. {
  394. if(!m_hDevice)
  395. {
  396. return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  397. }
  398. BOOLEAN fSuccess;
  399. //
  400. // Fill in ReportID for feature
  401. //
  402. ULONG_REPORT ulBogus;
  403. ulBogus.bReportId = MSGAME_FEATURE_DORESET;
  404. //
  405. // Call Get Feature on driver
  406. //
  407. fSuccess = HidD_GetFeature(m_hDevice, reinterpret_cast<PVOID>(&ulBogus), m_uiMaxFeatureLength);
  408. //
  409. // Return proper error code
  410. //
  411. if( !fSuccess )
  412. {
  413. return E_FAIL;
  414. }
  415. return S_OK;
  416. }