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.

4615 lines
145 KiB

  1. /******************************************************************************
  2. *
  3. * dimap.cpp
  4. *
  5. * Copyright (c) 1999, 2000 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Contents:
  10. *
  11. *****************************************************************************/
  12. #include "dimapp.h"
  13. #include "objbase.h"
  14. #include "stdio.h"
  15. #include "shlwapi.h"
  16. #include "shlobj.h"
  17. #include "lmcons.h"
  18. #include "dimap.h"
  19. #include "dinputp.h"
  20. #include "string"
  21. #include "list"
  22. #include "algorithm"
  23. #include "dinputd.h"
  24. /******************************************************************************
  25. *
  26. * Definitions
  27. *
  28. *****************************************************************************/
  29. using namespace std;
  30. #undef STRICT_DEV_DEF
  31. //MAKE SURE THIS FOUR ARE CONSISTENT
  32. #define MAP_DIR _T("\\DirectX\\DirectInput\\User Maps")
  33. #define DIRECTX _T("\\DirectX")
  34. #define DIRECTINPUT _T("\\DirectInput")
  35. #define USER_MAPS _T("\\User Maps")
  36. #define NAME _T("Name")
  37. #define RESERVED_STRING _T("Error")
  38. #define DIRECT_INPUT _T("DirectInput")
  39. #define DIRECTX_VERSION _T("DirectXVersion")
  40. #define DEVICES _T("Devices")
  41. #define DEVICE _T("Device")
  42. #define VENDORID _T("VID")
  43. #define PRODUCTID _T("PID")
  44. #define CONTROLS _T("Controls")
  45. #define CONTROL _T("Control")
  46. #define USAGE _T("Usage")
  47. #define USAGEPAGE _T("UsagePage")
  48. #define GENRE _T("Genre")
  49. #define MAPEXISTS _T("MapExists")
  50. #define APPLICATION _T("Application")
  51. #define IMAGE_FILENAME _T("ImageFileName")
  52. #define OVERLAY_FILENAME _T("OverlayFileName")
  53. #define SELECTION_FILENAME _T("SelectionFileName")
  54. #define VIEWSELECT_FILENAME _T("ViewSelectFileName")
  55. #define IMAGE_FORMAT _T("ImageFormat")
  56. #define OVERLAY_FORMAT _T("OverlayFormat")
  57. #define SELECTION_FORMAT _T("SelectionFormat")
  58. #define VIEWSELECT_FORMAT _T("ViewSelectFormat")
  59. #define OVERLAY_RECT _T("OverlayRect")
  60. #define CONTROL_STRING_ALIGN _T("Align")
  61. #define CONTROL_VISIBLE _T("Visible")
  62. #define STRING_POS _T("StringPos")
  63. #define LINE_DATA _T("LineData")
  64. #define CALLOUTMAX _T("CallOutMax")
  65. #define OVERLAYRECT _T("OverlayRect")
  66. #define OFFSET _T("Type")
  67. #define TIMESTAMPHIGH _T("TimestampHigh")
  68. #define TIMESTAMPLOW _T("TimestampLow")
  69. #define NUMACTIONS _T("NumActions")
  70. #define SEPARATOR _T(',')
  71. #define RESERVED_DX_VER 0xffffffff
  72. #define RESERVED_VENDORID 0
  73. #define RESERVED_PRODUCTID 0
  74. #define RESERVED_OFFSET 0xffffffff
  75. #define RESERVED_USAGE 0
  76. #define RESERVED_USAGEPAGE 0
  77. #define RESERVED_ACTION 0xffffffff
  78. #define _MAX_SECTION_NAME 64
  79. #define _MAX_KEY_NAME 64
  80. GUID NULLGUID;
  81. #ifdef UNICODE
  82. #define String wstring
  83. #define IsSpace iswspace
  84. #else
  85. #define String string
  86. #define IsSpace isspace
  87. #endif // !UNICODE
  88. typedef String::iterator StrIter;
  89. class CS:public String{};
  90. typedef list<CS> STRINGLIST;
  91. /******************************************************************************
  92. *
  93. * Classes
  94. *
  95. *****************************************************************************/
  96. template <class p> class AutoRelease
  97. {
  98. p m_p;
  99. public:
  100. AutoRelease(){m_p=NULL;};
  101. ~AutoRelease(){if(m_p){m_p->Release();m_p=NULL;};};
  102. inline LPVOID* Addr() { return (LPVOID*) &m_p;};
  103. operator p(){return m_p;};
  104. operator p*(){return &m_p;};
  105. p P(){return m_p;};
  106. };
  107. typedef AutoRelease<LPDIRECTINPUT8> LPDIRECTINPUT_AR;
  108. typedef AutoRelease<LPDIRECTINPUTDEVICE8> LPDIRECTINPUTDEVICE_AR;
  109. struct DeviceObjData;
  110. struct ControlData
  111. {
  112. DeviceObjData *pDevObj;
  113. String ControlName;//Name in .ini file
  114. String Name;
  115. DWORD dwUsage;
  116. DWORD dwUsagePage;
  117. DWORD dwAction;//<---workspace for mapping...
  118. DWORD dwOffset;
  119. };
  120. typedef list<ControlData> CONTROLLIST;
  121. struct DeviceObjData
  122. {
  123. ControlData *pUCtrlData;
  124. ControlData *pVCtrlData;
  125. String Name;//Name for device object returned by DInput
  126. DWORD dwUsage;
  127. DWORD dwUsagePage;
  128. DWORD dwOffset;
  129. DWORD dwType;
  130. DWORD dwFlags;
  131. bool bMapped;//<---workspace for mapping...
  132. };
  133. typedef list<DeviceObjData> DEVICEOBJLIST;
  134. struct DEVCNT
  135. {
  136. LPDIDEVICEINSTANCE pDIDI;
  137. int *m_pnCnt;
  138. };
  139. class IDirectInputMapperTrA:
  140. public IDirectInputMapperA,public IDirectInputMapperVendorA
  141. {
  142. virtual HRESULT InitializeI(
  143. LPCGUID lpThisGUIDInstance,
  144. LPCTSTR lpcstrFileName,
  145. DWORD dwFlags)=0;
  146. HRESULT STDMETHODCALLTYPE Initialize(
  147. LPCGUID lpThisGUIDInstance,
  148. LPCSTR lpcstrFileName,
  149. DWORD dwFlags);
  150. virtual HRESULT GetActionMapI(
  151. LPDIACTIONFORMAT lpDiActionFormat,
  152. LPCTSTR lpctstrUserName,
  153. FILETIME *pTimestamp,DWORD dwFlags)=0;
  154. HRESULT STDMETHODCALLTYPE GetActionMap(
  155. LPDIACTIONFORMATA lpDiActionFormat,
  156. LPCSTR lpctstrUserName,
  157. FILETIME *pTimestamp,DWORD dwFlags);
  158. virtual HRESULT SaveActionMapI(
  159. LPDIACTIONFORMAT lpDiActionFormat,
  160. LPCTSTR lpctstrUserName,
  161. DWORD dwFlags)=0;
  162. HRESULT STDMETHODCALLTYPE SaveActionMap(
  163. LPDIACTIONFORMATA lpDiActionFormat,
  164. LPCSTR lpctstrUserName,
  165. DWORD dwFlags);
  166. virtual HRESULT GetImageInfoI(
  167. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader)=0;
  168. HRESULT STDMETHODCALLTYPE GetImageInfo(
  169. LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader);
  170. virtual HRESULT WriteVendorFileI(
  171. LPDIACTIONFORMAT lpDiActionFormat,
  172. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  173. DWORD dwFlags)=0;
  174. HRESULT STDMETHODCALLTYPE WriteVendorFile(
  175. LPDIACTIONFORMATA lpDiActionFormat,
  176. LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader,
  177. DWORD dwFlags);
  178. };
  179. class IDirectInputMapperTrW:
  180. public IDirectInputMapperW,public IDirectInputMapperVendorW
  181. {
  182. virtual HRESULT InitializeI(
  183. LPCGUID lpThisGUIDInstance,
  184. LPCTSTR lpcstrFileName,
  185. DWORD dwFlags)=0;
  186. HRESULT STDMETHODCALLTYPE Initialize(
  187. LPCGUID lpThisGUIDInstance,
  188. LPCWSTR lpcstrFileName,
  189. DWORD dwFlags);
  190. virtual HRESULT GetActionMapI(
  191. LPDIACTIONFORMAT lpDiActionFormat,
  192. LPCTSTR lpctstrUserName,
  193. FILETIME *pTimestamp,DWORD dwFlags)=0;
  194. HRESULT STDMETHODCALLTYPE GetActionMap(
  195. LPDIACTIONFORMATW lpDiActionFormat,
  196. LPCWSTR lpctstrUserName,
  197. FILETIME *pTimestamp,DWORD dwFlags);
  198. virtual HRESULT SaveActionMapI(
  199. LPDIACTIONFORMAT lpDiActionFormat,
  200. LPCTSTR lpctstrUserName,
  201. DWORD dwFlags)=0;
  202. HRESULT STDMETHODCALLTYPE SaveActionMap(
  203. LPDIACTIONFORMATW lpDiActionFormat,
  204. LPCWSTR lpctstrUserName,
  205. DWORD dwFlags);
  206. virtual HRESULT GetImageInfoI(
  207. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader)=0;
  208. HRESULT STDMETHODCALLTYPE GetImageInfo(
  209. LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader);
  210. virtual HRESULT WriteVendorFileI(
  211. LPDIACTIONFORMAT lpDiActionFormat,
  212. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  213. DWORD dwFlags)=0;
  214. HRESULT STDMETHODCALLTYPE WriteVendorFile(
  215. LPDIACTIONFORMATW lpDiActionFormat,
  216. LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader,
  217. DWORD dwFlags);
  218. };
  219. class CDIMapObj:public IDirectInputMapperTrA,public IDirectInputMapperTrW
  220. {
  221. #ifdef _CHECKED
  222. static int m_DeviceCount;
  223. int m_DeviceNo;
  224. #endif
  225. ULONG m_ulRefCnt;
  226. bool m_bInitialized;
  227. DWORD m_dwThisVendorID;
  228. DWORD m_dwThisProductID;
  229. String m_DeviceName;
  230. GUID m_DeviceGuid;
  231. int m_nDeviceInstanceNo;
  232. //Vendor file name data
  233. String m_VFileName;
  234. LPCTSTR m_lpVFileName;
  235. String m_VFileDevName;
  236. CONTROLLIST m_VCtrlData;
  237. bool m_bVLoaded;
  238. //User file name data
  239. String m_UName;
  240. LPCTSTR m_lpUName;
  241. String m_UFileName;
  242. String m_UserDir;
  243. String m_UFileDevName;
  244. CONTROLLIST m_UCtrlData;
  245. bool m_bULoaded;
  246. FILETIME m_UTimestamp;
  247. bool m_bImageBufferSize;
  248. DWORD m_dwImageBufferSize;
  249. HRESULT InitializeI(
  250. LPCGUID lpThisGUIDInstance,
  251. LPCTSTR lpcstrFileName,
  252. DWORD dwFlags);
  253. HRESULT GetActionMapI(
  254. LPDIACTIONFORMAT lpDiActionFormat,
  255. LPCTSTR lpctstrUserName,
  256. FILETIME *pTimestamp,DWORD dwFlags);
  257. HRESULT SaveActionMapI(
  258. LPDIACTIONFORMAT lpDiActionFormat,
  259. LPCTSTR lpctstrUserName,
  260. DWORD dwFlags);
  261. HRESULT GetImageInfoI(
  262. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader);
  263. HRESULT WriteVendorFileI(
  264. LPDIACTIONFORMAT lpDiActionFormat,
  265. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  266. DWORD dwFlags);
  267. HRESULT GetImageInfoInternal(
  268. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  269. bool bGettingSize);
  270. void SaveActionMapUV(
  271. LPDIACTIONFORMAT lpDiActionFormat,
  272. bool bDevInFileLoaded,
  273. LPCTSTR pFileName,
  274. String &FileDevName,
  275. CONTROLLIST &ControlsData,
  276. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  277. DWORD dwHow1,DWORD dwHow2,bool bUserFile);
  278. void WriteImageInfo(LPCTSTR lpFileKeyName,LPCTSTR lpFormatKeyName,
  279. LPCTSTR lpSectionName,LPDIDEVICEIMAGEINFO lpImageInfo,
  280. bool bAddIndex,bool bDelete);
  281. void MakeNewControlName(String &CtrlName,
  282. DEVICEOBJLIST::iterator DevObjIt,
  283. CONTROLLIST &ControlsData,
  284. String &FileDevName,
  285. STRINGLIST &ControlsAllDevs,
  286. STRINGLIST &Controls);
  287. void Resinc(LPDIACTIONFORMAT lpDiActionFormat);
  288. HRESULT GetImageInfo(
  289. DeviceObjData *pDevObj,
  290. DWORD dwIndex,
  291. LPDIDEVICEIMAGEINFO lpImageInfo,
  292. DWORD dwImageType);
  293. bool GetImageInfoFileName(LPCTSTR lpKeyName,LPCTSTR lpSectionName,
  294. DWORD dwIndex,LPDIDEVICEIMAGEINFO lpImageInfo);
  295. //keep flags for a while just in case we change our minds again
  296. #if 0
  297. void GetImageInfoFormat(LPCTSTR lpKeyName,LPCTSTR lpSectionName,
  298. DWORD dwIndex,LPDIDEVICEIMAGEINFO lpImageInfo);
  299. #endif
  300. void LoadFileData(LPCTSTR lpFileName,LPCTSTR lpThisName,
  301. DWORD dwThisVendorID,DWORD dwThisProductID,
  302. String &FileDeviceName,CONTROLLIST &ControlsData,
  303. bool &bLoaded,FILETIME *pT,LPDIACTIONFORMAT lpDiActionFormat);
  304. void LoadUserData(LPCTSTR lpctstrUserName,
  305. LPDIACTIONFORMAT lpDiActionFormat,
  306. bool bForceReload=false,
  307. bool bCreateDir=false);
  308. void Clear();
  309. bool IsVIDPID(){if(m_dwThisVendorID&&m_dwThisProductID)
  310. return true;return false;};
  311. bool CompareData(DeviceObjData &DOD,ControlData &CD);
  312. bool GetOffset(ControlData &CD,DEVICEOBJLIST &DevObjList,DWORD dwSemantic,
  313. DEVICEOBJLIST::iterator &DevObjItOut);
  314. void MapGenre(LPDIACTIONFORMAT lpDiActionFormat,CONTROLLIST &ControlsData,
  315. LPCTSTR lpGenreName,LPCTSTR lpFileName,
  316. LPCGUID lpThisGUIDInstance,
  317. DEVICEOBJLIST &DevObjList,DWORD dwHow,
  318. DWORD &dwNOfMappedActions);
  319. void MapDevice(LPDIACTIONFORMAT lpDiActionFormat,
  320. LPCTSTR lpFileName,
  321. LPCTSTR lpFileDevName,LPCGUID lpThisGUIDInstance,
  322. DEVICEOBJLIST &DevObjList,CONTROLLIST &ControlsData,
  323. DWORD dwHow,DWORD dwHowApp,DWORD &dwNOfMappedActions,
  324. bool *pbMapExists,bool bUserFile);
  325. public:
  326. #ifdef _CHECKED
  327. int GetDeviceNo(){return m_DeviceNo;};
  328. #endif
  329. DEVICEOBJLIST m_DevObjList;
  330. CDIMapObj();
  331. ~CDIMapObj();
  332. ULONG STDMETHODCALLTYPE AddRef()
  333. {DllAddRef();m_ulRefCnt++;return m_ulRefCnt;};
  334. ULONG STDMETHODCALLTYPE Release();
  335. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID * ppvObj);
  336. };
  337. /******************************************************************************
  338. *
  339. * Debug code
  340. *
  341. *****************************************************************************/
  342. #ifdef _CHECKED
  343. #include <tchar.h>
  344. #include <crtdbg.h>
  345. #include <stdio.h>
  346. enum BlockType{
  347. eObjectEntryBT,
  348. eFunctionBT,
  349. eSubBT,
  350. eException,
  351. };
  352. enum ObjectEntry{
  353. eInitialize=1,
  354. eGetActionMap=2,
  355. eSaveActionMap=4,
  356. eGetImageInfo=8,
  357. eWriteVendorFile=16,
  358. eCDIMapObj=32,
  359. e_CDIMapObj=64,
  360. eAddRef=128,
  361. eRelease=256,
  362. eUnknownMethod=4096
  363. };
  364. class CAdvancedTracer
  365. {
  366. static DWORD s_dwFlags;
  367. static DWORD s_dwFlagsEx;
  368. static DWORD s_dwObjNo;
  369. static DWORD s_dwObjNoEx;
  370. static int s_nDeviceNo;
  371. static DWORD s_dwLevels;
  372. static String s_ExceptionBuffer;
  373. static LPCTSTR s_lpMethodName;
  374. static ObjectEntry s_eObjectEntry;
  375. static CDIMapObj* s_lpMapObj;
  376. static FILE *s_pLogFile; // File handle used for outputing to file
  377. static bool s_bException;
  378. static bool ExProcessing(){return s_bException;};
  379. BlockType m_eBlockType;
  380. int m_nExceptionBufferPos;
  381. static bool DumpFlagEx();
  382. static bool DumpFlag(bool bInfoEx);
  383. public:
  384. CAdvancedTracer(
  385. BlockType eBlockType=eSubBT,
  386. LPCTSTR pMethodName=NULL,
  387. ObjectEntry eObjectEntry=eUnknownMethod,
  388. CDIMapObj*lpMapObj=NULL);
  389. CAdvancedTracer(LPCTSTR lpSourceFile,DWORD dwLine,HRESULT hRes);
  390. ~CAdvancedTracer();
  391. static void OutputTraceString(LPCTSTR szFmt, ...);
  392. static void OutputTraceStringInfoEx(LPCTSTR szFmt, ...);
  393. static void OutputTraceStringI(bool bInfoEx,LPCTSTR szFmt,
  394. va_list argptr);
  395. static void Dump(LPCTSTR szName,DWORD dwVal);
  396. static void Dump(LPCTSTR szName,int nVal);
  397. static void Dump(LPCTSTR szName,bool bVal);
  398. static void Dump(LPCTSTR szName,LPDIACTIONFORMAT lpVal);
  399. static void Dump(LPCTSTR szName,LPDIDEVICEIMAGEINFOHEADER lpVal);
  400. static void Dump(LPCTSTR szName,LPCTSTR lpVal);
  401. static void Dump(LPCTSTR szName,LPTSTR lpVal);
  402. static void Dump(LPCTSTR szName,LPCGUID lpVal);
  403. static void Dump(LPCTSTR szName,LPCDIDEVICEOBJECTINSTANCE lpVal);
  404. static void Dump(LPCTSTR szName,const GUID &guid);
  405. static void Dump(LPCTSTR szName,String &Val);
  406. static void Dump(LPCTSTR szName,DEVICEOBJLIST &Val);
  407. };
  408. // Initialize to 0 implicitly
  409. DWORD CAdvancedTracer::s_dwFlags;
  410. DWORD CAdvancedTracer::s_dwFlagsEx;
  411. DWORD CAdvancedTracer::s_dwObjNo;
  412. DWORD CAdvancedTracer::s_dwObjNoEx;
  413. int CAdvancedTracer::s_nDeviceNo;
  414. DWORD CAdvancedTracer::s_dwLevels;
  415. String CAdvancedTracer::s_ExceptionBuffer;
  416. LPCTSTR CAdvancedTracer::s_lpMethodName=_T("");
  417. ObjectEntry CAdvancedTracer::s_eObjectEntry=eUnknownMethod;
  418. CDIMapObj* CAdvancedTracer::s_lpMapObj;
  419. FILE *CAdvancedTracer::s_pLogFile;
  420. bool CAdvancedTracer::s_bException;
  421. #define USETRACER() \
  422. CAdvancedTracer \
  423. There_can_be_only_one_USETRACER_macro_per_block;
  424. #define METHOD_ENTRY(MethodName) \
  425. CAdvancedTracer \
  426. There_can_be_only_one_USETRACER_macro_per_block\
  427. (eFunctionBT,_T(#MethodName));
  428. #define OBJECT_ENTRY(MethodName,MethodID) \
  429. CAdvancedTracer \
  430. There_can_be_only_one_USETRACER_macro_per_block\
  431. (eObjectEntryBT,MethodName,MethodID,this);
  432. #define EXCEPTION(lpSourceFile,dwLine,hRes) \
  433. CAdvancedTracer \
  434. There_can_be_only_one_USETRACER_macro_per_block\
  435. (lpSourceFile,dwLine,hRes);
  436. #define CDIMAPOBJ_ENTERED OBJECT_ENTRY\
  437. (_T("CDIMapObj"),eCDIMapObj);
  438. #define _CDIMAPOBJ_ENTERED OBJECT_ENTRY\
  439. (_T("~CDIMapObj"),e_CDIMapObj);
  440. #define ADDREF_ENTERED OBJECT_ENTRY\
  441. (_T("AddRef"),eAddRef);
  442. #define RELEASE_ENTERED OBJECT_ENTRY\
  443. (_T("Release"),eRelease);
  444. #define INITIALIZE_ENTERED OBJECT_ENTRY\
  445. (_T("Initialize"),eInitialize);
  446. #define GETACTIONMAP_ENTERED OBJECT_ENTRY\
  447. (_T("GetActionMap"),eGetActionMap);
  448. #define SAVEACTIONMAP_ENTERED OBJECT_ENTRY\
  449. (_T("SaveActionMap"),eSaveActionMap);
  450. #define GETIMAGEINFO_ENTERED OBJECT_ENTRY\
  451. (_T("GetImageInfo"),eGetImageInfo);
  452. #define WRITEVENDORFILE_ENTERED OBJECT_ENTRY\
  453. (_T("WriteVendorFile"),eWriteVendorFile);
  454. #define TRACE CAdvancedTracer::OutputTraceString
  455. #define TRACEI CAdvancedTracer::OutputTraceStringInfoEx
  456. #define DUMP(P) CAdvancedTracer::Dump(_T(#P),P)
  457. #define DUMPN(N,V) CAdvancedTracer::Dump(N,V)
  458. #define TRACEGUID OutputDebugGuid
  459. void OutputDebugGuid(const GUID &guid);
  460. #define MAP_EXCEPTION(A) MapException(_T(__FILE__),__LINE__,A)
  461. #else //_CHECKED
  462. #define TRACE 1 ? 0 :
  463. #define TRACEI 1 ? 0 :
  464. #define DUMP(a)
  465. #define DUMPN(a,b)
  466. #define USETRACER()
  467. #define METHOD_ENTRY(a)
  468. #define OBJECT_ENTRY(a,b)
  469. #define EXCEPTION(a,b,c)
  470. #define CDIMAPOBJ_ENTERED
  471. #define _CDIMAPOBJ_ENTERED
  472. #define ADDREF_ENTERED
  473. #define RELEASE_ENTERED
  474. #define INITIALIZE_ENTERED
  475. #define GETACTIONMAP_ENTERED
  476. #define SAVEACTIONMAP_ENTERED
  477. #define GETIMAGEINFO_ENTERED
  478. #define WRITEVENDORFILE_ENTERED
  479. #define TRACEGUID 0 ? 1 : (DWORD)&
  480. #define MAP_EXCEPTION(A) MapException(A)
  481. #endif //_CHECKED
  482. #ifdef _CHECKED
  483. CAdvancedTracer::CAdvancedTracer(
  484. BlockType eBlockType,
  485. LPCTSTR pMethodName,
  486. ObjectEntry eObjectEntry,
  487. CDIMapObj*lpMapObj)
  488. {
  489. m_eBlockType=eBlockType;
  490. switch(m_eBlockType)
  491. {
  492. case eObjectEntryBT:
  493. s_bException=false;
  494. //default - no method is dumped
  495. s_dwFlags=GetProfileInt(_T("DEBUG"),_T("dinput.map"),0);
  496. //default - all methods are dumped during exception
  497. s_dwFlagsEx=GetProfileInt(_T("DEBUG"),_T("dinput.mapex"),-1);
  498. //default - all objects are dumped
  499. s_dwObjNo=GetProfileInt(_T("DEBUG"),_T("dinput.mapobj"),-1);
  500. //default - all objects are dumped during exception
  501. s_dwObjNoEx=GetProfileInt(_T("DEBUG"),_T("dinput.mapobjex"),-1);
  502. s_nDeviceNo=lpMapObj->GetDeviceNo();
  503. s_dwLevels=0;
  504. s_ExceptionBuffer.resize(0);
  505. s_lpMethodName=pMethodName;
  506. s_eObjectEntry=eObjectEntry;
  507. s_lpMapObj=lpMapObj;
  508. s_pLogFile=NULL; // File handle used for outputing to file
  509. m_nExceptionBufferPos=0;
  510. TCHAR F[1024];
  511. if((GetProfileString(_T("DEBUG"),
  512. _T("dinput.maplogfile"),_T(""),
  513. F,1024)!=1023)&&F[0])
  514. {
  515. F[1023]=0;
  516. s_pLogFile=_tfopen(F,_T("a+"));
  517. }
  518. TRACE(_T("____________________________________\
  519. ___________________________________________\n"));
  520. TRACE(_T("%s() entered, dump method id=%u, dump object id=%u\n"),
  521. s_lpMethodName,s_eObjectEntry,s_nDeviceNo);
  522. TRACE(_T("{\n"));
  523. break;
  524. case eFunctionBT:
  525. m_nExceptionBufferPos=s_ExceptionBuffer.size();
  526. TRACE(_T("%s()\n"),pMethodName);
  527. TRACE(_T("{\n"));
  528. break;
  529. case eSubBT:
  530. m_nExceptionBufferPos=s_ExceptionBuffer.size();
  531. break;
  532. }
  533. s_dwLevels++;
  534. }
  535. CAdvancedTracer::CAdvancedTracer(
  536. LPCTSTR lpSourceFile,
  537. DWORD dwLine,
  538. HRESULT hRes)
  539. {
  540. m_eBlockType=eException;
  541. s_bException=true;
  542. DWORD dwOldLevels=s_dwLevels;
  543. s_dwLevels=0;
  544. TRACE(_T("MAPPER ERROR ******************************\n"));
  545. TRACE(_T("ERROR IN FILE: %s\n"),lpSourceFile);
  546. TRACE(_T("ERROR ON LINE: %d\n"),dwLine);
  547. TRACE(_T("hRes=0x%x\n"),hRes);
  548. switch(hRes)
  549. {
  550. case E_SYNTAX_ERROR:
  551. TRACE(_T("hRes=E_SYNTAX_ERROR\n"));
  552. break;
  553. case E_DEFINITION_NOT_FOUND:
  554. TRACE(_T("hRes=E_DEFINITION_NOT_FOUND\n"));
  555. break;
  556. case E_LINE_TO_LONG:
  557. TRACE(_T("hRes=E_LINE_TO_LONG\n"));
  558. break;
  559. case E_ACTION_NOT_DEFINED:
  560. TRACE(_T("hRes=E_ACTION_NOT_DEFINED\n"));
  561. break;
  562. case E_DEVICE_NOT_DEFINED:
  563. TRACE(_T("hRes=E_DEVICE_NOT_DEFINED\n"));
  564. break;
  565. case E_VENDORID_NOT_FOUND:
  566. TRACE(_T("hRes=E_VENDORID_NOT_FOUND\n"));
  567. break;
  568. case E_PRODUCTID_NOT_FOUND:
  569. TRACE(_T("hRes=E_PRODUCTID_NOT_FOUND\n"));
  570. break;
  571. case E_USAGE_NOT_FOUND:
  572. TRACE(_T("hRes=E_USAGE_NOT_FOUND\n"));
  573. break;
  574. case E_USAGEPAGE_NOT_FOUND:
  575. TRACE(_T("hRes=E_USAGEPAGE_NOT_FOUND\n"));
  576. break;
  577. case E_DEVICE_NOT_FOUND:
  578. TRACE(_T("hRes=E_DEVICE_NOT_FOUND\n"));
  579. break;
  580. case E_BAD_VERSION:
  581. TRACE(_T("hRes=E_BAD_VERSION\n"));
  582. break;
  583. case E_DEVICE_MISSING_CONTROL:
  584. TRACE(_T("hRes=E_DEVICE_MISSING_CONTROL\n"));
  585. break;
  586. case E_DEV_OBJ_NOT_FOUND:
  587. TRACE(_T("hRes=E_DEV_OBJ_NOT_FOUND\n"));
  588. break;
  589. case E_CTRL_W_OFFSET_NOTFOUND:
  590. TRACE(_T("hRes=E_CTRL_W_OFFSET_NOTFOUND\n"));
  591. break;
  592. case E_FILENAME_TO_LONG:
  593. TRACE(_T("hRes=E_FILENAME_TO_LONG\n"));
  594. break;
  595. case E_WRONG_ALIGN_DATA:
  596. TRACE(_T("hRes=E_WRONG_ALIGN_DATA\n"));
  597. break;
  598. case E_CORRUPT_IMAGE_DATA:
  599. TRACE(_T("hRes=E_CORRUPT_IMAGE_DATA\n"));
  600. break;
  601. case E_OUTOFMEMORY:
  602. TRACE(_T("hRes=E_OUTOFMEMORY\n"));
  603. break;
  604. case E_INVALIDARG:
  605. TRACE(_T("hRes=E_INVALIDARG\n"));
  606. break;
  607. case DIERR_NOTINITIALIZED:
  608. TRACE(_T("hRes=DIERR_NOTINITIALIZED\n"));
  609. break;
  610. case E_FAIL:
  611. TRACE(_T("hRes=E_FAIL\n"));
  612. break;
  613. default :
  614. TRACE(_T("hRes=UNKNOWN ERROR.\n"));
  615. break;
  616. }
  617. TRACE(_T("ERROR INFO:\n"));
  618. if(DumpFlagEx())
  619. {
  620. if(s_ExceptionBuffer.data())
  621. {
  622. LPCTSTR p=s_ExceptionBuffer.data();
  623. TCHAR C[2];
  624. C[1]=0;
  625. while(*p)
  626. {
  627. C[0]=*p;
  628. OutputDebugString(C);
  629. Sleep(0);
  630. p++;
  631. };
  632. //OutputDebugString(s_ExceptionBuffer.data());
  633. if (s_pLogFile)
  634. {
  635. _ftprintf(s_pLogFile,s_ExceptionBuffer.data());
  636. }
  637. }
  638. }
  639. TRACE(_T("ERROR HAPPENED HERE -->\n"));
  640. s_ExceptionBuffer.resize(0);
  641. s_dwLevels=dwOldLevels+1;
  642. }
  643. CAdvancedTracer::~CAdvancedTracer()
  644. {
  645. --s_dwLevels;
  646. switch(m_eBlockType)
  647. {
  648. case eObjectEntryBT:
  649. TRACE(_T("}\n"));
  650. TRACE(_T("%s leaving\n"),s_lpMethodName);
  651. TRACE(_T("____________________________________\
  652. ___________________________________________\n"));
  653. s_dwFlags=0;
  654. s_dwFlagsEx=-1;
  655. s_dwObjNo=-1;
  656. s_dwObjNoEx=-1;
  657. s_nDeviceNo=-1;
  658. s_dwLevels=0;
  659. s_ExceptionBuffer.resize(0);
  660. s_lpMethodName=_T("");
  661. s_eObjectEntry=eUnknownMethod;
  662. s_lpMapObj=NULL;
  663. if(s_pLogFile)
  664. fclose(s_pLogFile);
  665. s_pLogFile=NULL;
  666. break;
  667. case eFunctionBT:
  668. TRACE(_T("}\n"));
  669. break;
  670. case eSubBT:
  671. break;
  672. case eException:
  673. break;
  674. }
  675. if((m_eBlockType!=eObjectEntryBT)&&
  676. (m_eBlockType!=eSubBT))
  677. {
  678. if(!ExProcessing())
  679. s_ExceptionBuffer.resize(m_nExceptionBufferPos);
  680. }
  681. }
  682. bool CAdvancedTracer::DumpFlag(bool bInfoEx)
  683. {
  684. if((s_dwObjNo==-1)||(s_dwObjNo==s_nDeviceNo))
  685. if(s_dwFlags&s_eObjectEntry)
  686. return true;
  687. if(bInfoEx)
  688. if((s_dwObjNoEx==-1)||(s_dwObjNoEx==s_nDeviceNo))
  689. if(s_dwFlagsEx&s_eObjectEntry)
  690. return true;
  691. return false;
  692. }
  693. bool CAdvancedTracer::DumpFlagEx()
  694. {
  695. if((s_dwObjNoEx==-1)||(s_dwObjNoEx==s_nDeviceNo))
  696. if(s_dwFlagsEx&s_eObjectEntry)
  697. return true;
  698. return false;
  699. }
  700. void CAdvancedTracer::OutputTraceString(LPCTSTR szFmt, ...)
  701. {
  702. va_list argptr;
  703. va_start(argptr, szFmt);
  704. OutputTraceStringI(false,szFmt,argptr);
  705. va_end(argptr);
  706. }
  707. void CAdvancedTracer::OutputTraceStringInfoEx(LPCTSTR szFmt, ...)
  708. {
  709. va_list argptr;
  710. va_start(argptr, szFmt);
  711. OutputTraceStringI(true,szFmt,argptr);
  712. va_end(argptr);
  713. }
  714. // Warning: This function is not thread safe.
  715. void CAdvancedTracer::OutputTraceStringI(bool bInfoEx,
  716. LPCTSTR szFmt,va_list argptr)
  717. {
  718. const cBufSize=1024;
  719. TCHAR szBuf[cBufSize];
  720. szBuf[cBufSize-1]=0;
  721. // Print the identation first
  722. int nCnt=s_dwLevels;
  723. if(nCnt>cBufSize-1)nCnt=cBufSize-1;
  724. for (DWORD i = 0; i < nCnt; ++i)
  725. {
  726. szBuf[i]=_T(' ');
  727. }
  728. szBuf[i]=0;
  729. // Then print the content
  730. #ifdef WIN95
  731. {
  732. char *psz = NULL;
  733. char szDfs[1024]={0};
  734. strcpy(szDfs,szFmt); // make a local copy of format string
  735. while (psz = strstr(szDfs,"%p")) // find each %p
  736. *(psz+1) = 'x'; // replace each %p with %x
  737. _vsntprintf(&szBuf[i], cBufSize-1-i, szDfs, argptr); // use the local format string
  738. }
  739. #else
  740. {
  741. _vsntprintf(&szBuf[i], cBufSize-1-i, szFmt, argptr);
  742. }
  743. #endif
  744. szBuf[cBufSize-1]=0;
  745. if((!ExProcessing())&&DumpFlagEx())
  746. s_ExceptionBuffer+=szBuf;
  747. if(DumpFlag(bInfoEx)||(ExProcessing()&&DumpFlagEx()))
  748. {
  749. OutputDebugString(szBuf);
  750. if (s_pLogFile)
  751. {
  752. _ftprintf(s_pLogFile, szBuf);
  753. }
  754. }
  755. }
  756. void CAdvancedTracer::Dump(LPCTSTR szName,DWORD dwVal)
  757. {
  758. TRACE(_T("%s=%u\n"),szName,(unsigned int)dwVal);
  759. }
  760. void CAdvancedTracer::Dump(LPCTSTR szName,int nVal)
  761. {
  762. TRACE(_T("%s=%d\n"),szName,(unsigned int)nVal);
  763. }
  764. void CAdvancedTracer::Dump(LPCTSTR szName,String &Val)
  765. {
  766. if(Val.data())
  767. TRACE(_T("%s=%s\n"),szName,Val.data());
  768. else
  769. TRACE(_T("%s=NULL\n"),szName);
  770. }
  771. void CAdvancedTracer::Dump(LPCTSTR szName,bool bVal)
  772. {
  773. TRACE(_T("%s=%u\n"),szName,(unsigned int)bVal);
  774. }
  775. void CAdvancedTracer::Dump(LPCTSTR szName,DEVICEOBJLIST &Val)
  776. {
  777. TRACE(_T("%s:\n"),szName);
  778. USETRACER();
  779. TRACE(_T("UsagePage\tUsage\tType\tFlags\tName\n"));
  780. DEVICEOBJLIST::iterator DevObjIt;
  781. for(DevObjIt=Val.begin();DevObjIt!=Val.end();DevObjIt++)
  782. {
  783. TRACE(_T("%u\t%u\t0x%x\t0x%x\t%s\n"),
  784. DevObjIt->dwUsagePage,
  785. DevObjIt->dwUsage,
  786. DevObjIt->dwType,
  787. DevObjIt->dwFlags,
  788. DevObjIt->Name.data());
  789. }
  790. }
  791. void CAdvancedTracer::Dump(LPCTSTR szName,LPDIACTIONFORMAT lpVal)
  792. {
  793. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  794. TRACE(_T("%s=0x%p\n"),szName,lpVal);
  795. if(lpVal)
  796. {
  797. USETRACER();
  798. TRACE(_T("dwSize=%u\tdwActionSize=%u\n"),
  799. (unsigned int)lpVal->dwSize,
  800. (unsigned int)lpVal->dwActionSize);
  801. TRACE(_T("guidActionMap="));TRACEGUID(lpVal->guidActionMap);
  802. TRACE(_T("dwGenre=0x%x\tGenre=%u\n"),
  803. (unsigned int)lpVal->dwGenre,
  804. (unsigned int)DISEM_GENRE_GET(lpVal->dwGenre));
  805. TRACE(_T("dwNumActions=%u\trgoAction=0x%x\n"),
  806. (unsigned int)lpVal->dwNumActions,
  807. lpVal->rgoAction);
  808. TRACE(_T("ftTimeStamp.dwHighDateTime=0x%x\t"),
  809. (unsigned int)lpVal->ftTimeStamp.dwHighDateTime);
  810. TRACE(_T("ftTimeStamp.dwLowDateTime=0x%x\n"),
  811. (unsigned int)lpVal->ftTimeStamp.dwLowDateTime);
  812. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  813. TRACE(_T("rgoAction=0x%p\n"),lpVal);
  814. if(lpVal->rgoAction)
  815. {
  816. USETRACER();
  817. TRACE(_T("Action No\tdwSemantic\tSemantic\tSemantic type\tdwFlags\t\
  818. dwObjID\tdwHow\tguidInstance\n"));
  819. for(DWORD i=0;i<lpVal->dwNumActions;i++)
  820. {
  821. LPCTSTR p;
  822. if(DISEM_TYPE_GET(lpVal->rgoAction[i].dwSemantic)==
  823. DISEM_TYPE_GET(DISEM_TYPE_AXIS))
  824. p=_T("DISEM_TYPE_AXIS");
  825. else if(DISEM_TYPE_GET(lpVal->rgoAction[i].dwSemantic)==
  826. DISEM_TYPE_GET(DISEM_TYPE_BUTTON))
  827. p=_T("DISEM_TYPE_BUTTON");
  828. else if(DISEM_TYPE_GET(lpVal->rgoAction[i].dwSemantic)==
  829. DISEM_TYPE_GET(DISEM_TYPE_POV))
  830. p=_T("DISEM_TYPE_POV");
  831. else
  832. p=_T("");
  833. TRACE(_T("%u\t0x%x\t%u\t%u %s\t0x%x\t0x%x\t0x%x\t"),
  834. i,
  835. (unsigned int)lpVal->rgoAction[i].dwSemantic,
  836. (unsigned int)DISEM_INDEX_GET
  837. (lpVal->rgoAction[i].dwSemantic),
  838. (unsigned int)DISEM_TYPE_GET
  839. (lpVal->rgoAction[i].dwSemantic),p,
  840. (unsigned int)lpVal->rgoAction[i].dwFlags,
  841. (unsigned int)lpVal->rgoAction[i].dwObjID,
  842. (unsigned int)lpVal->rgoAction[i].dwHow);
  843. TRACEGUID(lpVal->rgoAction[i].guidInstance);
  844. }
  845. }
  846. }
  847. }
  848. void CAdvancedTracer::Dump(LPCTSTR szName,LPDIDEVICEIMAGEINFOHEADER lpVal)
  849. {
  850. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  851. TRACE(_T("%s=0x%p\n"),szName,lpVal);
  852. if(lpVal)
  853. {
  854. USETRACER();
  855. TRACE(_T("dwSize=%u\tdwSizeImageInfo=%u\n"),
  856. (unsigned int)lpVal->dwSize,
  857. (unsigned int)lpVal->dwSizeImageInfo);
  858. TRACE(_T("dwcViews=%u\tdwcButtons=%u\n"),
  859. (unsigned int)lpVal->dwcViews,
  860. (unsigned int)lpVal->dwcButtons);
  861. TRACE(_T("dwcAxes=%u\tdwcPOVs=%u\n"),
  862. (unsigned int)lpVal->dwcAxes,
  863. (unsigned int)lpVal->dwcPOVs);
  864. TRACE(_T("dwBufferSize=%u\tdwBufferUsed=%u\n"),
  865. (unsigned int)lpVal->dwBufferSize,
  866. (unsigned int)lpVal->dwBufferUsed);
  867. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  868. TRACE(_T("lprgImageInfoArray=0x%p\n"),lpVal->lprgImageInfoArray);
  869. if(lpVal->lprgImageInfoArray)
  870. {
  871. USETRACER();
  872. TRACE(_T("tszImagePath\ndwFlags\tdwViewID\trcOverlay\tdwObjID\t\
  873. dwcValidPts\trcCalloutRect\tdwTextAlign\n"));
  874. for(DWORD i=0;i<(lpVal->dwBufferSize/
  875. sizeof(lpVal->lprgImageInfoArray[0]));i++)
  876. {
  877. TCHAR tszImagePath[MAX_PATH];
  878. memcpy(&tszImagePath,
  879. &lpVal->lprgImageInfoArray[i].tszImagePath,
  880. sizeof(tszImagePath));
  881. tszImagePath[MAX_PATH-1]=0;
  882. TRACE(_T("%s\n"),&tszImagePath);
  883. TRACE(_T("0x%x\t"),lpVal->lprgImageInfoArray[i].dwFlags);
  884. TRACE(_T("%u\t"),lpVal->lprgImageInfoArray[i].dwViewID);
  885. TRACE(_T("[%u,%u],[%u,%u]\t"),
  886. lpVal->lprgImageInfoArray[i].rcOverlay.left,
  887. lpVal->lprgImageInfoArray[i].rcOverlay.top,
  888. lpVal->lprgImageInfoArray[i].rcOverlay.right,
  889. lpVal->lprgImageInfoArray[i].rcOverlay.bottom);
  890. TRACE(_T("0x%x\t"),lpVal->lprgImageInfoArray[i].dwObjID);
  891. TRACE(_T("%u\t"),lpVal->lprgImageInfoArray[i].dwcValidPts);
  892. const int nPnts=
  893. sizeof(lpVal->lprgImageInfoArray[i].rgptCalloutLine)/
  894. sizeof(lpVal->lprgImageInfoArray[i].rgptCalloutLine[0]);
  895. TRACE(_T("[%u,%u],[%u,%u]\t"),
  896. lpVal->lprgImageInfoArray[i].rcCalloutRect.left,
  897. lpVal->lprgImageInfoArray[i].rcCalloutRect.top,
  898. lpVal->lprgImageInfoArray[i].rcCalloutRect.right,
  899. lpVal->lprgImageInfoArray[i].rcCalloutRect.bottom);
  900. TRACE(_T("0x%x\n"),lpVal->lprgImageInfoArray[i].dwTextAlign);
  901. }
  902. }
  903. }
  904. }
  905. void CAdvancedTracer::Dump(LPCTSTR szName,LPCTSTR lpVal)
  906. {
  907. if(lpVal)
  908. TRACE(_T("%s=%s\n"),szName,lpVal);
  909. else
  910. TRACE(_T("%s=NULL\n"),szName);
  911. }
  912. void CAdvancedTracer::Dump(LPCTSTR szName,LPTSTR lpVal)
  913. {
  914. Dump(szName,(LPCTSTR)lpVal);
  915. }
  916. void CAdvancedTracer::Dump(LPCTSTR szName,LPCDIDEVICEOBJECTINSTANCE lpVal)
  917. {
  918. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  919. TRACE(_T("%s=0x%p\n"),szName,lpVal);
  920. if(lpVal)
  921. {
  922. USETRACER();
  923. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  924. TRACE(_T("tszName=0x%p\n"),lpVal->tszName);
  925. if(lpVal->tszName)
  926. {
  927. USETRACER();
  928. TRACE(_T("%s\n"),lpVal->tszName);
  929. }
  930. TRACE(_T("dwOfs=%u\n"),(unsigned int)lpVal->dwOfs);
  931. TRACE(_T("wUsagePage=%u\n"),(unsigned int)lpVal->wUsagePage);
  932. TRACE(_T("wUsage=%u\n"),(unsigned int)lpVal->wUsage);
  933. TRACE(_T("dwType=%u\n"),(unsigned int)lpVal->dwType);
  934. if(lpVal->dwType&DIDFT_RELAXIS)
  935. TRACE(_T("dwType&=DIDFT_RELAXIS\n"));
  936. if(lpVal->dwType&DIDFT_ABSAXIS)
  937. TRACE(_T("dwType&=DIDFT_ABSAXIS\n"));
  938. if(lpVal->dwType&DIDFT_PSHBUTTON)
  939. TRACE(_T("dwType&=DIDFT_PSHBUTTON\n"));
  940. if(lpVal->dwType&DIDFT_TGLBUTTON)
  941. TRACE(_T("dwType&=DIDFT_TGLBUTTON\n"));
  942. if(lpVal->dwType&DIDFT_POV)
  943. TRACE(_T("dwType&=DIDFT_POV\n"));
  944. }
  945. }
  946. void CAdvancedTracer::Dump(LPCTSTR szName,const GUID &guid)
  947. {
  948. TRACE(_T("%s="),szName);
  949. OutputDebugGuid(guid);
  950. }
  951. void CAdvancedTracer::Dump(LPCTSTR szName,LPCGUID lpVal)
  952. {
  953. if(lpVal)
  954. {
  955. TRACE(_T("%s="),szName);
  956. OutputDebugGuid(*lpVal);
  957. }
  958. else
  959. TRACE(_T("%s=NULL\n"),szName);
  960. }
  961. void OutputDebugGuid(const GUID &guid)
  962. {
  963. TRACE(_T("{%08X-%04hX-%04hX-%02hX%02hX-%02X%02X%02X%02X%02X%02X}\n"),
  964. guid.Data1,
  965. guid.Data2,
  966. guid.Data3,
  967. (WORD)guid.Data4[0], (WORD)guid.Data4[1],
  968. (WORD)guid.Data4[2], (WORD)guid.Data4[3],
  969. (WORD)guid.Data4[4], (WORD)guid.Data4[5],
  970. (WORD)guid.Data4[6], (WORD)guid.Data4[7]);
  971. }
  972. #endif //_CHECKED
  973. /******************************************************************************
  974. *
  975. * Exception Handler
  976. *
  977. *****************************************************************************/
  978. MapException::MapException(
  979. #ifdef _CHECKED
  980. LPCTSTR lpSourceFile,DWORD dwLine,
  981. #endif
  982. HRESULT hRes)
  983. {
  984. m_hRes=hRes;
  985. EXCEPTION(lpSourceFile,dwLine,hRes);
  986. }
  987. /******************************************************************************
  988. *
  989. * String Processing
  990. *
  991. *****************************************************************************/
  992. void ToUpper(String &S)
  993. {
  994. CharUpperBuff((LPTSTR)S.data(),S.size());
  995. for(StrIter B=S.begin();B<S.end();B++)
  996. {
  997. if(!IsSpace(*B))break;
  998. }
  999. for(StrIter E=S.end();E>S.begin();E--)
  1000. {
  1001. if(!(IsSpace(*(E-1))||(0==*(E-1))))break;
  1002. }
  1003. String R;
  1004. while(B<E)
  1005. {
  1006. if(*B)
  1007. R+=*B;
  1008. B++;
  1009. }
  1010. S=R;
  1011. }
  1012. String GUID2String(const GUID &G)
  1013. {
  1014. String Ret;
  1015. OLECHAR S[256];
  1016. if(!StringFromGUID2(G,S,255))
  1017. throw MAP_EXCEPTION(E_OUTOFMEMORY);
  1018. S[255]=0;
  1019. int i;
  1020. for(i=0;i<256;i++)
  1021. {
  1022. if(!S[i])break;
  1023. Ret+=(TCHAR)__toascii(S[i]);
  1024. }
  1025. ToUpper(Ret);
  1026. return Ret;
  1027. }
  1028. String N2Str(DWORD N)
  1029. {
  1030. String Ret;
  1031. _TCHAR S[32];
  1032. if(_sntprintf(S,32,_T("%d"),N)<0)
  1033. throw MAP_EXCEPTION(E_OUTOFMEMORY);
  1034. S[31]=0;
  1035. Ret=S;
  1036. return Ret;
  1037. }
  1038. void SkipWS(StrIter &Pos)
  1039. {
  1040. while(IsSpace(*Pos))
  1041. Pos++;
  1042. }
  1043. BOOL IsComma(StrIter &Pos)
  1044. {
  1045. if(*Pos==SEPARATOR)
  1046. {
  1047. Pos++;
  1048. return TRUE;
  1049. }
  1050. return FALSE;
  1051. }
  1052. void Eat(StrIter &Pos,TCHAR Ch)
  1053. {
  1054. if(*Pos!=Ch)
  1055. {
  1056. TRACE(_T("Error in ini file, key value.\n"));
  1057. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1058. }
  1059. Pos++;
  1060. }
  1061. DWORD GetNum(StrIter &Pos)
  1062. {
  1063. DWORD dwRet=0;
  1064. String S;
  1065. StrIter OldPos;
  1066. OldPos=Pos;
  1067. //Read each character, verify it is a number and append
  1068. while(isdigit(*Pos))
  1069. {
  1070. S+=*Pos;
  1071. Pos++;
  1072. }
  1073. if(Pos==OldPos)//There must be a string
  1074. {
  1075. TRACE(_T("Error in ini file, in key numeric value.\n"));
  1076. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1077. }
  1078. int nR=_stscanf(S.data(),_T("%d"),&dwRet);
  1079. if((nR==EOF)||(nR=0))
  1080. {
  1081. TRACE(_T("Error in ini file, in key numeric value.\n"));
  1082. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1083. }
  1084. return dwRet;
  1085. }
  1086. bool ReadString(StrIter &Pos,String &S,bool bNoStringOK=false)
  1087. {
  1088. StrIter OldPos;
  1089. //String has no white spaces
  1090. OldPos=Pos;
  1091. //Read each character, verify it is a string character and append
  1092. while(!((*Pos==SEPARATOR)||(*Pos==0)))
  1093. {
  1094. S+=*Pos;
  1095. Pos++;
  1096. }
  1097. if(Pos==OldPos)//If no string
  1098. {
  1099. if(!bNoStringOK)
  1100. {
  1101. TRACE(_T("Error in ini file, in key string.\n"));
  1102. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1103. }
  1104. else
  1105. return false;
  1106. }
  1107. return true;
  1108. }
  1109. bool LoadString(String &S,LPCTSTR lpFileName,LPCTSTR lpSectionName,
  1110. LPCTSTR lpKeyName,bool bNoThrow=false)
  1111. {
  1112. METHOD_ENTRY(LoadString);
  1113. DUMP(lpFileName);
  1114. DUMP(lpSectionName);
  1115. DUMP(lpKeyName);
  1116. //Load line from a file
  1117. TCHAR L[1024];
  1118. if(GetPrivateProfileString(lpSectionName,lpKeyName,RESERVED_STRING,
  1119. L,1024,lpFileName)==1023)
  1120. {
  1121. TRACE(_T("Line in file is too long.\n"));
  1122. throw MAP_EXCEPTION(E_LINE_TO_LONG);
  1123. }
  1124. L[1023]=0;
  1125. String Line=L;
  1126. if((Line==RESERVED_STRING)||(Line==_T("")))
  1127. {
  1128. if(!bNoThrow)
  1129. {
  1130. TRACE(_T("No such section, key or key is empty.\n"));
  1131. throw MAP_EXCEPTION(E_DEFINITION_NOT_FOUND);
  1132. }
  1133. else
  1134. return false;
  1135. }
  1136. S=_T("");
  1137. StrIter Pos=Line.begin();
  1138. //Read single string
  1139. ReadString(Pos,S);
  1140. //To upper case and throw away spaces infront and back
  1141. ToUpper(S);
  1142. if(S==_T(""))//There must be a string
  1143. {
  1144. TRACE(_T("No such section, key or key is empty.\n"));
  1145. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1146. }
  1147. //Must end with 0
  1148. if(*Pos!=0)
  1149. {
  1150. TRACE(_T("String corrupted.\n"));
  1151. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1152. }
  1153. return true;
  1154. }
  1155. bool LoadPointArray(LPCTSTR lpFileName,LPCTSTR lpSectionName,
  1156. LPCTSTR lpKeyName,LPPOINT pPt,DWORD &dwCount,DWORD dwSize)
  1157. {
  1158. METHOD_ENTRY(LoadPointArray);
  1159. DUMP(lpFileName);
  1160. DUMP(lpSectionName);
  1161. DUMP(lpKeyName);
  1162. dwCount=0;
  1163. //Load line with strings
  1164. TCHAR L[1024];
  1165. if(GetPrivateProfileString(lpSectionName,lpKeyName,RESERVED_STRING,
  1166. L,1024,lpFileName)==1023)
  1167. {
  1168. TRACE(_T("Line in file is too long.\n"));
  1169. throw MAP_EXCEPTION(E_LINE_TO_LONG);
  1170. }
  1171. L[1023]=0;
  1172. String Line=L;
  1173. if((Line==RESERVED_STRING)||(Line==_T("")))
  1174. return false;
  1175. ToUpper(Line);
  1176. StrIter Pos=Line.begin();
  1177. do
  1178. {
  1179. if(dwCount==dwSize)
  1180. break;
  1181. SkipWS(Pos);
  1182. Eat(Pos,_T('('));
  1183. pPt[dwCount].x=GetNum(Pos);
  1184. SkipWS(Pos);
  1185. Eat(Pos,_T(','));
  1186. SkipWS(Pos);
  1187. pPt[dwCount].y=GetNum(Pos);
  1188. SkipWS(Pos);
  1189. Eat(Pos,_T(')'));
  1190. SkipWS(Pos);
  1191. dwCount++;
  1192. //Repeat while comma is found
  1193. }while(IsComma(Pos));
  1194. // if(!dwCount)
  1195. // throw MAP_EXCEPTION4(E_SYNTAX_ERROR);
  1196. return true;
  1197. }
  1198. bool LoadListOfStrings(LPCTSTR lpFileName,LPCTSTR lpSectionName,
  1199. LPCTSTR lpKeyName,STRINGLIST &StrList,
  1200. bool bNoThrow=false)
  1201. {
  1202. METHOD_ENTRY(LoadListOfStrings);
  1203. DUMP(lpFileName);
  1204. DUMP(lpSectionName);
  1205. DUMP(lpKeyName);
  1206. //Load line with strings
  1207. TCHAR L[1024];
  1208. if(GetPrivateProfileString(lpSectionName,lpKeyName,RESERVED_STRING,
  1209. L,1024,lpFileName)==1023)
  1210. {
  1211. TRACE(_T("Line in file is too long.\n"));
  1212. throw MAP_EXCEPTION(E_LINE_TO_LONG);
  1213. }
  1214. L[1023]=0;
  1215. String Line=L;
  1216. if((Line==RESERVED_STRING)||(Line==_T("")))
  1217. {
  1218. if(!bNoThrow)
  1219. {
  1220. TRACE(_T("No such section, key or key is empty.\n"));
  1221. throw MAP_EXCEPTION(E_DEFINITION_NOT_FOUND);
  1222. }
  1223. else
  1224. return false;
  1225. }
  1226. StrIter Pos=Line.begin();
  1227. CS S;
  1228. //Read first string, must be there
  1229. ReadString(Pos,S);
  1230. //To upper case and throw away spaces infront and back
  1231. ToUpper(S);
  1232. if(S==_T(""))//There must be a string
  1233. {
  1234. TRACE(_T("No such section, key or key is empty.\n"));
  1235. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1236. }
  1237. //Store string into the list
  1238. StrList.push_back(S);
  1239. //Repeat while comma is found
  1240. while(IsComma(Pos))
  1241. {
  1242. CS S;
  1243. //Read next string, does not have to be there
  1244. if(ReadString(Pos,S,true))
  1245. {
  1246. //String found
  1247. //To upper case and throw away spaces infront and back
  1248. ToUpper(S);
  1249. //Check if string, if no cont.
  1250. if(S==_T(""))
  1251. continue;
  1252. //Store string into the list
  1253. StrList.push_back(S);
  1254. }
  1255. }
  1256. if(*Pos!=0)//Must end with 0
  1257. {
  1258. TRACE(_T("Corrupt string list.\n"));
  1259. throw MAP_EXCEPTION(E_SYNTAX_ERROR);
  1260. }
  1261. return true;
  1262. }
  1263. void WritePrivateProfileIntX(LPCTSTR lpAppName,LPCTSTR lpKeyName,
  1264. UINT Value,LPCTSTR lpFileName)
  1265. {
  1266. METHOD_ENTRY(WritePrivateProfileIntX);
  1267. DUMP(lpFileName);
  1268. DUMP(lpAppName);
  1269. DUMP(lpKeyName);
  1270. TCHAR ValBuf[16];
  1271. wsprintf(ValBuf,TEXT("0x%X"),Value);
  1272. if(!WritePrivateProfileString(lpAppName,lpKeyName,
  1273. ValBuf,lpFileName))
  1274. {
  1275. TRACE(_T("Error writing ini file.\n"));
  1276. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1277. }
  1278. }
  1279. void WritePrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,
  1280. INT Value,LPCTSTR lpFileName)
  1281. {
  1282. METHOD_ENTRY(WritePrivateProfileInt);
  1283. DUMP(lpFileName);
  1284. DUMP(lpAppName);
  1285. DUMP(lpKeyName);
  1286. TCHAR ValBuf[16];
  1287. wsprintf(ValBuf,TEXT("%i"),Value);
  1288. if(!WritePrivateProfileString(lpAppName,lpKeyName,
  1289. ValBuf,lpFileName))
  1290. {
  1291. TRACE(_T("Error writing ini file.\n"));
  1292. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1293. }
  1294. }
  1295. void WriteRect(LPCTSTR pSection,LPCTSTR pKey,LPRECT pR,LPCTSTR pFile)
  1296. {
  1297. METHOD_ENTRY(WriteRect);
  1298. DUMP(pFile);
  1299. DUMP(pSection);
  1300. DUMP(pKey);
  1301. String Rect;
  1302. Rect+=_T("(")+N2Str(pR->left)+_T(",")+N2Str(pR->top)+
  1303. _T("),(")+N2Str(pR->right)+_T(",")+N2Str(pR->bottom)+_T(")");
  1304. if(!WritePrivateProfileString(pSection,pKey,Rect.data(),pFile))
  1305. {
  1306. TRACE(_T("Error writing ini file.\n"));
  1307. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1308. }
  1309. }
  1310. void WritePointArray(LPCTSTR pSection,LPCTSTR pKey,LPPOINT pP,
  1311. int N,LPCTSTR pFile)
  1312. {
  1313. METHOD_ENTRY(WritePointArray);
  1314. DUMP(pFile);
  1315. DUMP(pSection);
  1316. DUMP(pKey);
  1317. String LineData;
  1318. for(DWORD i=0;i<N;i++)
  1319. {
  1320. LineData+=_T("(")+N2Str(pP[i].x)+_T(",")+N2Str(pP[i].y)+_T(")");
  1321. if(i<(N-1))
  1322. LineData+=_T(",");
  1323. }
  1324. if(!WritePrivateProfileString(pSection,pKey,LineData.data(),pFile))
  1325. {
  1326. TRACE(_T("Error writing ini file.\n"));
  1327. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1328. }
  1329. }
  1330. void WriteListOfStrings(LPCTSTR pSection,LPCTSTR pKey,
  1331. STRINGLIST &Values,LPCTSTR pFile)
  1332. {
  1333. METHOD_ENTRY(WriteListOfStrings);
  1334. DUMP(pFile);
  1335. DUMP(pSection);
  1336. DUMP(pKey);
  1337. if(!Values.size())return;
  1338. String List;
  1339. List=*Values.begin();
  1340. STRINGLIST::iterator ValuesIt=Values.begin();
  1341. ValuesIt++;
  1342. for(;ValuesIt!=Values.end();ValuesIt++)
  1343. List=List+_T(",")+*ValuesIt;
  1344. if(!WritePrivateProfileString(pSection,pKey,List.data(),pFile))
  1345. {
  1346. TRACE(_T("Error writing ini file.\n"));
  1347. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1348. }
  1349. }
  1350. void MakeUniqueName(String &InitialName,STRINGLIST &Names)
  1351. {
  1352. METHOD_ENTRY(MakeUniqueName);
  1353. for(int i=0;i<10000;i++)
  1354. {
  1355. CS S;
  1356. S.assign(InitialName);
  1357. if(i)
  1358. {
  1359. S+=_T("_");;
  1360. S+=N2Str(i);
  1361. }
  1362. if(find(Names.begin(),Names.end(),S)==Names.end())
  1363. {
  1364. InitialName=S;
  1365. Names.push_back(S);
  1366. break;
  1367. }
  1368. }
  1369. if(i==10000)//Could not find unique name after 10000 tries ???!!!
  1370. {
  1371. TRACE(_T("Could not generate unique name!?!?\n"));
  1372. throw MAP_EXCEPTION(E_DEVICE_NOT_DEFINED);
  1373. }
  1374. }
  1375. /******************************************************************************
  1376. *
  1377. * Directory/filename functions
  1378. *
  1379. *****************************************************************************/
  1380. void GetDirectory(LPCTSTR lpFullName,String &FullDir)
  1381. {
  1382. if(lpFullName)
  1383. {
  1384. TCHAR Drive[_MAX_DRIVE];Drive[0]=0;
  1385. TCHAR Dir[_MAX_DIR];Dir[0]=0;
  1386. // TCHAR FName[_MAX_FNAME];
  1387. // TCHAR Ext[_MAX_EXT];
  1388. _tsplitpath(lpFullName,Drive,Dir,NULL,NULL);
  1389. FullDir=Drive;
  1390. FullDir+=Dir;
  1391. }
  1392. }
  1393. void StripDirectory(LPCTSTR lpFullName,String &FileName)
  1394. {
  1395. if(lpFullName)
  1396. {
  1397. // TCHAR Drive[_MAX_DRIVE];Drive[0]=0;
  1398. // TCHAR Dir[_MAX_DIR];Dir[0]=0;
  1399. TCHAR FName[_MAX_FNAME];
  1400. TCHAR Ext[_MAX_EXT];
  1401. _tsplitpath(lpFullName,NULL,NULL,FName,Ext);
  1402. FileName=FName;
  1403. FileName+=Ext;
  1404. }
  1405. }
  1406. void GetHexCode(String &Ret,char In)
  1407. {
  1408. switch(In&0x0f)
  1409. {
  1410. case 0x00:Ret+=_T('0');break;
  1411. case 0x01:Ret+=_T('1');break;
  1412. case 0x02:Ret+=_T('2');break;
  1413. case 0x03:Ret+=_T('3');break;
  1414. case 0x04:Ret+=_T('4');break;
  1415. case 0x05:Ret+=_T('5');break;
  1416. case 0x06:Ret+=_T('6');break;
  1417. case 0x07:Ret+=_T('7');break;
  1418. case 0x08:Ret+=_T('8');break;
  1419. case 0x09:Ret+=_T('9');break;
  1420. case 0x0A:Ret+=_T('A');break;
  1421. case 0x0B:Ret+=_T('B');break;
  1422. case 0x0C:Ret+=_T('C');break;
  1423. case 0x0D:Ret+=_T('D');break;
  1424. case 0x0E:Ret+=_T('E');break;
  1425. case 0x0F:Ret+=_T('F');break;
  1426. }
  1427. }
  1428. void MakeUniqueUserName(String &Ret,
  1429. LPCTSTR pIn)
  1430. {
  1431. Ret=_T("");
  1432. for(const TCHAR *p=pIn;*p!=0;p++)
  1433. {
  1434. switch(*p)
  1435. {
  1436. case _T('A'):
  1437. case _T('a'):Ret+=_T('A');break;
  1438. case _T('B'):
  1439. case _T('b'):Ret+=_T('B');break;
  1440. case _T('C'):
  1441. case _T('c'):Ret+=_T('C');break;
  1442. case _T('D'):
  1443. case _T('d'):Ret+=_T('D');break;
  1444. case _T('E'):
  1445. case _T('e'):Ret+=_T('E');break;
  1446. case _T('F'):
  1447. case _T('f'):Ret+=_T('F');break;
  1448. case _T('G'):
  1449. case _T('g'):Ret+=_T('G');break;
  1450. case _T('H'):
  1451. case _T('h'):Ret+=_T('H');break;
  1452. case _T('I'):
  1453. case _T('i'):Ret+=_T('I');break;
  1454. case _T('J'):
  1455. case _T('j'):Ret+=_T('J');break;
  1456. case _T('K'):
  1457. case _T('k'):Ret+=_T('K');break;
  1458. case _T('L'):
  1459. case _T('l'):Ret+=_T('L');break;
  1460. case _T('M'):
  1461. case _T('m'):Ret+=_T('M');break;
  1462. case _T('N'):
  1463. case _T('n'):Ret+=_T('N');break;
  1464. case _T('O'):
  1465. case _T('o'):Ret+=_T('O');break;
  1466. case _T('P'):
  1467. case _T('p'):Ret+=_T('P');break;
  1468. case _T('Q'):
  1469. case _T('q'):Ret+=_T('Q');break;
  1470. case _T('R'):
  1471. case _T('r'):Ret+=_T('R');break;
  1472. case _T('S'):
  1473. case _T('s'):Ret+=_T('S');break;
  1474. case _T('T'):
  1475. case _T('t'):Ret+=_T('T');break;
  1476. case _T('U'):
  1477. case _T('u'):Ret+=_T('U');break;
  1478. case _T('V'):
  1479. case _T('v'):Ret+=_T('V');break;
  1480. case _T('W'):
  1481. case _T('w'):Ret+=_T('W');break;
  1482. //X: Special case. Make sure it is consistent
  1483. //with special case elsewhere.
  1484. case _T('X'):
  1485. case _T('x'):Ret+=_T("XX");break;
  1486. case _T('Y'):
  1487. case _T('y'):Ret+=_T('Y');break;
  1488. case _T('Z'):
  1489. case _T('z'):Ret+=_T('Z');break;
  1490. case _T('1'):Ret+=_T('1');break;
  1491. case _T('2'):Ret+=_T('2');break;
  1492. case _T('3'):Ret+=_T('3');break;
  1493. case _T('4'):Ret+=_T('4');break;
  1494. case _T('5'):Ret+=_T('5');break;
  1495. case _T('6'):Ret+=_T('6');break;
  1496. case _T('7'):Ret+=_T('7');break;
  1497. case _T('8'):Ret+=_T('8');break;
  1498. case _T('9'):Ret+=_T('9');break;
  1499. case _T('0'):Ret+=_T('0');break;
  1500. case _T(' '):Ret+=_T(' ');break;
  1501. case _T('('):Ret+=_T('(');break;
  1502. case _T(')'):Ret+=_T(')');break;
  1503. case _T('.'):Ret+=_T('.');break;
  1504. case _T('_'):Ret+=_T('_');break;
  1505. case _T('-'):Ret+=_T('-');break;
  1506. case _T('&'):Ret+=_T('&');break;
  1507. default:
  1508. //X: Special case. Make sure it is consistent
  1509. //with special case elsewhere.
  1510. Ret+=_T("X");
  1511. GetHexCode(Ret,(*p)>>12);
  1512. GetHexCode(Ret,(*p)>>8);
  1513. GetHexCode(Ret,(*p)>>4);
  1514. GetHexCode(Ret,*p);
  1515. break;
  1516. }
  1517. }
  1518. }
  1519. void MakeUniqueDeviceName(String &Ret,
  1520. LPCWSTR pIn/*This is hardcoded in dinput to WSTR*/)
  1521. {
  1522. Ret=_T("");
  1523. for(LPCWCH p=pIn;*p!=0;p++)
  1524. {
  1525. switch(*p)
  1526. {
  1527. case L'A':
  1528. case L'a':Ret+=_T('A');break;
  1529. case L'B':
  1530. case L'b':Ret+=_T('B');break;
  1531. case L'C':
  1532. case L'c':Ret+=_T('C');break;
  1533. case L'D':
  1534. case L'd':Ret+=_T('D');break;
  1535. case L'E':
  1536. case L'e':Ret+=_T('E');break;
  1537. case L'F':
  1538. case L'f':Ret+=_T('F');break;
  1539. case L'G':
  1540. case L'g':Ret+=_T('G');break;
  1541. case L'H':
  1542. case L'h':Ret+=_T('H');break;
  1543. case L'I':
  1544. case L'i':Ret+=_T('I');break;
  1545. case L'J':
  1546. case L'j':Ret+=_T('J');break;
  1547. case L'K':
  1548. case L'k':Ret+=_T('K');break;
  1549. case L'L':
  1550. case L'l':Ret+=_T('L');break;
  1551. case L'M':
  1552. case L'm':Ret+=_T('M');break;
  1553. case L'N':
  1554. case L'n':Ret+=_T('N');break;
  1555. case L'O':
  1556. case L'o':Ret+=_T('O');break;
  1557. case L'P':
  1558. case L'p':Ret+=_T('P');break;
  1559. case L'Q':
  1560. case L'q':Ret+=_T('Q');break;
  1561. case L'R':
  1562. case L'r':Ret+=_T('R');break;
  1563. case L'S':
  1564. case L's':Ret+=_T('S');break;
  1565. case L'T':
  1566. case L't':Ret+=_T('T');break;
  1567. case L'U':
  1568. case L'u':Ret+=_T('U');break;
  1569. case L'V':
  1570. case L'v':Ret+=_T('V');break;
  1571. case L'W':
  1572. case L'w':Ret+=_T('W');break;
  1573. //X: Special case. Make sure it is consistent
  1574. //with special case elsewhere.
  1575. case L'X':
  1576. case L'x':Ret+=_T("XX");break;
  1577. case L'Y':
  1578. case L'y':Ret+=_T('Y');break;
  1579. case L'Z':
  1580. case L'z':Ret+=_T('Z');break;
  1581. case L'1':Ret+=_T('1');break;
  1582. case L'2':Ret+=_T('2');break;
  1583. case L'3':Ret+=_T('3');break;
  1584. case L'4':Ret+=_T('4');break;
  1585. case L'5':Ret+=_T('5');break;
  1586. case L'6':Ret+=_T('6');break;
  1587. case L'7':Ret+=_T('7');break;
  1588. case L'8':Ret+=_T('8');break;
  1589. case L'9':Ret+=_T('9');break;
  1590. case L'0':Ret+=_T('0');break;
  1591. case L' ':Ret+=_T(' ');break;
  1592. case L'(':Ret+=_T('(');break;
  1593. case L')':Ret+=_T(')');break;
  1594. case L'.':Ret+=_T('.');break;
  1595. case L'_':Ret+=_T('_');break;
  1596. case L'-':Ret+=_T('-');break;
  1597. case L'&':Ret+=_T('&');break;
  1598. default:
  1599. //X: Special case. Make sure it is consistent
  1600. //with special case elsewhere.
  1601. Ret+=_T("X");
  1602. GetHexCode(Ret,(*p)>>12);
  1603. GetHexCode(Ret,(*p)>>8);
  1604. GetHexCode(Ret,(*p)>>4);
  1605. GetHexCode(Ret,*p);
  1606. break;
  1607. }
  1608. }
  1609. }
  1610. void MakeSubDir(LPCTSTR lpDir)
  1611. {
  1612. String DirCreationString=lpDir;
  1613. DirCreationString+=_T("\\");
  1614. LPTSTR lpPos=_tcschr(DirCreationString.data(),_T('\\'));
  1615. if(!lpPos)
  1616. {
  1617. TRACE(_T("Error creating user directory. Invalid parent directory.\n"));
  1618. throw MAP_EXCEPTION(E_FAIL);
  1619. }
  1620. lpPos=_tcschr(lpPos+1,_T('\\'));
  1621. if(!lpPos)
  1622. {
  1623. TRACE(_T("Error creating user directory. Invalid parent directory.\n"));
  1624. throw MAP_EXCEPTION(E_FAIL);
  1625. }
  1626. while(lpPos)
  1627. {
  1628. *lpPos=0;
  1629. if(!CreateDirectory(DirCreationString.data(),NULL))
  1630. {
  1631. DWORD dwErr=GetLastError();
  1632. if(dwErr!=ERROR_ALREADY_EXISTS)
  1633. {
  1634. TRACE(_T("Error creating user directory.\n"));
  1635. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(dwErr));
  1636. }
  1637. }
  1638. *lpPos=_T('\\');
  1639. lpPos=_tcschr(lpPos+1,_T('\\'));
  1640. }
  1641. }
  1642. void GetMapFileName(LPCTSTR lpctstrUserName,LPCTSTR lpctstrDeviceName,
  1643. int nDeviceInstanceNo,
  1644. LPTSTR szFileName/*_MAX_PATH*/,bool bCreateDir=false,
  1645. String *lpUserDir=NULL)
  1646. {
  1647. //Allocate a pointer to an Item ID list
  1648. LPITEMIDLIST pidl;
  1649. //Get a pointer to an item ID list that
  1650. //represents the path of a special folder
  1651. HRESULT hRes=S_OK;
  1652. DWORD dwVersion=GetVersion();
  1653. if(dwVersion<0x80000000)// Windows NT
  1654. {
  1655. // hRes=SHGetSpecialFolderLocation(NULL,CSIDL_COMMON_APPDATA,&pidl);
  1656. hRes=SHGetSpecialFolderLocation(NULL,CSIDL_PROGRAM_FILES_COMMON,&pidl);
  1657. if(FAILED(hRes))
  1658. {
  1659. TRACE(_T("Error calling SHGetSpecialFolderLocation().\n"));
  1660. throw MAP_EXCEPTION(hRes);
  1661. }
  1662. //Convert the item ID list's binary
  1663. //representation into a file system path
  1664. if(!SHGetPathFromIDList(pidl,szFileName))
  1665. {
  1666. TRACE(_T("Error calling SHGetPathFromIDList().\n"));
  1667. }
  1668. //Allocate a pointer to an IMalloc interface
  1669. LPMALLOC pMalloc=NULL;
  1670. //Get the address of our task allocator's IMalloc interface
  1671. SHGetMalloc(&pMalloc);
  1672. if((hRes==NOERROR)&&pMalloc)
  1673. {
  1674. //Free the item ID list allocated by SHGetSpecialFolderLocation
  1675. pMalloc->Free(pidl);
  1676. //Free our task allocator
  1677. pMalloc->Release();
  1678. }
  1679. #ifdef _CHECKED
  1680. else
  1681. {
  1682. TRACE(_T("RESOURCE LEAK! SHGetMalloc failed, can not free resource.\n"));
  1683. }
  1684. #endif
  1685. }
  1686. else// WIn9x
  1687. {
  1688. //For win9x get directory name from the registry
  1689. HKEY Key=0;
  1690. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1691. _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
  1692. (DWORD)0,
  1693. KEY_QUERY_VALUE,
  1694. &Key)!=ERROR_SUCCESS)
  1695. {
  1696. TRACE(_T("Error calling RegOpenKeyEx(HKEY_LOCAL_MACHINE\
  1697. \\SOFTWARE\\Microsoft\\Windows\\CurrentVersion).\n"));
  1698. throw MAP_EXCEPTION(E_FAIL);
  1699. }
  1700. DWORD dwType=REG_SZ;
  1701. DWORD dwSize=MAX_PATH*sizeof(TCHAR);
  1702. if(RegQueryValueEx(Key,_T("CommonFilesDir"),
  1703. NULL,&dwType,(LPBYTE)szFileName,&dwSize)!=ERROR_SUCCESS)
  1704. {
  1705. TRACE(_T("Error calling RegQueryValueEx(CommonFilesDir).\n"));
  1706. throw MAP_EXCEPTION(E_FAIL);
  1707. }
  1708. RegCloseKey(Key);
  1709. }
  1710. String DirCreationString=szFileName;
  1711. //Check if directory name is too long
  1712. if((_tcslen(szFileName)+_tcslen(MAP_DIR)+1)>_MAX_PATH)
  1713. {
  1714. TRACE(_T("User dir name too long.\n"));
  1715. throw MAP_EXCEPTION(E_FAIL);
  1716. }
  1717. _tcscat(szFileName,MAP_DIR);
  1718. if(lpUserDir)*lpUserDir=szFileName;
  1719. //Create directory for map files
  1720. if(bCreateDir)
  1721. {
  1722. //Create subdirs one by one
  1723. TRACE(_T("Creating user directory %s.\n"),szFileName);
  1724. DirCreationString+=DIRECTX;
  1725. if(!CreateDirectory(DirCreationString.data(),NULL))
  1726. {
  1727. DWORD dwErr=GetLastError();
  1728. if(dwErr!=ERROR_ALREADY_EXISTS)
  1729. {
  1730. //could be that Win95 Gold does not have "Common Files" dir
  1731. MakeSubDir(DirCreationString.data());
  1732. // TRACE(_T("Error creating user directory.\n"));
  1733. // throw MAP_EXCEPTION(HRESULT_FROM_WIN32(dwErr));
  1734. }
  1735. }
  1736. DirCreationString+=DIRECTINPUT;
  1737. if(!CreateDirectory(DirCreationString.data(),NULL))
  1738. {
  1739. DWORD dwErr=GetLastError();
  1740. if(dwErr!=ERROR_ALREADY_EXISTS)
  1741. {
  1742. TRACE(_T("Error creating user directory.\n"));
  1743. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(dwErr));
  1744. }
  1745. }
  1746. DirCreationString+=USER_MAPS;
  1747. if(!CreateDirectory(DirCreationString.data(),NULL))
  1748. {
  1749. DWORD dwErr=GetLastError();
  1750. if(dwErr!=ERROR_ALREADY_EXISTS)
  1751. {
  1752. TRACE(_T("Error creating user directory.\n"));
  1753. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(dwErr));
  1754. }
  1755. }
  1756. }
  1757. //Create full path filename
  1758. //Get user name
  1759. TCHAR UN[UNLEN+1];
  1760. if(!lpctstrUserName)
  1761. {
  1762. DWORD dwLen=UNLEN+1;
  1763. GetUserName(UN,&dwLen);
  1764. lpctstrUserName=UN;
  1765. }
  1766. //Unique user name
  1767. String UniqueUserName;
  1768. MakeUniqueUserName(UniqueUserName,lpctstrUserName);
  1769. //Device instance string
  1770. String DevInst;
  1771. DevInst=N2Str(nDeviceInstanceNo);
  1772. if((_tcslen(szFileName)+1+_tcslen(UniqueUserName.data())+2+
  1773. _tcslen(lpctstrDeviceName)+2+
  1774. _tcslen(DevInst.data())+4+1)>_MAX_PATH)
  1775. {
  1776. TRACE(_T("User path file name too long.\n"));
  1777. throw MAP_EXCEPTION(E_FAIL);
  1778. }
  1779. _tcscat(szFileName,_T("\\"));
  1780. _tcscat(szFileName,UniqueUserName.data());
  1781. //X: Special case. Make sure it is consistent
  1782. //with special case elsewhere.
  1783. _tcscat(szFileName,_T("X_"));
  1784. _tcscat(szFileName,lpctstrDeviceName);
  1785. //X: Special case. Make sure it is consistent
  1786. //with special case elsewhere.
  1787. _tcscat(szFileName,_T("X_"));
  1788. _tcscat(szFileName,DevInst.data());
  1789. _tcscat(szFileName,_T(".INI"));
  1790. }
  1791. /******************************************************************************
  1792. *
  1793. * ANSI/UNICODE parameter translation templates
  1794. *
  1795. *****************************************************************************/
  1796. int TrCopy(LPCSTR pszA,size_t nCharacters,LPWSTR pszW,size_t nSizeW)
  1797. {return MultiByteToWideChar(CP_ACP,0,pszA,nCharacters,pszW,nSizeW);};
  1798. int TrCopy(LPCOLESTR pszW,size_t nCharacters,LPSTR pszA,size_t nSizeA)
  1799. {return WideCharToMultiByte(CP_ACP,0,pszW,nCharacters,
  1800. pszA,nSizeA,NULL,NULL);};
  1801. size_t TrSize(LPCSTR pszA,size_t nSizeA){return nSizeA;};
  1802. size_t TrSize(LPCWSTR pszW,size_t nSizeW){return nSizeW*2;};
  1803. size_t TrStrLen(LPCSTR pszA){return strlen(pszA);};
  1804. size_t TrStrLen(LPCWSTR pszW){return wcslen(pszW);};
  1805. template <class StrTypeFrom,class StrTypeTo>
  1806. void Tr(StrTypeFrom *pszFrom,size_t nSizeFrom,
  1807. StrTypeTo* pszTo,size_t nSizeTo)
  1808. {
  1809. if(!TrCopy(pszFrom,TrStrLen(pszFrom)+1,pszTo,nSizeTo))
  1810. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  1811. pszTo[nSizeTo-1]=0;
  1812. };
  1813. template <class StrTypeFrom,class StrTypeTo> class C2Base
  1814. {
  1815. protected:
  1816. StrTypeTo *m_pszStrTo;
  1817. size_t m_nSizeTo;
  1818. StrTypeFrom *m_pszStrFrom;
  1819. size_t m_nSizeFrom;
  1820. bool m_bReturn;
  1821. public:
  1822. C2Base(){m_pszStrTo=NULL;};
  1823. ~C2Base(){delete m_pszStrTo;};
  1824. operator StrTypeTo*(){return m_pszStrTo;};
  1825. size_t Size(){return m_nSizeTo;};
  1826. void Set(const StrTypeFrom *pszStrFrom=NULL,size_t nSizeFrom=-1)
  1827. {
  1828. //Delete old buffer
  1829. delete m_pszStrTo;
  1830. //Initialize members
  1831. m_pszStrTo=NULL;
  1832. m_nSizeTo=0;
  1833. m_pszStrFrom=(StrTypeFrom*)pszStrFrom;
  1834. m_nSizeFrom=nSizeFrom;
  1835. m_bReturn=false;
  1836. //Check if in string is 0
  1837. if((!m_pszStrFrom)||(!nSizeFrom))
  1838. {
  1839. m_nSizeFrom=0;
  1840. return;
  1841. }
  1842. //Get len of the in string
  1843. if(m_nSizeFrom==-1)
  1844. m_nSizeFrom=TrStrLen(m_pszStrFrom)+1;
  1845. //Allocate buffer for translated string
  1846. m_nSizeTo=TrSize(m_pszStrFrom,m_nSizeFrom);
  1847. m_pszStrTo=new StrTypeTo[m_nSizeTo];
  1848. if(m_nSizeTo)
  1849. m_pszStrTo[0]=0;
  1850. //Check if this is in or out param
  1851. if((nSizeFrom!=-1))
  1852. m_bReturn=true;
  1853. //Translate
  1854. if(!m_bReturn)
  1855. Tr(m_pszStrFrom,m_nSizeFrom,m_pszStrTo,m_nSizeTo);
  1856. }
  1857. };
  1858. template <class StrTypeFrom,class StrTypeTo> class C2:
  1859. public C2Base<StrTypeFrom,StrTypeTo>
  1860. {
  1861. public:
  1862. C2(const StrTypeFrom *pszStrFrom=NULL,size_t nSizeFrom=-1)
  1863. {Set(pszStrFrom,nSizeFrom);};
  1864. ~C2(){if(m_bReturn)
  1865. Tr(m_pszStrTo,m_nSizeTo,m_pszStrFrom,m_nSizeFrom);};
  1866. };
  1867. //This template translates between DIACTIONFORMATA and DIACTIONFORMATW
  1868. template <class IDFrom,class IDTo,class Act>
  1869. class CTrDIACTIONFORMAT:public IDTo
  1870. {
  1871. IDTo* m_pIDTo;
  1872. IDFrom* m_pIDFrom;
  1873. public:
  1874. CTrDIACTIONFORMAT(IDFrom *pIn)
  1875. {
  1876. m_pIDTo=NULL;
  1877. m_pIDFrom=pIn;
  1878. if(pIn)
  1879. {
  1880. dwSize=sizeof(IDTo);
  1881. dwActionSize=pIn->dwActionSize;
  1882. dwDataSize=0;
  1883. dwNumActions=pIn->dwNumActions;
  1884. guidActionMap=pIn->guidActionMap;
  1885. dwGenre=pIn->dwGenre;
  1886. rgoAction=(Act*)(pIn->rgoAction);
  1887. dwBufferSize=0;
  1888. lAxisMin=0;
  1889. lAxisMax=0;
  1890. hInstString=0;
  1891. tszActionMap[0]=0;
  1892. ftTimeStamp.dwLowDateTime=
  1893. pIn->ftTimeStamp.dwLowDateTime;
  1894. ftTimeStamp.dwHighDateTime=
  1895. pIn->ftTimeStamp.dwHighDateTime;
  1896. m_pIDTo=(IDTo*)this;
  1897. }
  1898. };
  1899. ~CTrDIACTIONFORMAT()
  1900. {
  1901. if(m_pIDFrom&&m_pIDTo)
  1902. {
  1903. m_pIDFrom->ftTimeStamp.dwLowDateTime=
  1904. m_pIDTo->ftTimeStamp.dwLowDateTime;
  1905. m_pIDFrom->ftTimeStamp.dwHighDateTime=
  1906. m_pIDTo->ftTimeStamp.dwHighDateTime;
  1907. }
  1908. }
  1909. operator IDTo*(){return m_pIDTo;};
  1910. };
  1911. //This templates translate between DIDEVICEIMAGEINFOHEADERA and
  1912. //DIDEVICEIMAGEINFOHEADERW
  1913. template <class IDTo> class CTrDIDEVICEIMAGEINFOHEADERB:public IDTo
  1914. {
  1915. public:
  1916. CTrDIDEVICEIMAGEINFOHEADERB(){lprgImageInfoArray=NULL;};
  1917. ~CTrDIDEVICEIMAGEINFOHEADERB(){delete lprgImageInfoArray;};
  1918. };
  1919. template <class StrTypeFrom,class StrTypeTo>
  1920. void TrDIDEVICEIMAGEINFO(StrTypeFrom *pszFrom,StrTypeTo* pszTo)
  1921. {
  1922. Tr(pszFrom->tszImagePath,
  1923. sizeof(pszFrom->tszImagePath)/sizeof(pszFrom->tszImagePath[0]),
  1924. pszTo->tszImagePath,
  1925. sizeof(pszTo->tszImagePath)/sizeof(pszTo->tszImagePath[0]));
  1926. pszTo->dwFlags=pszFrom->dwFlags;
  1927. pszTo->dwViewID=pszFrom->dwViewID;
  1928. pszTo->rcOverlay=pszFrom->rcOverlay;
  1929. pszTo->dwObjID=pszFrom->dwObjID;
  1930. pszTo->rgptCalloutLine[0]=pszFrom->rgptCalloutLine[0];
  1931. pszTo->rgptCalloutLine[1]=pszFrom->rgptCalloutLine[1];
  1932. pszTo->rgptCalloutLine[2]=pszFrom->rgptCalloutLine[2];
  1933. pszTo->rgptCalloutLine[3]=pszFrom->rgptCalloutLine[3];
  1934. pszTo->rgptCalloutLine[4]=pszFrom->rgptCalloutLine[4];
  1935. pszTo->dwcValidPts=pszFrom->dwcValidPts;
  1936. pszTo->rcCalloutRect=pszFrom->rcCalloutRect;
  1937. pszTo->dwTextAlign=pszFrom->dwTextAlign;
  1938. }
  1939. template <class IDFrom,class IDTo,class IDFromImgInfo,class IDToImgInfo>
  1940. class CTrDIDEVICEIMAGEINFOHEADER:public CTrDIDEVICEIMAGEINFOHEADERB<IDTo>
  1941. {
  1942. IDTo* m_pIDTo;
  1943. IDFrom* m_pIDFrom;
  1944. bool m_bGet;
  1945. public:
  1946. CTrDIDEVICEIMAGEINFOHEADER(IDFrom *pIn,bool bGet=true)
  1947. {
  1948. m_pIDTo=NULL;
  1949. m_pIDFrom=pIn;
  1950. m_bGet=bGet;
  1951. if(pIn)
  1952. {
  1953. memset((IDTo*)this,0,sizeof(IDTo));
  1954. if(pIn->dwSize==sizeof(IDFrom))
  1955. dwSize=sizeof(IDTo);
  1956. else
  1957. dwSize=0;
  1958. if(pIn->dwSizeImageInfo==sizeof(IDFromImgInfo))
  1959. dwSizeImageInfo=sizeof(IDToImgInfo);
  1960. else
  1961. dwSizeImageInfo=0;
  1962. //dwcViews=pIn->dwcViews;
  1963. //dwcButtons=pIn->dwcButtons;
  1964. //dwcAxes=pIn->dwcAxes;
  1965. dwBufferSize=(pIn->dwBufferSize/
  1966. sizeof(IDFromImgInfo))*sizeof(IDToImgInfo);
  1967. dwBufferUsed=(pIn->dwBufferUsed/
  1968. sizeof(IDFromImgInfo))*sizeof(IDToImgInfo);
  1969. if(dwBufferSize&&pIn->lprgImageInfoArray)
  1970. {
  1971. lprgImageInfoArray=(IDToImgInfo*)new char[dwBufferSize];
  1972. //PREFIX #171787 new does not return NULL. Instead, exception is thrown and
  1973. //handled properly inside of catch block.
  1974. memset(lprgImageInfoArray,0,dwBufferSize);
  1975. for(int i=0;i<(dwBufferSize/sizeof(IDToImgInfo));i++)
  1976. {
  1977. //PREFIX #34520 I do not see how m_pIDFrom or m_pIDFrom->lprgImageInfoArray
  1978. //can be NULL at this point.
  1979. if(!m_bGet)
  1980. {
  1981. TrDIDEVICEIMAGEINFO(
  1982. &m_pIDFrom->lprgImageInfoArray[i],
  1983. &lprgImageInfoArray[i]);
  1984. }
  1985. }
  1986. }
  1987. m_pIDTo=(IDTo*)this;
  1988. }
  1989. };
  1990. ~CTrDIDEVICEIMAGEINFOHEADER()
  1991. {
  1992. if(m_pIDFrom)
  1993. {
  1994. m_pIDFrom->dwcViews=dwcViews;
  1995. //m_pIDFrom->dwcButtons=dwcButtons;
  1996. //m_pIDFrom->dwcAxes=dwcAxes;
  1997. m_pIDFrom->dwBufferUsed=(dwBufferUsed/
  1998. sizeof(IDToImgInfo))*sizeof(IDFromImgInfo);
  1999. if(m_pIDFrom->dwBufferSize)
  2000. {
  2001. for(int i=0;i<(dwBufferSize/sizeof(IDToImgInfo));i++)
  2002. {
  2003. if(m_bGet)
  2004. {
  2005. TrDIDEVICEIMAGEINFO(&lprgImageInfoArray[i],
  2006. &m_pIDFrom->lprgImageInfoArray[i]);
  2007. }
  2008. }
  2009. }
  2010. delete lprgImageInfoArray;
  2011. lprgImageInfoArray=NULL;
  2012. }
  2013. };
  2014. operator IDTo*(){return m_pIDTo;};
  2015. };
  2016. /*
  2017. template <class ActionFormat,class Action,class Str> class CDIAFAUBase
  2018. {
  2019. protected:
  2020. Str m_ApplicationName;
  2021. ActionFormat *m_pDIAF;
  2022. ActionFormat m_DIAF;
  2023. Action* m_lpDIA;
  2024. Str *m_pA2U;
  2025. public:
  2026. CDIAFAUBase()
  2027. {
  2028. m_pDIAF=NULL;
  2029. m_lpDIA=NULL;
  2030. m_pA2U=NULL;
  2031. };
  2032. ~CDIAFAUBase()
  2033. {
  2034. delete[] m_lpDIA;
  2035. delete[] m_pA2U;
  2036. };
  2037. operator ActionFormat*(){return m_pDIAF;};
  2038. };
  2039. template <class ActionFormat,class Action,class Str,class ActionFormatFrom>
  2040. class CDIAFAU:
  2041. public CDIAFAUBase <ActionFormat,Action,Str>
  2042. {
  2043. public:
  2044. CDIAFAU(ActionFormatFrom lpDiActionFormat)
  2045. {
  2046. if(!lpDiActionFormat)return;
  2047. memcpy(&m_DIAF,lpDiActionFormat,sizeof(m_DIAF));
  2048. m_ApplicationName.Set(lpDiActionFormat->lptszActionMap);
  2049. m_DIAF.lptszActionMap=m_ApplicationName;
  2050. if(!(m_DIAF.dwNumActions&&m_DIAF.rgoAction))return;
  2051. m_lpDIA=new Action[m_DIAF.dwNumActions];
  2052. m_DIAF.rgoAction=m_lpDIA;
  2053. m_pA2U=new Str[m_DIAF.dwNumActions];
  2054. for(DWORD i=0;i<m_DIAF.dwNumActions;i++)
  2055. {
  2056. memcpy(&m_lpDIA[i],&lpDiActionFormat->rgoAction[i],
  2057. sizeof(m_lpDIA[i]));
  2058. m_pA2U[i].Set(lpDiActionFormat->rgoAction[i].lptszActionName);
  2059. m_lpDIA[i].lptszActionName=m_pA2U[i];
  2060. }
  2061. m_pDIAF=&m_DIAF;
  2062. };
  2063. };
  2064. */
  2065. #define STARTTR try{
  2066. #define ENDTR }catch(MapException E){return E.GetResult();}\
  2067. catch(exception){return E_OUTOFMEMORY;}
  2068. #ifdef UNICODE
  2069. #define U2A(P) P
  2070. #define DIAFU2A(P) P
  2071. #define IDW(P) P
  2072. typedef C2<CHAR,WCHAR> CA2U;
  2073. #define A2U(P) CA2U(P)
  2074. #define STARTTRA STARTTR
  2075. #define ENDTRA ENDTR
  2076. #define STARTTRW
  2077. #define ENDTRW
  2078. //DIACTIONFORMAT translation
  2079. typedef CTrDIACTIONFORMAT<DIACTIONFORMATA,DIACTIONFORMATW,DIACTIONW>
  2080. CDIACTIONFORMAT;
  2081. #define AFA(P) CDIACTIONFORMAT(P)
  2082. #define AFW(P) P
  2083. //DIDEVICEIMAGEINFOHEADER translation
  2084. typedef CTrDIDEVICEIMAGEINFOHEADER<DIDEVICEIMAGEINFOHEADERA,
  2085. DIDEVICEIMAGEINFOHEADERW,DIDEVICEIMAGEINFOA,DIDEVICEIMAGEINFOW>
  2086. CDIDEVICEIMAGEINFOHEADER;
  2087. #define DIIHA(P) CDIDEVICEIMAGEINFOHEADER(P)
  2088. #define DIIHW(P) P
  2089. #define SETDIIHA(P) CDIDEVICEIMAGEINFOHEADER(P,false)
  2090. #define SETDIIHW(P) P
  2091. #else //ANSI
  2092. #define A2U(P) P
  2093. #define DIAFA2U(P) P
  2094. #define IDA(P) P
  2095. typedef C2<WCHAR,CHAR> CU2A;
  2096. #define U2A(P) CU2A(P)
  2097. #define STARTTRA
  2098. #define ENDTRA
  2099. #define STARTTRW STARTTR
  2100. #define ENDTRW ENDTR
  2101. //DIACTIONFORMAT translation
  2102. typedef CTrDIACTIONFORMAT<DIACTIONFORMATW,DIACTIONFORMATA,DIACTIONA>
  2103. CDIACTIONFORMAT;
  2104. #define AFA(P) P
  2105. #define AFW(P) CDIACTIONFORMAT(P)
  2106. //DIDEVICEIMAGEINFOHEADER translation
  2107. typedef CTrDIDEVICEIMAGEINFOHEADER<DIDEVICEIMAGEINFOHEADERW,
  2108. DIDEVICEIMAGEINFOHEADERA,DIDEVICEIMAGEINFOW,DIDEVICEIMAGEINFOA>
  2109. CDIDEVICEIMAGEINFOHEADER;
  2110. #define DIIHA(P) P
  2111. #define DIIHW(P) CDIDEVICEIMAGEINFOHEADER(P)
  2112. #define SETDIIHA(P) P
  2113. #define SETDIIHW(P) CDIDEVICEIMAGEINFOHEADER(P,false)
  2114. #endif //ANSI
  2115. /******************************************************************************
  2116. *
  2117. * ANSI/UNICODE parameter translation
  2118. *
  2119. *****************************************************************************/
  2120. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrA::
  2121. Initialize(
  2122. LPCGUID lpThisGUIDInstance,
  2123. LPCSTR lpcstrFileName,
  2124. DWORD dwFlags)
  2125. {
  2126. STARTTRA
  2127. return InitializeI(lpThisGUIDInstance,A2U(lpcstrFileName),dwFlags);
  2128. ENDTRA
  2129. }
  2130. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrA::
  2131. GetActionMap(
  2132. LPDIACTIONFORMATA lpDiActionFormat,
  2133. LPCSTR lpcstrUserName,
  2134. FILETIME *pTimestamp,DWORD dwFlags)
  2135. {
  2136. STARTTRA
  2137. return GetActionMapI(AFA(lpDiActionFormat),A2U(lpcstrUserName),
  2138. pTimestamp,dwFlags);
  2139. ENDTRA
  2140. }
  2141. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrA::
  2142. SaveActionMap(
  2143. LPDIACTIONFORMATA lpDiActionFormat,
  2144. LPCSTR lpcstrUserName,
  2145. DWORD dwFlags)
  2146. {
  2147. STARTTRA
  2148. return SaveActionMapI(AFA(lpDiActionFormat),A2U(lpcstrUserName),
  2149. dwFlags);
  2150. ENDTRA
  2151. }
  2152. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrA::
  2153. GetImageInfo(
  2154. LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
  2155. {
  2156. STARTTRA
  2157. return GetImageInfoI(DIIHA(lpdiDevImageInfoHeader));
  2158. ENDTRA
  2159. }
  2160. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrA::
  2161. WriteVendorFile(
  2162. LPDIACTIONFORMATA lpDiActionFormat,
  2163. LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader,
  2164. DWORD dwFlags)
  2165. {
  2166. STARTTRA
  2167. return WriteVendorFileI(AFA(lpDiActionFormat),
  2168. SETDIIHA(lpdiDevImageInfoHeader),dwFlags);
  2169. ENDTRA
  2170. }
  2171. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrW::
  2172. Initialize(
  2173. LPCGUID lpThisGUIDInstance,
  2174. LPCWSTR lpcwstrFileName,
  2175. DWORD dwFlags)
  2176. {
  2177. STARTTRA
  2178. return InitializeI(lpThisGUIDInstance,U2A(lpcwstrFileName),dwFlags);
  2179. ENDTRA
  2180. }
  2181. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrW::
  2182. GetActionMap(
  2183. LPDIACTIONFORMATW lpDiActionFormat,
  2184. LPCWSTR lpcwstrUserName,
  2185. FILETIME *pTimestamp,DWORD dwFlags)
  2186. {
  2187. STARTTRW
  2188. return GetActionMapI(AFW(lpDiActionFormat),U2A(lpcwstrUserName),
  2189. pTimestamp,dwFlags);
  2190. ENDTRW
  2191. }
  2192. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrW::
  2193. SaveActionMap(
  2194. LPDIACTIONFORMATW lpDiActionFormat,
  2195. LPCWSTR lpcwstrUserName,
  2196. DWORD dwFlags)
  2197. {
  2198. STARTTRW
  2199. return SaveActionMapI(AFW(lpDiActionFormat),U2A(lpcwstrUserName),
  2200. dwFlags);
  2201. ENDTRW
  2202. }
  2203. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrW::
  2204. GetImageInfo(
  2205. LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)
  2206. {
  2207. STARTTRW
  2208. return GetImageInfoI(DIIHW(lpdiDevImageInfoHeader));
  2209. ENDTRW
  2210. }
  2211. HRESULT STDMETHODCALLTYPE IDirectInputMapperTrW::
  2212. WriteVendorFile(
  2213. LPDIACTIONFORMATW lpDiActionFormat,
  2214. LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader,
  2215. DWORD dwFlags)
  2216. {
  2217. STARTTRW
  2218. return WriteVendorFileI(AFW(lpDiActionFormat),
  2219. SETDIIHW(lpdiDevImageInfoHeader),dwFlags);
  2220. ENDTRW
  2221. }
  2222. /******************************************************************************
  2223. *
  2224. * Mapper object implementation
  2225. *
  2226. *****************************************************************************/
  2227. BOOL CALLBACK DIEnumDeviceObjectsProcC(LPCDIDEVICEOBJECTINSTANCE lpddoi,
  2228. LPVOID pvRef)
  2229. {
  2230. //Read offset, usage page, usage and name and store into private list
  2231. DEVICEOBJLIST *pDevObjList=&(((CDIMapObj*)pvRef)->m_DevObjList);
  2232. DeviceObjData D;
  2233. /* We decided to use dwType (ObjID) instead of dwOffset.
  2234. This place and exports are the only places where this data enters into
  2235. the module so there should not be problem. Latter rename the code
  2236. from dwOffset. Also, it is valid to use 0xffffffff value of dwType for
  2237. special purposes.
  2238. */ //D.dwOffset=lpddoi->dwOfs;
  2239. D.dwOffset=lpddoi->dwType;
  2240. D.dwUsage=lpddoi->wUsage;
  2241. D.dwUsagePage=lpddoi->wUsagePage;
  2242. D.dwType=lpddoi->dwType;
  2243. D.dwFlags=lpddoi->dwFlags;
  2244. D.Name=lpddoi->tszName;
  2245. ToUpper(D.Name);
  2246. pDevObjList->push_back(D);
  2247. return DIENUM_CONTINUE;
  2248. }
  2249. void MakeGenreName(String &S,LPCTSTR lpDeviceName,
  2250. DWORD dwGenre,LPCGUID lpAppGUID=NULL)
  2251. {
  2252. S=lpDeviceName;
  2253. S+=_T(".");
  2254. //If application genre
  2255. if(lpAppGUID)
  2256. {
  2257. S=S+APPLICATION+_T(".")+GUID2String(*lpAppGUID)+_T(".");
  2258. }
  2259. S=S+GENRE+_T(".")+N2Str(DISEM_GENRE_GET(dwGenre));
  2260. DUMPN(_T("Genre section name"),S);
  2261. }
  2262. bool CompareTypeObjAct(DWORD dwObjType,DWORD dwActType)
  2263. {
  2264. if((dwObjType&DIDFT_AXIS)&&
  2265. (DISEM_TYPE_GET(dwActType)==DISEM_TYPE_GET(DISEM_TYPE_AXIS)))
  2266. return true;
  2267. if((dwObjType&DIDFT_BUTTON)&&
  2268. (DISEM_TYPE_GET(dwActType)==DISEM_TYPE_GET(DISEM_TYPE_BUTTON)))
  2269. return true;
  2270. if((dwObjType&DIDFT_POV)&&
  2271. (DISEM_TYPE_GET(dwActType)==DISEM_TYPE_GET(DISEM_TYPE_POV)))
  2272. return true;
  2273. return false;
  2274. }
  2275. bool CDIMapObj::CompareData(DeviceObjData &DOD,ControlData &CD)
  2276. {
  2277. if(IsVIDPID())
  2278. {
  2279. //Assume for now that the DOD.dwOffset and DOD.dwType fields are
  2280. //both always set as they are actually the same thing
  2281. //under W2K. If this isn't the case we need to work out
  2282. //which one to check against CD.dwOffset
  2283. #ifdef _CHECKED
  2284. if (DOD.dwOffset!=DOD.dwType)
  2285. DUMP(_T("CDIMapObj::CompareData. Problem - DeviceObjData has differing dwOffset and dwType fields should not differ!"));
  2286. #endif
  2287. if((DOD.dwUsagePage==CD.dwUsagePage)&&
  2288. (DOD.dwUsage==CD.dwUsage) &&
  2289. (DIDFT_FINDMASK&DOD.dwOffset)==(DIDFT_FINDMASK&CD.dwOffset))
  2290. //Device object found
  2291. return true;
  2292. }
  2293. else
  2294. {
  2295. //Ignore FF bits since some drivers do not report properly.
  2296. //Also, this way same ini file can be used for both FF and
  2297. //non-FF device.
  2298. if((DIDFT_FINDMASK&DOD.dwOffset)==(DIDFT_FINDMASK&CD.dwOffset))
  2299. //Device object found
  2300. return true;
  2301. }
  2302. return false;
  2303. }
  2304. bool CDIMapObj::GetOffset(ControlData &CD,
  2305. DEVICEOBJLIST &DevObjList,DWORD dwSemantic,
  2306. DEVICEOBJLIST::iterator &DevObjItOut)
  2307. {
  2308. METHOD_ENTRY(GetOffset);
  2309. bool bFoundDevice=false;
  2310. //Find DI device object with usage/usage page or name
  2311. DEVICEOBJLIST::iterator DevObjIt;
  2312. for(DevObjIt=DevObjList.begin();DevObjIt!=DevObjList.end();DevObjIt++)
  2313. {
  2314. if(CompareData(*DevObjIt,CD))
  2315. {
  2316. bFoundDevice=true;
  2317. if(CompareTypeObjAct(DevObjIt->dwType,dwSemantic)&&
  2318. !(DevObjIt->bMapped))
  2319. {
  2320. DevObjItOut=DevObjIt;
  2321. return true;
  2322. }
  2323. }
  2324. }
  2325. if(!bFoundDevice)
  2326. {
  2327. TRACE(_T("Control with filename '%s' does not exist in device.\n"),
  2328. CD.ControlName.data());
  2329. throw MAP_EXCEPTION(E_DEVICE_MISSING_CONTROL);
  2330. }
  2331. return false;
  2332. }
  2333. /*This three functions TBD*/
  2334. //Use when writing
  2335. DWORD GetFileSemantic(DWORD dwSemantic,DWORD dwHow)
  2336. {
  2337. if(dwHow==DIAH_USERCONFIG)
  2338. return dwSemantic;
  2339. return DISEM_INDEX_SET(DISEM_INDEX_GET(dwSemantic));
  2340. }
  2341. //Use to get value from file
  2342. DWORD GetCmpFileGenreSemantic(DWORD dwSemantic,DWORD dwHow,DWORD dwGenre)
  2343. {
  2344. if(dwHow==DIAH_USERCONFIG)
  2345. return dwSemantic;
  2346. return DISEM_INDEX_SET(DISEM_INDEX_GET(dwSemantic))|
  2347. DISEM_GENRE_SET(DISEM_GENRE_GET(dwGenre));
  2348. }
  2349. //Use to get value from action array
  2350. DWORD GetCmpActionGenreSemantic(DWORD dwSemantic,DWORD dwHow)
  2351. {
  2352. if(dwHow==DIAH_USERCONFIG)
  2353. return dwSemantic;
  2354. return DISEM_INDEX_SET(DISEM_INDEX_GET(dwSemantic))|
  2355. DISEM_GENRE_SET(DISEM_GENRE_GET(dwSemantic));
  2356. }
  2357. /**/
  2358. void WhichDeviceObjectIsMapped(LPDIACTIONFORMAT lpDiActionFormat,
  2359. DEVICEOBJLIST &DevObjList,
  2360. LPCGUID lpThisGUIDInstance)
  2361. {
  2362. DEVICEOBJLIST::iterator DevObjIt;
  2363. for(DevObjIt=DevObjList.begin();DevObjIt!=DevObjList.end();DevObjIt++)
  2364. {
  2365. DevObjIt->bMapped=false;
  2366. for(DWORD i=0;i<lpDiActionFormat->dwNumActions;i++)
  2367. {
  2368. if((lpDiActionFormat->rgoAction[i].guidInstance!=
  2369. *lpThisGUIDInstance)||
  2370. (lpDiActionFormat->rgoAction[i].dwHow==DIAH_UNMAPPED)||
  2371. ((DIDFT_FINDMASK&lpDiActionFormat->rgoAction[i].dwObjID)!=
  2372. (DIDFT_FINDMASK&DevObjIt->dwOffset)))
  2373. continue;
  2374. else
  2375. {
  2376. DevObjIt->bMapped=true;
  2377. break;
  2378. }
  2379. }
  2380. }
  2381. }
  2382. void CDIMapObj::MapGenre(LPDIACTIONFORMAT lpDiActionFormat,
  2383. CONTROLLIST &ControlsData,
  2384. LPCTSTR lpGenreName,LPCTSTR lpFileName,
  2385. LPCGUID lpThisGUIDInstance,
  2386. DEVICEOBJLIST &DevObjList,DWORD dwHow,
  2387. DWORD &dwNOfMappedActions)
  2388. {
  2389. METHOD_ENTRY(MapGenre);
  2390. //For all file control names, read the genre action mapping
  2391. CONTROLLIST::iterator CtrlIt;
  2392. for(CtrlIt=ControlsData.begin();CtrlIt!=ControlsData.end();CtrlIt++)
  2393. {
  2394. DWORD dwAction=GetPrivateProfileInt(lpGenreName,
  2395. CtrlIt->ControlName.data(),RESERVED_ACTION,lpFileName);
  2396. CtrlIt->dwAction=dwAction;
  2397. }
  2398. //Find actions which are not mapped yet
  2399. TRACE(_T("Iterate through action array and controls in ini file.\n"));
  2400. for(DWORD i=0;i<lpDiActionFormat->dwNumActions;i++)
  2401. {
  2402. if(((lpDiActionFormat->rgoAction[i].guidInstance!=NULLGUID)
  2403. &&(lpDiActionFormat->rgoAction[i].guidInstance!=*lpThisGUIDInstance))||
  2404. (lpDiActionFormat->rgoAction[i].dwFlags&DIA_APPNOMAP)||
  2405. (lpDiActionFormat->rgoAction[i].dwHow!=DIAH_UNMAPPED))
  2406. continue;
  2407. //Find control which maps to this action
  2408. for(CtrlIt=ControlsData.begin();CtrlIt!=ControlsData.end();CtrlIt++)
  2409. {
  2410. if(GetCmpFileGenreSemantic(CtrlIt->dwAction,dwHow,
  2411. lpDiActionFormat->dwGenre)==
  2412. GetCmpActionGenreSemantic(
  2413. lpDiActionFormat->rgoAction[i].dwSemantic,dwHow))
  2414. {
  2415. //Find offset and initialize it in the action structure
  2416. DEVICEOBJLIST::iterator DevObjIt;
  2417. if(GetOffset(*CtrlIt,DevObjList,
  2418. lpDiActionFormat->rgoAction[i].dwSemantic,DevObjIt))
  2419. {
  2420. if((lpDiActionFormat->rgoAction[i].dwFlags&
  2421. DIA_FORCEFEEDBACK)&&
  2422. !((DevObjIt->dwFlags&DIDOI_FFEFFECTTRIGGER)||
  2423. (DevObjIt->dwFlags&DIDOI_FFACTUATOR)))
  2424. {
  2425. TRACE(_T("Action array %u has DIA_FORCEFEEDBACK set but devobj \
  2426. does not have DIDOI_FFEFFECTTRIGGER or DIDOI_FFACTUATOR set. Not mapped.\n"),i);
  2427. continue;
  2428. }
  2429. TRACE(_T("Action array %u mapped to ini file \
  2430. control and devobj with dwObjID 0x%x\n"),i,DevObjIt->dwOffset);
  2431. lpDiActionFormat->rgoAction[i].dwObjID=DevObjIt->dwOffset;
  2432. DevObjIt->bMapped=true;
  2433. dwNOfMappedActions++;
  2434. lpDiActionFormat->rgoAction[i].guidInstance=
  2435. *lpThisGUIDInstance;
  2436. lpDiActionFormat->rgoAction[i].dwHow=dwHow;
  2437. break;
  2438. }
  2439. else
  2440. {
  2441. TRACE(_T("Action array %u related to ini file \
  2442. control but devobj not found. Not mapping.\n"),i);
  2443. }
  2444. }
  2445. }
  2446. }
  2447. }
  2448. void WriteTimestamp(LPCTSTR lpFileName,LPCTSTR lpDeviceName,
  2449. GUID &AppGUID,LPDIACTIONFORMAT lpDiActionFormat)
  2450. {
  2451. String S,SH,SL;
  2452. S=GUID2String(AppGUID)+_T(".");
  2453. SH=S+TIMESTAMPHIGH;
  2454. SL=S+TIMESTAMPLOW;
  2455. FILETIME T;
  2456. if((lpDiActionFormat->ftTimeStamp.dwLowDateTime==DIAFTS_NEWDEVICELOW)&&
  2457. (lpDiActionFormat->ftTimeStamp.dwHighDateTime==DIAFTS_NEWDEVICEHIGH))
  2458. {
  2459. T.dwHighDateTime=DIAFTS_UNUSEDDEVICEHIGH;
  2460. T.dwLowDateTime=DIAFTS_UNUSEDDEVICELOW;
  2461. }
  2462. else
  2463. {
  2464. GetSystemTimeAsFileTime(&T);
  2465. }
  2466. WritePrivateProfileIntX(lpDeviceName,SH.data(),
  2467. T.dwHighDateTime,lpFileName);
  2468. WritePrivateProfileIntX(lpDeviceName,SL.data(),
  2469. T.dwLowDateTime,lpFileName);
  2470. }
  2471. void ReadTimestamp(FILETIME &T,LPCTSTR lpFileName,
  2472. LPCTSTR lpDeviceName,GUID &AppGUID)
  2473. {
  2474. String S,SH,SL;
  2475. S=GUID2String(AppGUID)+_T(".");
  2476. SH=S+TIMESTAMPHIGH;
  2477. SL=S+TIMESTAMPLOW;
  2478. T.dwHighDateTime=GetPrivateProfileInt(lpDeviceName,SH.data(),
  2479. DIAFTS_NEWDEVICELOW,lpFileName);
  2480. T.dwLowDateTime=GetPrivateProfileInt(lpDeviceName,SL.data(),
  2481. DIAFTS_NEWDEVICEHIGH,lpFileName);
  2482. }
  2483. #ifdef _CHECKED
  2484. int CDIMapObj::m_DeviceCount=0;
  2485. #endif
  2486. CDIMapObj::CDIMapObj()
  2487. {
  2488. #ifdef _CHECKED
  2489. m_DeviceNo=m_DeviceCount++;
  2490. #endif
  2491. m_ulRefCnt=0;
  2492. Clear();
  2493. }
  2494. void CDIMapObj::Clear()
  2495. {
  2496. //m_ulRefCnt must not be set here, only in constructor
  2497. bool m_bInitialized=false;
  2498. m_dwThisVendorID=0;
  2499. m_dwThisProductID=0;
  2500. m_DeviceName=_T("");
  2501. memset(&m_DeviceGuid,0,sizeof(m_DeviceGuid));
  2502. //Vendor file name data
  2503. m_VFileName=_T("");
  2504. m_lpVFileName=NULL;
  2505. m_VFileDevName=_T("");
  2506. m_VCtrlData.clear();
  2507. m_bVLoaded=false;
  2508. //User file name data
  2509. m_UName=_T("");
  2510. m_lpUName=NULL;
  2511. m_UFileName=_T("");
  2512. m_UserDir=_T("");
  2513. m_UFileDevName=_T("");
  2514. m_UCtrlData.clear();
  2515. m_bULoaded=false;
  2516. m_UTimestamp.dwHighDateTime=0;
  2517. m_UTimestamp.dwLowDateTime=0;
  2518. m_bImageBufferSize=false;
  2519. m_dwImageBufferSize=0;
  2520. }
  2521. CDIMapObj::~CDIMapObj()
  2522. {
  2523. }
  2524. void CDIMapObj::LoadFileData(LPCTSTR lpFileName,LPCTSTR lpThisName,
  2525. DWORD dwThisVendorID,DWORD dwThisProductID,
  2526. String &FileDeviceName,CONTROLLIST &ControlsData,
  2527. bool &bLoaded,FILETIME *pT,
  2528. LPDIACTIONFORMAT lpDiActionFormat)
  2529. {
  2530. METHOD_ENTRY(LoadFileData);
  2531. DUMPN(_T("Filename"),lpFileName);
  2532. bLoaded=false;
  2533. FileDeviceName=_T("");
  2534. ControlsData.clear();
  2535. //Clear DevObj pointers to controls
  2536. for(DEVICEOBJLIST::iterator DevObjIt=m_DevObjList.begin();DevObjIt!=
  2537. m_DevObjList.end();DevObjIt++)
  2538. {
  2539. if(&ControlsData==&m_UCtrlData)
  2540. DevObjIt->pUCtrlData=NULL;
  2541. else
  2542. DevObjIt->pVCtrlData=NULL;
  2543. }
  2544. if(pT)
  2545. {
  2546. pT->dwLowDateTime=DIAFTS_NEWDEVICELOW;
  2547. pT->dwHighDateTime=DIAFTS_NEWDEVICEHIGH;
  2548. }
  2549. //Read file version and choose file parser
  2550. DWORD dwVersion=GetPrivateProfileInt(DIRECT_INPUT,DIRECTX_VERSION,
  2551. RESERVED_DX_VER,lpFileName);
  2552. if(dwVersion==0x800)
  2553. {
  2554. //Load all file device names
  2555. STRINGLIST Devices;
  2556. LoadListOfStrings(lpFileName,DIRECT_INPUT,DEVICES,Devices);
  2557. BOOL bDeviceFound=FALSE;
  2558. //Iterate through all file device names
  2559. STRINGLIST::iterator DevIt=Devices.begin();
  2560. while(DevIt!=Devices.end())
  2561. {
  2562. String DeviceName=(*DevIt);
  2563. DUMPN(_T("Trying to match device with ini file name"),
  2564. DeviceName);
  2565. //Read VID, PID and type name.
  2566. String NameCur;
  2567. DWORD dwVendorIDCur=GetPrivateProfileInt(DeviceName.data(),
  2568. VENDORID,RESERVED_VENDORID,lpFileName);
  2569. DWORD dwProductIDCur=GetPrivateProfileInt(DeviceName.data(),
  2570. PRODUCTID,RESERVED_PRODUCTID,lpFileName);
  2571. LoadString(NameCur,lpFileName,DeviceName.data(),NAME);
  2572. if((IsVIDPID()&&
  2573. ((dwVendorIDCur==dwThisVendorID)&&
  2574. (dwProductIDCur==dwThisProductID)))||
  2575. ((!IsVIDPID())&&
  2576. (NameCur==lpThisName)))
  2577. {
  2578. TRACE(_T("Device found in ini file!\n"));
  2579. //Definition of a device is found in the file
  2580. bDeviceFound=TRUE;
  2581. FileDeviceName=DeviceName;
  2582. if(pT&&lpDiActionFormat)
  2583. ReadTimestamp(*pT,lpFileName,FileDeviceName.data(),
  2584. lpDiActionFormat->guidActionMap);
  2585. //Load all file control names
  2586. STRINGLIST Controls;
  2587. LoadListOfStrings(lpFileName,DeviceName.data(),CONTROLS,
  2588. Controls,true);
  2589. //Iterate through all file control names for this device
  2590. STRINGLIST::iterator CtrlIt=Controls.begin();
  2591. while(CtrlIt!=Controls.end())
  2592. {
  2593. DUMPN(_T("Read control data with ini file name"),
  2594. CtrlIt->data());
  2595. String ControlSectionName=*CtrlIt;
  2596. ControlData ControlDataCur;
  2597. ControlDataCur.pDevObj=NULL;
  2598. ControlDataCur.ControlName=*CtrlIt;
  2599. ControlDataCur.dwOffset=RESERVED_OFFSET;
  2600. ControlDataCur.dwUsagePage=RESERVED_USAGEPAGE;
  2601. ControlDataCur.dwUsage=RESERVED_USAGE;
  2602. //Read offset, Usage and UsagePage for a file control name
  2603. ControlDataCur.dwOffset=
  2604. GetPrivateProfileInt(ControlSectionName.data(),
  2605. OFFSET,RESERVED_OFFSET,lpFileName);
  2606. ControlDataCur.dwUsage=
  2607. GetPrivateProfileInt(ControlSectionName.data(),
  2608. USAGE,RESERVED_USAGE,lpFileName);
  2609. ControlDataCur.dwUsagePage=
  2610. GetPrivateProfileInt(
  2611. ControlSectionName.data(),
  2612. USAGEPAGE,RESERVED_USAGEPAGE,
  2613. lpFileName);
  2614. // LoadString(ControlDataCur.Name,lpFileName,
  2615. // ControlSectionName.data(),NAME);
  2616. #ifdef STRICT_DEV_DEF
  2617. //Store data for this control into the list
  2618. ControlsData.push_back(ControlDataCur);
  2619. #endif STRICT_DEV_DEF
  2620. //Here bind device obj and control data
  2621. //Find DI device object with usage/usage page or name
  2622. for(DEVICEOBJLIST::iterator DevObjIt=m_DevObjList.begin();
  2623. DevObjIt!=m_DevObjList.end();DevObjIt++)
  2624. {
  2625. if(CompareData(*DevObjIt,ControlDataCur))
  2626. {
  2627. #ifndef STRICT_DEV_DEF
  2628. //Store data for this control into the list
  2629. ControlsData.push_back(ControlDataCur);
  2630. #endif STRICT_DEV_DEF
  2631. ControlsData.back().pDevObj=&(*DevObjIt);
  2632. if(&ControlsData==&m_UCtrlData)
  2633. DevObjIt->pUCtrlData=&ControlsData.back();
  2634. else
  2635. DevObjIt->pVCtrlData=&ControlsData.back();
  2636. }
  2637. }
  2638. #ifdef STRICT_DEV_DEF
  2639. if(!ControlsData.back().pDevObj)
  2640. {
  2641. TRACE(_T("Could not match control in file with device object.\n"));
  2642. throw MAP_EXCEPTION(E_DEVICE_MISSING_CONTROL);
  2643. }
  2644. #endif STRICT_DEV_DEF
  2645. CtrlIt++;
  2646. }
  2647. break;
  2648. }
  2649. DevIt++;
  2650. }
  2651. if(!bDeviceFound)
  2652. {
  2653. TRACE(_T("Device description not present in this file!!!!!!!!!!!!!\n"));
  2654. //throw MAP_EXCEPTION(E_DEVICE_NOT_FOUND); Currently this is legal
  2655. }
  2656. else
  2657. {
  2658. TRACE(_T("Device data loaded from ini file.\n"));
  2659. bLoaded=true;
  2660. }
  2661. }
  2662. else if(dwVersion!=RESERVED_DX_VER)
  2663. {
  2664. TRACE(_T("Bad file version\n"));
  2665. throw MAP_EXCEPTION(E_BAD_VERSION);
  2666. }
  2667. else
  2668. {
  2669. TRACE(_T("File not found, or no version info. Continuing...\n"));
  2670. }
  2671. }
  2672. void CDIMapObj::LoadUserData(LPCTSTR lpctstrUserName,
  2673. LPDIACTIONFORMAT lpDiActionFormat,
  2674. bool bForceReload/*=false*/,bool bCreateDir/*=false*/)
  2675. {
  2676. METHOD_ENTRY(LoadUserData);
  2677. String UserName;
  2678. if(bForceReload)
  2679. lpctstrUserName=m_lpUName;
  2680. if(lpctstrUserName)
  2681. UserName=lpctstrUserName;
  2682. if((m_UFileName==_T(""))||//first run
  2683. (UserName!=m_UName)||//different user name
  2684. bForceReload)
  2685. {
  2686. TRACE(_T("First run or new user or forced reload of user data.\n"));
  2687. m_UName=_T("");
  2688. m_lpUName=NULL;
  2689. m_UFileName=_T("");
  2690. m_UserDir=_T("");
  2691. m_UFileDevName=_T("");
  2692. m_UCtrlData.clear();
  2693. m_bULoaded=false;
  2694. m_UTimestamp.dwHighDateTime;
  2695. m_UTimestamp.dwLowDateTime;
  2696. if(lpctstrUserName)//just used as logic operation
  2697. {
  2698. m_UName=UserName;
  2699. m_lpUName=m_UName.data();
  2700. }
  2701. TCHAR lpctstrUserFileName[_MAX_PATH];
  2702. GetMapFileName(m_UName.data(),m_DeviceName.data(),
  2703. m_nDeviceInstanceNo,
  2704. lpctstrUserFileName,false,&m_UserDir);
  2705. m_UFileName=lpctstrUserFileName;
  2706. DUMPN(_T("User File Name"),lpctstrUserFileName);
  2707. LoadFileData(m_UFileName.data(),m_DeviceName.data(),
  2708. m_dwThisVendorID,m_dwThisProductID,m_UFileDevName,m_UCtrlData,
  2709. m_bULoaded,&m_UTimestamp,lpDiActionFormat);
  2710. }
  2711. if(bCreateDir)
  2712. {
  2713. TCHAR lpctstrUserFileName[_MAX_PATH];
  2714. GetMapFileName(m_UName.data(),m_DeviceName.data(),
  2715. m_nDeviceInstanceNo,
  2716. lpctstrUserFileName,true,&m_UserDir);
  2717. }
  2718. }
  2719. BOOL CALLBACK DIEnumDevicesProc(
  2720. const DIDEVICEINSTANCE * lpddi,LPVOID pvRef)
  2721. {
  2722. DEVCNT *pDevCnt=(DEVCNT*)pvRef;
  2723. if(!memcmp(&lpddi->guidProduct,
  2724. &pDevCnt->pDIDI->guidProduct,
  2725. sizeof(lpddi->guidProduct)))
  2726. {
  2727. if(0<memcmp(&lpddi->guidInstance,
  2728. &pDevCnt->pDIDI->guidInstance,
  2729. sizeof(lpddi->guidInstance)))
  2730. (*(pDevCnt->m_pnCnt))++;
  2731. }
  2732. return DIENUM_CONTINUE;
  2733. }
  2734. HRESULT CDIMapObj::InitializeI(
  2735. LPCGUID lpThisGUIDInstance,
  2736. LPCTSTR lpctstrFileName,
  2737. DWORD dwFlags)
  2738. {
  2739. try
  2740. {
  2741. INITIALIZE_ENTERED;
  2742. TRACE(_T("Parameters:\n"));
  2743. DUMP(lpThisGUIDInstance);
  2744. DUMP(lpctstrFileName);
  2745. TRACE(_T("\n"));
  2746. //Check parameters
  2747. //Check guid pointer
  2748. if(!lpThisGUIDInstance)
  2749. {
  2750. TRACE(_T("lpThisGUIDInstance is NULL\n"));
  2751. throw MAP_EXCEPTION(E_INVALIDARG);
  2752. }
  2753. HRESULT hRes=S_OK;
  2754. Clear();
  2755. m_DeviceGuid=*lpThisGUIDInstance;
  2756. //Create DInput device and get info
  2757. LPDIRECTINPUT_AR lpDI;
  2758. HMODULE hM=GetModuleHandle(NULL);
  2759. if(!hM)
  2760. {
  2761. TRACE(_T("ERROR, GetModuleHandle failed\n"));
  2762. throw MAP_EXCEPTION(E_FAIL);
  2763. }
  2764. hRes=DirectInput8Create(hM, DIRECTINPUT_VERSION,
  2765. IID_IDirectInput8, lpDI.Addr(),NULL);
  2766. if(FAILED(hRes))
  2767. {
  2768. TRACE(_T("ERROR, DirectInput8Create failed\n"));
  2769. throw MAP_EXCEPTION(hRes);
  2770. }
  2771. LPDIRECTINPUTDEVICE_AR lpDID;
  2772. hRes=lpDI.P()->CreateDevice(*lpThisGUIDInstance,lpDID,NULL);
  2773. if(FAILED(hRes))
  2774. {
  2775. TRACE(_T("ERROR, CreateDeviceEx failed\n"));
  2776. throw MAP_EXCEPTION(hRes);
  2777. }
  2778. DIDEVICEINSTANCE DIDI;
  2779. DIDI.dwSize=sizeof(DIDI);
  2780. hRes=lpDID.P()->GetDeviceInfo(&DIDI);
  2781. if(FAILED(hRes))
  2782. {
  2783. TRACE(_T("ERROR, GetDeviceInfo failed\n"));
  2784. throw MAP_EXCEPTION(hRes);
  2785. }
  2786. //find device instance number
  2787. m_nDeviceInstanceNo=0;
  2788. DEVCNT DevCnt;
  2789. DevCnt.m_pnCnt=&m_nDeviceInstanceNo;
  2790. DevCnt.pDIDI=&DIDI;
  2791. if(DI_OK!=lpDI.P()->EnumDevices
  2792. (0,DIEnumDevicesProc,&DevCnt,DIEDFL_ATTACHEDONLY))
  2793. {
  2794. TRACE(_T("ERROR, EnumDevices failed\n"));
  2795. throw MAP_EXCEPTION(hRes);
  2796. }
  2797. DUMP(m_nDeviceInstanceNo);
  2798. // Code block added by MarcAnd
  2799. {
  2800. DIPROPDWORD dipdw;
  2801. dipdw.diph.dwSize = sizeof( dipdw );
  2802. dipdw.diph.dwHeaderSize = sizeof( dipdw.diph );
  2803. dipdw.diph.dwObj = 0;
  2804. dipdw.diph.dwHow = DIPH_DEVICE;
  2805. if(FAILED(lpDID.P()->GetProperty(DIPROP_VIDPID,&dipdw.diph)))
  2806. {
  2807. m_dwThisVendorID=0;
  2808. m_dwThisProductID=0;
  2809. }
  2810. else
  2811. {
  2812. m_dwThisVendorID=LOWORD( dipdw.dwData );
  2813. m_dwThisProductID=HIWORD( dipdw.dwData );
  2814. }
  2815. }
  2816. DUMP(m_dwThisVendorID);
  2817. DUMP(m_dwThisProductID);
  2818. DIPROPSTRING dipwsz;
  2819. dipwsz.diph.dwSize=sizeof(dipwsz);
  2820. dipwsz.diph.dwHeaderSize=sizeof(dipwsz.diph);
  2821. dipwsz.diph.dwObj=0;
  2822. dipwsz.diph.dwHow=DIPH_DEVICE;
  2823. if(FAILED(lpDID.P()->GetProperty(DIPROP_TYPENAME,&dipwsz.diph)))
  2824. {
  2825. //keyboard, mouse...
  2826. m_DeviceName=DIDI.tszInstanceName;
  2827. }
  2828. else
  2829. {
  2830. MakeUniqueDeviceName(m_DeviceName,dipwsz.wsz);
  2831. }
  2832. ToUpper(m_DeviceName);
  2833. DUMP(DIDI.tszInstanceName);
  2834. DUMP(m_DeviceName);
  2835. //Enumerate DI device objects and get info.
  2836. //Must go before LoadFileData file control data
  2837. //can be binded to object data
  2838. hRes=lpDID.P()->EnumObjects(DIEnumDeviceObjectsProcC,this,
  2839. DIDFT_AXIS|DIDFT_BUTTON|DIDFT_POV);
  2840. if(FAILED(hRes))
  2841. {
  2842. TRACE(_T("ERROR, EnumObjects failed\n"));
  2843. throw MAP_EXCEPTION(hRes);
  2844. }
  2845. if(!m_DevObjList.size())
  2846. {
  2847. TRACE(_T("ERROR, No dev objects found\n"));
  2848. throw MAP_EXCEPTION(E_DEV_OBJ_NOT_FOUND);
  2849. }
  2850. DUMP(m_DevObjList);
  2851. m_lpVFileName=NULL;
  2852. if(lpctstrFileName)
  2853. {
  2854. m_VFileName=lpctstrFileName;
  2855. m_lpVFileName=m_VFileName.data();
  2856. LoadFileData(m_lpVFileName,m_DeviceName.data(),m_dwThisVendorID,
  2857. m_dwThisProductID,m_VFileDevName,
  2858. m_VCtrlData,m_bVLoaded,NULL,NULL);
  2859. }
  2860. m_bInitialized=true;
  2861. TRACE(_T("hRes=0x%x\n"),S_OK);
  2862. return S_OK;
  2863. }
  2864. catch(MapException E)
  2865. {
  2866. return E.GetResult();
  2867. }
  2868. catch(exception)
  2869. {
  2870. USETRACER();
  2871. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  2872. return E_FAIL;
  2873. }
  2874. }
  2875. ULONG STDMETHODCALLTYPE CDIMapObj::Release()
  2876. {
  2877. m_ulRefCnt--;
  2878. if(m_ulRefCnt)return m_ulRefCnt;
  2879. delete this;
  2880. DllRelease();
  2881. return 0;
  2882. }
  2883. HRESULT STDMETHODCALLTYPE CDIMapObj::QueryInterface(REFIID riid,
  2884. LPVOID * ppvOut)
  2885. {
  2886. if(IsEqualIID(riid,IID_IDirectInputMapIW))
  2887. {
  2888. AddRef();
  2889. *ppvOut=(IDirectInputMapperW*)this;
  2890. return S_OK;
  2891. }
  2892. else if(IsEqualIID(riid,IID_IDirectInputMapIA))
  2893. {
  2894. AddRef();
  2895. *ppvOut=(IDirectInputMapperA*)this;
  2896. return S_OK;
  2897. }
  2898. else if(IsEqualIID(riid,IID_IUnknown))
  2899. {
  2900. AddRef();
  2901. *ppvOut=(IUnknown*)(IDirectInputMapperA*)this;
  2902. return S_OK;
  2903. }
  2904. else if(IsEqualIID(riid,IID_IDirectInputMapVendorIW))
  2905. {
  2906. AddRef();
  2907. *ppvOut=(IDirectInputMapperVendorW*)this;
  2908. return S_OK;
  2909. }
  2910. else if(IsEqualIID(riid,IID_IDirectInputMapVendorIA))
  2911. {
  2912. AddRef();
  2913. *ppvOut=(IDirectInputMapperVendorA*)this;
  2914. return S_OK;
  2915. }
  2916. *ppvOut = 0;
  2917. return E_NOINTERFACE;
  2918. }
  2919. void CDIMapObj::MapDevice(LPDIACTIONFORMAT lpDiActionFormat,
  2920. LPCTSTR lpFileName,
  2921. LPCTSTR lpFileDevName,LPCGUID lpThisGUIDInstance,
  2922. DEVICEOBJLIST &DevObjList,CONTROLLIST &ControlsData,
  2923. DWORD dwHow,DWORD dwHowApp,DWORD &dwNOfMappedActions,
  2924. bool *pbMapExists,bool bUserFile)
  2925. {
  2926. METHOD_ENTRY(MapDevice);
  2927. DUMPN(_T("Filename"),lpFileName);
  2928. DUMPN(_T("Device name file"),lpFileDevName);
  2929. //Map genre overrides for a particular game
  2930. String ApplicationGenreName;
  2931. MakeGenreName(ApplicationGenreName,lpFileDevName,
  2932. lpDiActionFormat->dwGenre,
  2933. &lpDiActionFormat->guidActionMap);
  2934. if(GetPrivateProfileInt(ApplicationGenreName.data(),
  2935. MAPEXISTS,0,lpFileName))
  2936. {
  2937. if(pbMapExists)
  2938. {
  2939. *pbMapExists=true;
  2940. }
  2941. if(lpDiActionFormat->dwNumActions!=
  2942. GetPrivateProfileInt(
  2943. ApplicationGenreName.data(),NUMACTIONS,
  2944. -1,lpFileName))
  2945. {
  2946. TRACEI(_T("WARNING! Action map changed!\n"));
  2947. TRACEI(_T("File name=%s\n"),lpFileName);
  2948. TRACEI(_T("Genre section name=%s\n"),ApplicationGenreName.data());
  2949. }
  2950. }
  2951. TRACE(_T("Process application specific genre.\n"));
  2952. DUMPN(_T("Section name"),ApplicationGenreName.data());
  2953. MapGenre(lpDiActionFormat,ControlsData,
  2954. ApplicationGenreName.data(),lpFileName,lpThisGUIDInstance,
  2955. DevObjList,dwHowApp,dwNOfMappedActions);
  2956. //Map remainder of semantics of a genre
  2957. if(!bUserFile)//only app. specific maps in user file
  2958. {
  2959. String GenreName;
  2960. MakeGenreName(GenreName,lpFileDevName,
  2961. lpDiActionFormat->dwGenre);
  2962. if(pbMapExists)
  2963. {
  2964. if(GetPrivateProfileInt(GenreName.data(),
  2965. MAPEXISTS,0,lpFileName))
  2966. *pbMapExists=true;
  2967. }
  2968. TRACE(_T("Process genre.\n"));
  2969. DUMPN(_T("Section name"),GenreName.data());
  2970. MapGenre(lpDiActionFormat,ControlsData,GenreName.data(),
  2971. lpFileName,lpThisGUIDInstance,DevObjList,
  2972. dwHow,dwNOfMappedActions);
  2973. }
  2974. }
  2975. bool IsImageInfoFull(DIDEVICEIMAGEINFOHEADER *lpdiDevImageInfoHeader,
  2976. DWORD dwImages)
  2977. {
  2978. if((lpdiDevImageInfoHeader->dwBufferSize!=0)&&
  2979. (((dwImages+1)*sizeof(DIDEVICEIMAGEINFO))>
  2980. lpdiDevImageInfoHeader->dwBufferSize))
  2981. return true;
  2982. return false;
  2983. }
  2984. DIDEVICEIMAGEINFO *GetImageInfoAdr(
  2985. DIDEVICEIMAGEINFOHEADER *lpdiDevImageInfoHeader,DWORD dwImages)
  2986. {
  2987. if(lpdiDevImageInfoHeader->dwBufferSize==0)
  2988. return NULL;
  2989. return &lpdiDevImageInfoHeader->lprgImageInfoArray[dwImages];
  2990. }
  2991. HRESULT CDIMapObj::GetImageInfoI(
  2992. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader)
  2993. {
  2994. try
  2995. {
  2996. GETIMAGEINFO_ENTERED;
  2997. return GetImageInfoInternal(lpdiDevImageInfoHeader,false);
  2998. }
  2999. catch(MapException E)
  3000. {
  3001. return E.GetResult();
  3002. }
  3003. catch(exception)
  3004. {
  3005. USETRACER();
  3006. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  3007. return E_FAIL;
  3008. }
  3009. }
  3010. HRESULT CDIMapObj::GetImageInfoInternal(
  3011. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  3012. bool bGettingSize)
  3013. {
  3014. METHOD_ENTRY(GetImageInfoInternal);
  3015. TRACE(_T("Parameters:\n"));
  3016. // DUMP(lpdiDevImageInfoHeader);Instead of dumping entire struct
  3017. // dump only input params
  3018. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  3019. TRACE(_T("lpdiDevImageInfoHeader=0x%p\n"),lpdiDevImageInfoHeader);
  3020. if(lpdiDevImageInfoHeader)
  3021. {
  3022. USETRACER();
  3023. TRACE(_T("dwSize=%u\tdwSizeImageInfo=%u\n"),
  3024. (unsigned int)lpdiDevImageInfoHeader->dwSize,
  3025. (unsigned int)lpdiDevImageInfoHeader->dwSizeImageInfo);
  3026. TRACE(_T("dwBufferSize=%u\tdwBufferUsed=%u\n"),
  3027. (unsigned int)lpdiDevImageInfoHeader->dwBufferSize,
  3028. (unsigned int)lpdiDevImageInfoHeader->dwBufferUsed);
  3029. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  3030. TRACE(_T("lprgImageInfoArray=0x%p\n"),
  3031. lpdiDevImageInfoHeader->lprgImageInfoArray);
  3032. }
  3033. TRACE(_T("\n"));
  3034. //Check if initialized
  3035. if(!m_bInitialized)
  3036. {
  3037. TRACE(_T("Object not initialized\n"));
  3038. throw MAP_EXCEPTION(DIERR_NOTINITIALIZED);
  3039. }
  3040. //Check parameters
  3041. if(!lpdiDevImageInfoHeader)
  3042. {
  3043. TRACE(_T("lpdiDevImageInfoHeader is NULL\n"));
  3044. throw MAP_EXCEPTION(E_INVALIDARG);
  3045. }
  3046. //Check structure sizes
  3047. if(lpdiDevImageInfoHeader->dwSize!=sizeof(DIDEVICEIMAGEINFOHEADER))
  3048. {
  3049. TRACE(_T("lpdiDevImageInfoHeader->dwSize is wrong size\n"));
  3050. throw MAP_EXCEPTION(E_INVALIDARG);
  3051. }
  3052. if(lpdiDevImageInfoHeader->dwBufferSize&&
  3053. lpdiDevImageInfoHeader->dwSizeImageInfo!=
  3054. sizeof(DIDEVICEIMAGEINFO))
  3055. {
  3056. TRACE(_T("lpdiDevImageInfoHeader->dwSizeImageInfo is wrong size\n"));
  3057. throw MAP_EXCEPTION(E_INVALIDARG);
  3058. }
  3059. //Check buffer size
  3060. if(lpdiDevImageInfoHeader->dwBufferSize&&
  3061. !lpdiDevImageInfoHeader->lprgImageInfoArray)
  3062. {
  3063. TRACE(_T("lpdiDevImageInfoHeader->\
  3064. dwBufferSize is not 0 and lpdiDevImageInfoHeader->\
  3065. lprgImageInfo is NULL\n"));
  3066. throw MAP_EXCEPTION(E_INVALIDARG);
  3067. }
  3068. DUMPN(_T("Vendor filename"),m_VFileName);
  3069. DUMPN(_T("Device name in vendor file"),m_VFileDevName);
  3070. HRESULT hRes=S_OK;
  3071. if((!m_bImageBufferSize)&&(!bGettingSize)&&
  3072. lpdiDevImageInfoHeader->dwBufferSize)
  3073. {
  3074. TRACE(_T("User forgot to inquire about buffer size.\n"));
  3075. DIDEVICEIMAGEINFOHEADER DIIH;
  3076. DIIH.dwSize=sizeof(DIIH);
  3077. DIIH.dwSizeImageInfo=sizeof(DIDEVICEIMAGEINFO);
  3078. DIIH.dwcViews=0;
  3079. DIIH.dwcButtons=0;
  3080. DIIH.dwcAxes=0;
  3081. DIIH.dwcPOVs=0;
  3082. DIIH.dwBufferSize=0;
  3083. DIIH.dwBufferUsed=0;
  3084. hRes=GetImageInfoInternal(&DIIH,true);
  3085. if(hRes!=S_OK)
  3086. return hRes;
  3087. }
  3088. //check if image info buffer is big enough
  3089. if(lpdiDevImageInfoHeader->dwBufferSize&&
  3090. (lpdiDevImageInfoHeader->dwBufferSize<
  3091. m_dwImageBufferSize))
  3092. {
  3093. TRACE(_T("lpdiDevImageInfoHeader->dwBufferSize is too small.\n"));
  3094. throw MAP_EXCEPTION(DIERR_MOREDATA );
  3095. }
  3096. //process configuration images
  3097. TRACE(_T("Processing DIDIFT_CONFIGURATION images.\n"));
  3098. lpdiDevImageInfoHeader->dwcViews=0;
  3099. DWORD dwImages=0;
  3100. do
  3101. {
  3102. if(IsImageInfoFull(lpdiDevImageInfoHeader,dwImages))break;
  3103. hRes=GetImageInfo((DeviceObjData*)NULL,
  3104. lpdiDevImageInfoHeader->dwcViews,
  3105. GetImageInfoAdr(lpdiDevImageInfoHeader,dwImages),
  3106. DIDIFT_CONFIGURATION);
  3107. if(hRes==S_OK)
  3108. {
  3109. lpdiDevImageInfoHeader->dwcViews++;
  3110. dwImages++;
  3111. }
  3112. }
  3113. while(hRes==S_OK);
  3114. #if 0
  3115. //process view select images
  3116. TRACE(_T("Processing DIDIFT_VIEWSELECT images.\n"));
  3117. for(int i=0;i<lpdiDevImageInfoHeader->dwcViews;i++)
  3118. {
  3119. if(IsImageInfoFull(lpdiDevImageInfoHeader,dwImages))break;
  3120. if(GetImageInfo((DeviceObjData*)NULL,i,
  3121. GetImageInfoAdr(lpdiDevImageInfoHeader,dwImages),
  3122. DIDIFT_VIEWSELECT)==S_OK)
  3123. dwImages++;
  3124. }
  3125. //process device selection image
  3126. TRACE(_T("Processing DIDIFT_SELECTION images.\n"));
  3127. if(!IsImageInfoFull(lpdiDevImageInfoHeader,dwImages))
  3128. {
  3129. if(GetImageInfo((DeviceObjData*)NULL,-1,
  3130. GetImageInfoAdr(lpdiDevImageInfoHeader,dwImages),
  3131. DIDIFT_SELECTION)==S_OK)
  3132. dwImages++;
  3133. }
  3134. #endif
  3135. //process control data
  3136. TRACE(_T("Processing DIDIFT_OVERLAY images.\n"));
  3137. DEVICEOBJLIST::iterator DevObjIt;
  3138. for(DevObjIt=m_DevObjList.begin();
  3139. DevObjIt!=m_DevObjList.end();DevObjIt++)
  3140. {
  3141. if(IsImageInfoFull(lpdiDevImageInfoHeader,dwImages))break;
  3142. for(int i=0;i<lpdiDevImageInfoHeader->dwcViews;i++)
  3143. {
  3144. if(IsImageInfoFull(lpdiDevImageInfoHeader,dwImages))break;
  3145. if(GetImageInfo(&(*DevObjIt),i,
  3146. GetImageInfoAdr(lpdiDevImageInfoHeader,dwImages),
  3147. DIDIFT_OVERLAY)==S_OK)
  3148. dwImages++;
  3149. }
  3150. }
  3151. lpdiDevImageInfoHeader->dwBufferUsed=
  3152. dwImages*sizeof(DIDEVICEIMAGEINFO);
  3153. if((!lpdiDevImageInfoHeader->dwBufferSize)&&(!m_bImageBufferSize))
  3154. {
  3155. m_bImageBufferSize=true;
  3156. m_dwImageBufferSize=lpdiDevImageInfoHeader->dwBufferUsed;
  3157. }
  3158. TRACE(_T("hRes=0x%x\n"),S_OK);
  3159. DUMP(lpdiDevImageInfoHeader);
  3160. return S_OK;
  3161. }
  3162. bool CDIMapObj::
  3163. GetImageInfoFileName(LPCTSTR lpKeyName,LPCTSTR lpSectionName,
  3164. DWORD dwIndex,LPDIDEVICEIMAGEINFO lpImageInfo)
  3165. {
  3166. METHOD_ENTRY(GetImageInfoFileName);
  3167. DUMP(lpSectionName);
  3168. DUMP(lpKeyName);
  3169. DUMP(dwIndex);
  3170. String KeyName=lpKeyName;
  3171. if(dwIndex!=-1)
  3172. KeyName+=_T(".")+N2Str(dwIndex);
  3173. String ImageFileName;
  3174. if(lpImageInfo)
  3175. lpImageInfo->tszImagePath[0]=0;
  3176. if(!LoadString(ImageFileName,m_VFileName.data(),
  3177. lpSectionName,KeyName.data(),true))
  3178. return false;
  3179. String Dir;
  3180. GetDirectory(m_VFileName.data(),Dir);
  3181. Dir+=ImageFileName;
  3182. if(Dir.size()>
  3183. (sizeof(lpImageInfo->tszImagePath)/
  3184. sizeof(lpImageInfo->tszImagePath[0])))
  3185. {
  3186. TRACE(_T("Image filename too long.\n"));
  3187. throw MAP_EXCEPTION(E_FILENAME_TO_LONG);
  3188. }
  3189. if(lpImageInfo)
  3190. _tcscpy(lpImageInfo->tszImagePath,Dir.data());
  3191. return true;
  3192. }
  3193. //keep flags for a while just in case we change our minds again
  3194. #if 0
  3195. void CDIMapObj::
  3196. GetImageInfoFormat(LPCTSTR lpKeyName,LPCTSTR lpSectionName,
  3197. DWORD dwIndex,LPDIDEVICEIMAGEINFO lpImageInfo)
  3198. {
  3199. if(lpImageInfo)
  3200. {
  3201. METHOD_ENTRY(GetImageInfoFormat);
  3202. DUMP(lpSectionName);
  3203. DUMP(lpKeyName);
  3204. DUMP(dwIndex);
  3205. String ImageFileFormatKeyName=lpKeyName;
  3206. if(dwIndex!=-1)
  3207. ImageFileFormatKeyName+=_T(".")+N2Str(dwIndex);
  3208. String ImageFileFormat;
  3209. if(!LoadString(ImageFileFormat,m_VFileName.data(),
  3210. lpSectionName,ImageFileFormatKeyName.data(),true))
  3211. lpImageInfo->dwFlags|=DIDIFT_IMAGE2D_BMP;
  3212. else
  3213. {
  3214. if(ImageFileFormat==_T("BMP"))
  3215. lpImageInfo->dwFlags|=DIDIFT_IMAGE2D_BMP;
  3216. else if(ImageFileFormat==_T("PNG"))
  3217. lpImageInfo->dwFlags|=DIDIFT_IMAGE2D_PNG;
  3218. else
  3219. {
  3220. TRACE(_T("Corrupt image type.\n"));
  3221. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  3222. }
  3223. }
  3224. }
  3225. }
  3226. #endif
  3227. bool ImageDataPresent(DWORD dwIndex,LPCTSTR pControlName,
  3228. LPCTSTR pVFileName)
  3229. {
  3230. TCHAR Ret[2];
  3231. String VisibleKeyName;
  3232. VisibleKeyName=OVERLAY_FILENAME;
  3233. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3234. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3235. _T(""),Ret,2,pVFileName))
  3236. return true;
  3237. VisibleKeyName=OVERLAY_FORMAT;
  3238. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3239. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3240. _T(""),Ret,2,pVFileName))
  3241. return true;
  3242. VisibleKeyName=OVERLAY_RECT;
  3243. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3244. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3245. _T(""),Ret,2,pVFileName))
  3246. return true;
  3247. VisibleKeyName=CONTROL_STRING_ALIGN;
  3248. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3249. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3250. _T(""),Ret,2,pVFileName))
  3251. return true;
  3252. VisibleKeyName=CALLOUTMAX;
  3253. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3254. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3255. _T(""),Ret,2,pVFileName))
  3256. return true;
  3257. VisibleKeyName=LINE_DATA;
  3258. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3259. if(GetPrivateProfileString(pControlName,VisibleKeyName.data(),
  3260. _T(""),Ret,2,pVFileName))
  3261. return true;
  3262. return false;
  3263. }
  3264. HRESULT CDIMapObj::GetImageInfo(
  3265. DeviceObjData *pDevObj,
  3266. DWORD dwIndex,
  3267. LPDIDEVICEIMAGEINFO lpImageInfo,
  3268. DWORD dwImageType)
  3269. {
  3270. METHOD_ENTRY(GetImageInfo);
  3271. DUMPN(_T("Image index"),dwIndex);
  3272. HRESULT hRes=S_OK;
  3273. //There must be vendor file when getting image data
  3274. if(!m_bVLoaded)
  3275. {
  3276. TRACE(_T("No vendor file or error in Initialize().\n"));
  3277. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  3278. }
  3279. switch(dwImageType)
  3280. {
  3281. case DIDIFT_CONFIGURATION:
  3282. if(GetImageInfoFileName(IMAGE_FILENAME,m_VFileDevName.data(),
  3283. dwIndex,lpImageInfo))
  3284. {
  3285. if(lpImageInfo)//we are not only counting
  3286. {
  3287. lpImageInfo->dwFlags=dwImageType;
  3288. lpImageInfo->dwViewID=dwIndex;
  3289. //keep flags for a while just in case we change our minds again
  3290. #if 0
  3291. GetImageInfoFormat(IMAGE_FORMAT,m_VFileDevName.data(),
  3292. dwIndex,lpImageInfo);
  3293. #endif
  3294. }
  3295. return S_OK;
  3296. }
  3297. else
  3298. {
  3299. if(dwIndex)
  3300. return S_FALSE;
  3301. else
  3302. {
  3303. //there must be at least one device view
  3304. TRACE(_T("There must be at least one device view, with index 0.\n"));
  3305. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  3306. }
  3307. }
  3308. break;
  3309. #if 0
  3310. case DIDIFT_SELECTION:
  3311. if(GetImageInfoFileName(SELECTION_FILENAME,m_VFileDevName.data(),
  3312. -1,lpImageInfo))
  3313. {
  3314. if(lpImageInfo)//we are not only counting
  3315. {
  3316. lpImageInfo->dwFlags=dwImageType;
  3317. //keep flags for a while just in case we change our minds again
  3318. #if 0
  3319. GetImageInfoFormat(SELECTION_FORMAT,m_VFileDevName.data(),
  3320. -1,lpImageInfo);
  3321. #endif
  3322. }
  3323. return S_OK;
  3324. }
  3325. else
  3326. return S_FALSE;
  3327. break;
  3328. case DIDIFT_VIEWSELECT:
  3329. if(GetImageInfoFileName(VIEWSELECT_FILENAME,m_VFileDevName.data(),
  3330. dwIndex,lpImageInfo))
  3331. {
  3332. if(lpImageInfo)//we are not only counting
  3333. {
  3334. lpImageInfo->dwFlags=dwImageType;
  3335. lpImageInfo->dwViewID=dwIndex;
  3336. //keep flags for a while just in case we change our minds again
  3337. #if 0
  3338. GetImageInfoFormat(VIEWSELECT_FORMAT,m_VFileDevName.data(),
  3339. dwIndex,lpImageInfo);
  3340. #endif
  3341. }
  3342. return S_OK;
  3343. }
  3344. else
  3345. return S_FALSE;
  3346. break;
  3347. #endif
  3348. case DIDIFT_OVERLAY:
  3349. {
  3350. //Get control section name
  3351. CONTROLLIST::iterator VCtrlDataIt=m_VCtrlData.begin();
  3352. while(VCtrlDataIt!=m_VCtrlData.end())
  3353. {
  3354. if(CompareData(*pDevObj,*VCtrlDataIt))break;
  3355. VCtrlDataIt++;
  3356. }
  3357. if(VCtrlDataIt==m_VCtrlData.end())
  3358. {
  3359. TRACE(_T("No control with obj ID in file.\n"));
  3360. return S_FALSE;//control with offset not found
  3361. }
  3362. //Section=VCtrlDataIt->ControlName.data();
  3363. DUMPN(_T("Control name in ini file"),VCtrlDataIt->ControlName);
  3364. //Is there ctrl image data
  3365. String VisibleKeyName=CONTROL_VISIBLE;
  3366. VisibleKeyName+=_T(".")+N2Str(dwIndex);
  3367. if(!GetPrivateProfileInt(VCtrlDataIt->ControlName.data(),
  3368. VisibleKeyName.data(),1,m_VFileName.data()))
  3369. {
  3370. TRACE(_T("No image data for this control.\n"));
  3371. return S_FALSE;//No control data
  3372. }
  3373. if(!ImageDataPresent(dwIndex,VCtrlDataIt->ControlName.data(),
  3374. m_VFileName.data()))
  3375. {
  3376. TRACE(_T("No image data for this control.\n"));
  3377. return S_FALSE;//No control data
  3378. }
  3379. if(!lpImageInfo)
  3380. return S_OK;//Just counting data...
  3381. lpImageInfo->dwFlags=dwImageType;
  3382. lpImageInfo->dwViewID=dwIndex;
  3383. lpImageInfo->dwObjID=pDevObj->dwType;
  3384. //Get overlay image data
  3385. if(GetImageInfoFileName(OVERLAY_FILENAME,
  3386. VCtrlDataIt->ControlName.data(),dwIndex,lpImageInfo))
  3387. {
  3388. TRACE(_T("There is image file name, reading rest.\n"));
  3389. //keep flags for a while just in case we change our minds again
  3390. #if 0
  3391. GetImageInfoFormat(OVERLAY_FORMAT,
  3392. VCtrlDataIt->ControlName.data(),dwIndex,lpImageInfo);
  3393. #endif
  3394. //Get overlay rect
  3395. DWORD dwOverlayRectCnt;
  3396. String OverlayRectKeyName=OVERLAY_RECT;
  3397. OverlayRectKeyName+=_T(".")+N2Str(dwIndex);
  3398. POINT OverlayRect[2];
  3399. if(LoadPointArray(m_VFileName.data(),
  3400. VCtrlDataIt->ControlName.data(),
  3401. OverlayRectKeyName.data(),OverlayRect,
  3402. dwOverlayRectCnt,2))
  3403. {
  3404. if(dwOverlayRectCnt!=2)
  3405. {
  3406. TRACE(_T("Corrupt overlay rect data.\n"));
  3407. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  3408. }
  3409. lpImageInfo->rcOverlay.left=OverlayRect[0].x;
  3410. lpImageInfo->rcOverlay.top=OverlayRect[0].y;
  3411. lpImageInfo->rcOverlay.right=OverlayRect[1].x;
  3412. lpImageInfo->rcOverlay.bottom=OverlayRect[1].y;
  3413. }
  3414. else
  3415. {
  3416. lpImageInfo->rcOverlay.left=0;
  3417. lpImageInfo->rcOverlay.top=0;
  3418. lpImageInfo->rcOverlay.right=100;
  3419. lpImageInfo->rcOverlay.bottom=20;
  3420. }
  3421. }
  3422. //Get string alignment
  3423. String KeyName=CONTROL_STRING_ALIGN;
  3424. KeyName+=_T(".")+N2Str(dwIndex);
  3425. String Align;
  3426. if(!LoadString(Align,m_VFileName.data(),
  3427. VCtrlDataIt->ControlName.data(),KeyName.data(),true))
  3428. lpImageInfo->dwTextAlign=DIDAL_CENTERED|DIDAL_MIDDLE;
  3429. else
  3430. {
  3431. if(Align==_T("C"))
  3432. lpImageInfo->dwTextAlign=
  3433. DIDAL_CENTERED|DIDAL_MIDDLE;
  3434. else if(Align==_T("L"))
  3435. lpImageInfo->dwTextAlign=
  3436. DIDAL_LEFTALIGNED|DIDAL_MIDDLE;
  3437. else if(Align==_T("R"))
  3438. lpImageInfo->dwTextAlign=
  3439. DIDAL_RIGHTALIGNED|DIDAL_MIDDLE;
  3440. else if(Align==_T("T"))
  3441. lpImageInfo->dwTextAlign=
  3442. DIDAL_CENTERED|DIDAL_TOPALIGNED;
  3443. else if(Align==_T("B"))
  3444. lpImageInfo->dwTextAlign=
  3445. DIDAL_CENTERED|DIDAL_BOTTOMALIGNED;
  3446. else if(Align==_T("TL"))
  3447. lpImageInfo->dwTextAlign=
  3448. DIDAL_LEFTALIGNED|DIDAL_TOPALIGNED;
  3449. else if(Align==_T("TR"))
  3450. lpImageInfo->dwTextAlign=
  3451. DIDAL_RIGHTALIGNED|DIDAL_TOPALIGNED;
  3452. else if(Align==_T("BL"))
  3453. lpImageInfo->dwTextAlign=
  3454. DIDAL_LEFTALIGNED|DIDAL_BOTTOMALIGNED;
  3455. else if(Align==_T("BR"))
  3456. lpImageInfo->dwTextAlign=
  3457. DIDAL_RIGHTALIGNED|DIDAL_BOTTOMALIGNED;
  3458. else
  3459. {
  3460. TRACE(_T("Corrupt align data.\n"));
  3461. throw MAP_EXCEPTION(E_WRONG_ALIGN_DATA);
  3462. }
  3463. }
  3464. //Get call out rect
  3465. DWORD dwCallOutMaxCnt;
  3466. String CallOutMaxKeyName=CALLOUTMAX;
  3467. CallOutMaxKeyName+=_T(".")+N2Str(dwIndex);
  3468. POINT Callout[2];
  3469. if(LoadPointArray(m_VFileName.data(),
  3470. VCtrlDataIt->ControlName.data(),
  3471. CallOutMaxKeyName.data(),Callout,
  3472. dwCallOutMaxCnt,2))
  3473. {
  3474. if(dwCallOutMaxCnt!=2)
  3475. {
  3476. TRACE(_T("Corrupt callout rect data.\n"));
  3477. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  3478. }
  3479. lpImageInfo->rcCalloutRect.left=Callout[0].x;
  3480. lpImageInfo->rcCalloutRect.top=Callout[0].y;
  3481. lpImageInfo->rcCalloutRect.right=Callout[1].x;
  3482. lpImageInfo->rcCalloutRect.bottom=Callout[1].y;
  3483. }
  3484. else
  3485. {
  3486. lpImageInfo->rcCalloutRect.left=0;
  3487. lpImageInfo->rcCalloutRect.top=0;
  3488. lpImageInfo->rcCalloutRect.right=100;
  3489. lpImageInfo->rcCalloutRect.bottom=20;
  3490. }
  3491. //Get line data
  3492. String PointArrayKeyName=LINE_DATA;
  3493. PointArrayKeyName+=_T(".")+N2Str(dwIndex);
  3494. LoadPointArray(m_VFileName.data(),
  3495. VCtrlDataIt->ControlName.data(),
  3496. PointArrayKeyName.data(),
  3497. lpImageInfo->rgptCalloutLine,
  3498. lpImageInfo->dwcValidPts,
  3499. sizeof(lpImageInfo->rgptCalloutLine)/
  3500. sizeof(lpImageInfo->rgptCalloutLine[0]));
  3501. return S_OK;
  3502. }
  3503. break;
  3504. default:
  3505. TRACE(_T("Internal error!!!!\n"));
  3506. throw MAP_EXCEPTION(E_INVALIDARG);break;
  3507. }
  3508. return S_FALSE;
  3509. }
  3510. HRESULT CDIMapObj::GetActionMapI(
  3511. LPDIACTIONFORMAT lpDiActionFormat,
  3512. LPCTSTR lpctstrUserName,
  3513. FILETIME *pTimestamp,DWORD dwFlags)
  3514. {
  3515. try
  3516. {
  3517. GETACTIONMAP_ENTERED;
  3518. TRACE(_T("Parameters:\n"));
  3519. DUMP(lpDiActionFormat);
  3520. DUMP(lpctstrUserName);
  3521. TRACE(_T("\n"));
  3522. //Check if initialized
  3523. if(!m_bInitialized)
  3524. {
  3525. TRACE(_T("Object not initialized\n"));
  3526. throw MAP_EXCEPTION(DIERR_NOTINITIALIZED);
  3527. }
  3528. //Check parameters
  3529. if(!lpDiActionFormat)
  3530. {
  3531. TRACE(_T("lpDiActionFormat is NULL\n"));
  3532. throw MAP_EXCEPTION(E_INVALIDARG);
  3533. }
  3534. //Check structure sizes
  3535. if(lpDiActionFormat->dwSize!=sizeof(*lpDiActionFormat))
  3536. {
  3537. TRACE(_T("lpDiActionFormat->\
  3538. dwSize is wrong size\n"));
  3539. throw MAP_EXCEPTION(E_INVALIDARG);
  3540. }
  3541. if(lpDiActionFormat->dwActionSize!=
  3542. sizeof(*(lpDiActionFormat->rgoAction)))
  3543. {
  3544. TRACE(_T("lpDiActionFormat->\
  3545. dwActionSize is wrong size\n"));
  3546. throw MAP_EXCEPTION(E_INVALIDARG);
  3547. }
  3548. //Check how many actions, should be more than 0
  3549. if(!lpDiActionFormat->dwNumActions)
  3550. {
  3551. TRACE(_T("lpDiActionFormat->dwNumActions is 0\n"));
  3552. throw MAP_EXCEPTION(E_INVALIDARG);
  3553. }
  3554. //Check ptr to the action array
  3555. if(!lpDiActionFormat->rgoAction)
  3556. {
  3557. TRACE(_T("lpDiActionFormat->rgoAction is NULL\n"));
  3558. throw MAP_EXCEPTION(E_INVALIDARG);
  3559. }
  3560. DWORD dwNOfMappedActions=0;
  3561. bool bDoNotMapControl=false;//is this per control or action???
  3562. bool bDoNotMapGenre=false;
  3563. WhichDeviceObjectIsMapped(
  3564. lpDiActionFormat,m_DevObjList,&m_DeviceGuid);
  3565. bool bMapExists=false;//sticky flag, must set to false
  3566. if(!(DIDBAM_HWDEFAULTS&dwFlags))
  3567. {
  3568. TRACE(_T("No DIDBAM_HWDEFAULTS flag, map user file first."));
  3569. //Map the user file first
  3570. LoadUserData(lpctstrUserName,lpDiActionFormat);
  3571. DUMPN(_T("User File Name"),m_UFileName.data());
  3572. lpDiActionFormat->ftTimeStamp=m_UTimestamp;
  3573. if(m_bULoaded)//file was sucessfully preloaded...
  3574. {
  3575. TRACE(_T("User file loaded.\n"));
  3576. MapDevice(lpDiActionFormat,m_UFileName.data(),
  3577. m_UFileDevName.data(),
  3578. &m_DeviceGuid,m_DevObjList,m_UCtrlData,
  3579. DIAH_USERCONFIG,DIAH_USERCONFIG,
  3580. dwNOfMappedActions,&bMapExists,true);
  3581. }
  3582. }
  3583. if(m_lpVFileName&&m_bVLoaded&&
  3584. ((DIDBAM_HWDEFAULTS&dwFlags)||!bMapExists))
  3585. {
  3586. TRACE(_T("Vendor file loaded.\n"));
  3587. //Check if there are unmapped entries
  3588. for(DWORD i=0;i<lpDiActionFormat->dwNumActions;i++)
  3589. {
  3590. if((lpDiActionFormat->rgoAction[i].guidInstance==NULLGUID)
  3591. ||((lpDiActionFormat->rgoAction[i].guidInstance==m_DeviceGuid)
  3592. &&(lpDiActionFormat->rgoAction[i].dwHow==DIAH_UNMAPPED)
  3593. &&((lpDiActionFormat->rgoAction[i].dwFlags&DIA_APPNOMAP)==0)))
  3594. {
  3595. TRACE(_T("Unmapped action found, mapping vendor file.\n"));
  3596. //If there are unmapped entries, map manufacturer file
  3597. DUMPN(_T("Vendor file name"),m_lpVFileName);
  3598. MapDevice(lpDiActionFormat,m_lpVFileName,
  3599. m_VFileDevName.data(),&m_DeviceGuid,m_DevObjList,
  3600. m_VCtrlData,DIAH_HWDEFAULT,DIAH_HWAPP,
  3601. dwNOfMappedActions,NULL,false);
  3602. break;
  3603. }
  3604. }
  3605. }
  3606. if(dwNOfMappedActions)
  3607. {
  3608. DUMP(dwNOfMappedActions);
  3609. TRACE(_T("hRes=0x%x\n"),S_OK);
  3610. DUMP(lpDiActionFormat);
  3611. return S_OK;
  3612. }
  3613. if((!(DIDBAM_HWDEFAULTS&dwFlags))&&bMapExists)
  3614. {
  3615. TRACE(_T("hRes=0x%x\n"),S_FALSE);
  3616. return S_FALSE;
  3617. }
  3618. TRACE(_T("hRes=0x%x\n"),S_NOMAP);
  3619. return S_NOMAP;
  3620. }
  3621. catch(MapException E)
  3622. {
  3623. return E.GetResult();
  3624. }
  3625. catch(exception)
  3626. {
  3627. USETRACER();
  3628. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  3629. return E_FAIL;
  3630. }
  3631. }
  3632. void CDIMapObj::Resinc(LPDIACTIONFORMAT lpDiActionFormat)
  3633. {
  3634. TRACE(_T("Resincing object after writing.\n"));
  3635. LoadUserData(NULL,lpDiActionFormat,true);
  3636. }
  3637. HRESULT CDIMapObj::SaveActionMapI(
  3638. LPDIACTIONFORMAT lpDiActionFormat,
  3639. LPCTSTR lpctstrUserName,
  3640. DWORD dwFlags)
  3641. {
  3642. try
  3643. {
  3644. SAVEACTIONMAP_ENTERED;
  3645. TRACE(_T("Parameters:\n"));
  3646. DUMP(lpDiActionFormat);
  3647. DUMP(lpctstrUserName);
  3648. TRACE(_T("\n"));
  3649. //Check if initialized
  3650. if(!m_bInitialized)
  3651. {
  3652. TRACE(_T("Object not initialized\n"));
  3653. throw MAP_EXCEPTION(DIERR_NOTINITIALIZED);
  3654. }
  3655. //Check parameters
  3656. if(!lpDiActionFormat)
  3657. {
  3658. TRACE(_T("lpDiActionFormat is NULL\n"));
  3659. throw MAP_EXCEPTION(E_INVALIDARG);
  3660. }
  3661. //Check structure sizes
  3662. if(lpDiActionFormat->dwSize!=sizeof(*lpDiActionFormat))
  3663. {
  3664. TRACE(_T("lpDiActionFormat->\
  3665. dwSize is wrong size\n"));
  3666. throw MAP_EXCEPTION(E_INVALIDARG);
  3667. }
  3668. if(lpDiActionFormat->dwActionSize!=
  3669. sizeof(*(lpDiActionFormat->rgoAction)))
  3670. {
  3671. TRACE(_T("lpDiActionFormat->\
  3672. dwActionSize is wrong size\n"));
  3673. throw MAP_EXCEPTION(E_INVALIDARG);
  3674. }
  3675. //Check how many actions, should be more than 0
  3676. if(!lpDiActionFormat->dwNumActions)
  3677. {
  3678. TRACE(_T("lpDiActionFormat->dwNumActions is 0\n"));
  3679. throw MAP_EXCEPTION(E_INVALIDARG);
  3680. }
  3681. //Check ptr to the action array
  3682. if(!lpDiActionFormat->rgoAction)
  3683. {
  3684. TRACE(_T("lpDiActionFormat->rgoAction is NULL\n"));
  3685. throw MAP_EXCEPTION(E_INVALIDARG);
  3686. }
  3687. //this also creates directory if necessary
  3688. LoadUserData(lpctstrUserName,lpDiActionFormat,false,true);
  3689. SaveActionMapUV(
  3690. lpDiActionFormat,
  3691. m_bULoaded,
  3692. m_UFileName.data(),
  3693. m_UFileDevName,
  3694. m_UCtrlData,
  3695. NULL,
  3696. DIAH_USERCONFIG,DIAH_USERCONFIG,true);
  3697. Resinc(lpDiActionFormat);
  3698. TRACE(_T("hRes=0x%x\n"),S_OK);
  3699. return S_OK;
  3700. }
  3701. catch(MapException E)
  3702. {
  3703. return E.GetResult();
  3704. }
  3705. catch(exception)
  3706. {
  3707. USETRACER();
  3708. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  3709. return E_FAIL;
  3710. }
  3711. }
  3712. void CDIMapObj::WriteImageInfo(LPCTSTR lpFileKeyName,
  3713. LPCTSTR lpFormatKeyName,
  3714. LPCTSTR lpSectionName,
  3715. LPDIDEVICEIMAGEINFO lpImageInfo,
  3716. bool bAddIndex,
  3717. bool bDelete)
  3718. {
  3719. if(lpImageInfo->tszImagePath[0]||bDelete)
  3720. {
  3721. String FileKeyName=lpFileKeyName;
  3722. if(bAddIndex)
  3723. FileKeyName+=_T(".")+N2Str(lpImageInfo->dwViewID);
  3724. String ImageFileName;
  3725. LPCTSTR pImageFileName=NULL;
  3726. if(!bDelete)
  3727. {
  3728. StripDirectory(lpImageInfo->tszImagePath,ImageFileName);
  3729. pImageFileName=ImageFileName.data();
  3730. }
  3731. if(!WritePrivateProfileString(lpSectionName,FileKeyName.data(),
  3732. pImageFileName,m_VFileName.data()))
  3733. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  3734. //keep flags for a while just in case we change our minds again
  3735. #if 0
  3736. String FormatKeyName=lpFormatKeyName;
  3737. if(bAddIndex)
  3738. FormatKeyName+=_T(".")+N2Str(lpImageInfo->dwViewID);
  3739. String ImageFileFormat;
  3740. LPCTSTR pImageFileFormat=NULL;
  3741. if(!bDelete)
  3742. {
  3743. if(lpImageInfo->dwFlags&DIDIFT_IMAGE2D_PNG)
  3744. ImageFileFormat=_T("PNG");
  3745. else
  3746. ImageFileFormat=_T("BMP");
  3747. pImageFileFormat=ImageFileFormat.data();
  3748. }
  3749. if(!WritePrivateProfileString(lpSectionName,FormatKeyName.data(),
  3750. pImageFileFormat,m_VFileName.data()))
  3751. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  3752. #endif
  3753. }
  3754. }
  3755. void CDIMapObj::MakeNewControlName(String &CtrlName,
  3756. DEVICEOBJLIST::iterator DevObjIt,
  3757. CONTROLLIST &ControlsData,
  3758. String &FileDevName,
  3759. STRINGLIST &ControlsAllDevs,
  3760. STRINGLIST &Controls)
  3761. {
  3762. ControlData *pCtrlData=NULL;
  3763. if(&ControlsData==&m_UCtrlData)
  3764. pCtrlData=DevObjIt->pUCtrlData;
  3765. else
  3766. pCtrlData=DevObjIt->pVCtrlData;
  3767. //Was control data allready in the file
  3768. if(!pCtrlData)
  3769. {
  3770. //No control data in the file
  3771. //Make unique control name for the file
  3772. ControlData ControlDataCur;
  3773. ControlDataCur.ControlName=_T("Ctrl");
  3774. ControlDataCur.ControlName+=N2Str(DevObjIt->dwOffset);
  3775. //ControlDataCur.ControlName+=FileDevName;
  3776. ToUpper(ControlDataCur.ControlName);
  3777. MakeUniqueName(ControlDataCur.ControlName,ControlsAllDevs);
  3778. //Now add this control name into the list
  3779. CS S;
  3780. S.assign(ControlDataCur.ControlName);
  3781. Controls.push_back(S);
  3782. //Store data for this control into the list
  3783. ControlsData.push_back(ControlDataCur);
  3784. //Here bind device obj and control data
  3785. ControlsData.back().pDevObj=&(*DevObjIt);
  3786. if(&ControlsData==&m_UCtrlData)
  3787. pCtrlData=DevObjIt->pUCtrlData=&ControlsData.back();
  3788. else
  3789. pCtrlData=DevObjIt->pVCtrlData=&ControlsData.back();
  3790. }
  3791. CtrlName=pCtrlData->ControlName;
  3792. }
  3793. void WriteCtrlData(DEVICEOBJLIST::iterator DevObjIt,
  3794. LPCTSTR pCtrlName,LPCTSTR pFileName)
  3795. {
  3796. //Write offset
  3797. WritePrivateProfileIntX(pCtrlName,OFFSET,
  3798. DevObjIt->dwOffset,pFileName);
  3799. //Write USB usage/usagepage if available
  3800. if(DevObjIt->dwUsage&&DevObjIt->dwUsagePage)
  3801. {
  3802. WritePrivateProfileIntX(pCtrlName,USAGEPAGE,
  3803. DevObjIt->dwUsagePage,pFileName);
  3804. WritePrivateProfileIntX(pCtrlName,USAGE,
  3805. DevObjIt->dwUsage,pFileName);
  3806. }
  3807. //Write control name
  3808. if(!WritePrivateProfileString(pCtrlName,NAME,
  3809. DevObjIt->Name.data(),pFileName))
  3810. {
  3811. TRACE(_T("Error writing ini file.\n"));
  3812. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  3813. }
  3814. }
  3815. void CDIMapObj::
  3816. SaveActionMapUV(
  3817. LPDIACTIONFORMAT lpDiActionFormat,
  3818. bool bDevInFileLoaded,
  3819. LPCTSTR pFileName,
  3820. String &FileDevName,
  3821. CONTROLLIST &ControlsData,
  3822. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  3823. DWORD dwHowDev,DWORD dwHowApp,bool bUserFile)
  3824. {
  3825. METHOD_ENTRY(SaveActionMapUV);
  3826. DUMPN(_T("Filename"),pFileName);
  3827. //Write allways ,just to update name with lattest.
  3828. WritePrivateProfileIntX(DIRECT_INPUT,DIRECTX_VERSION,
  3829. 0x800,pFileName);
  3830. //Load list of devices in the file
  3831. STRINGLIST Devices;
  3832. LoadListOfStrings(pFileName,DIRECT_INPUT,DEVICES,Devices,true);
  3833. if(!bDevInFileLoaded)
  3834. {
  3835. TRACE(_T("Device not in file.\n"));
  3836. FileDevName=m_DeviceName;
  3837. //Find unique device name and add the list
  3838. MakeUniqueName(FileDevName,Devices);
  3839. //Write list of devices
  3840. WriteListOfStrings(DIRECT_INPUT,DEVICES,Devices,pFileName);
  3841. //Write VID and PID
  3842. if(m_dwThisVendorID&&m_dwThisProductID)
  3843. {
  3844. WritePrivateProfileIntX(FileDevName.data(),VENDORID,
  3845. m_dwThisVendorID,pFileName);
  3846. WritePrivateProfileIntX(FileDevName.data(),PRODUCTID,
  3847. m_dwThisProductID,pFileName);
  3848. }
  3849. //Write device name.
  3850. if(!WritePrivateProfileString(FileDevName.data(),NAME,
  3851. m_DeviceName.data(),pFileName))
  3852. {
  3853. TRACE(_T("Error writing ini file.\n"));
  3854. throw MAP_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  3855. }
  3856. }
  3857. DUMPN(_T("Device name in file"),FileDevName);
  3858. //write timestamp, but only if we are processing user file
  3859. if(&ControlsData==&m_UCtrlData)
  3860. WriteTimestamp(pFileName,FileDevName.data(),
  3861. lpDiActionFormat->guidActionMap,lpDiActionFormat);
  3862. //Load list of controls for this device in the file
  3863. STRINGLIST Controls;
  3864. LoadListOfStrings(pFileName,FileDevName.data(),CONTROLS,Controls,true);
  3865. //Load list of controls for all devices in the file
  3866. STRINGLIST ControlsAllDevs;
  3867. for(STRINGLIST::iterator DevIt=Devices.begin();
  3868. DevIt!=Devices.end();DevIt++)
  3869. LoadListOfStrings(pFileName,DevIt->data(),CONTROLS,
  3870. ControlsAllDevs,true);
  3871. // bool bOtherAppFirst=true;
  3872. // bool bUserConfig=true;
  3873. //Delete old sections and create empty mapping
  3874. String GenreName;
  3875. //Game specific section
  3876. //Get section name
  3877. MakeGenreName(GenreName,FileDevName.data(),
  3878. lpDiActionFormat->dwGenre,&lpDiActionFormat->guidActionMap);
  3879. //Find out if this is first writting
  3880. bool bFirstWrite=!GetPrivateProfileInt(GenreName.data(),
  3881. MAPEXISTS,0,pFileName);
  3882. UINT nNoOfMappings=-1;
  3883. if(!bFirstWrite)
  3884. {
  3885. nNoOfMappings=GetPrivateProfileInt(GenreName.data(),
  3886. NUMACTIONS,-1,pFileName);
  3887. }
  3888. //Delete section
  3889. if(!WritePrivateProfileString(GenreName.data(),NULL,
  3890. NULL,pFileName))
  3891. {
  3892. TRACE(_T("Error writing ini file.\n"));
  3893. throw MAP_EXCEPTION(
  3894. HRESULT_FROM_WIN32(GetLastError()));
  3895. }
  3896. //Write numbet of actions
  3897. if(bUserFile)
  3898. {
  3899. if(bFirstWrite)
  3900. WritePrivateProfileInt(GenreName.data(),NUMACTIONS,
  3901. lpDiActionFormat->dwNumActions,pFileName);
  3902. else
  3903. WritePrivateProfileInt(GenreName.data(),NUMACTIONS,
  3904. nNoOfMappings,pFileName);
  3905. }
  3906. //Mark that section exists
  3907. WritePrivateProfileInt(GenreName.data(),
  3908. MAPEXISTS,1,pFileName);
  3909. //General section (not game specific)
  3910. //Delete section
  3911. MakeGenreName(GenreName,FileDevName.data(),
  3912. lpDiActionFormat->dwGenre,NULL);
  3913. if(!WritePrivateProfileString(GenreName.data(),NULL,
  3914. NULL,pFileName))
  3915. {
  3916. TRACE(_T("Error writing ini file.\n"));
  3917. throw MAP_EXCEPTION(
  3918. HRESULT_FROM_WIN32(GetLastError()));
  3919. }
  3920. //Mark that section exist
  3921. if(!bUserFile)
  3922. WritePrivateProfileInt(GenreName.data(),
  3923. MAPEXISTS,1,pFileName);
  3924. TRACE(_T("Looking for action to write.\n"));
  3925. //Iterate through all the actions and store control data
  3926. for(DWORD dwAct=0;dwAct<lpDiActionFormat->dwNumActions;dwAct++)
  3927. {
  3928. DWORD dwHow=lpDiActionFormat->rgoAction[dwAct].dwHow;
  3929. if(!(lpDiActionFormat->rgoAction[dwAct].guidInstance==
  3930. m_DeviceGuid))
  3931. continue;
  3932. if(bUserFile)
  3933. {
  3934. if(!(dwHow&
  3935. (DIAH_USERCONFIG|DIAH_APPREQUESTED|DIAH_HWAPP|
  3936. DIAH_HWDEFAULT|DIAH_DEFAULT)))
  3937. continue;
  3938. }
  3939. else
  3940. {
  3941. if(!(dwHow&(DIAH_HWAPP|DIAH_HWDEFAULT)))
  3942. continue;
  3943. }
  3944. if(bUserFile)
  3945. dwHow=DIAH_HWAPP;
  3946. String CtrlName;
  3947. #ifdef _CHECKED
  3948. int nObjIndex=-1;
  3949. #endif
  3950. //Find device object with same offset
  3951. for(DEVICEOBJLIST::iterator DevObjIt=m_DevObjList.begin();
  3952. DevObjIt!=m_DevObjList.end();DevObjIt++)
  3953. {
  3954. #ifdef _CHECKED
  3955. nObjIndex++;
  3956. #endif
  3957. if((DIDFT_FINDMASK&DevObjIt->dwOffset)!=
  3958. (DIDFT_FINDMASK&lpDiActionFormat->rgoAction[dwAct].dwObjID))
  3959. continue;
  3960. if(((DIDFT_FINDMASK&DevObjIt->dwOffset)==
  3961. (DIDFT_FINDMASK&lpDiActionFormat->rgoAction[dwAct].dwObjID))&&
  3962. CompareTypeObjAct(DevObjIt->dwType,
  3963. lpDiActionFormat->rgoAction[dwAct].dwSemantic))
  3964. {
  3965. #ifdef _CHECKED
  3966. TRACE(_T("To write found action %u matched with devobj %u\n"),
  3967. dwAct,nObjIndex);
  3968. #endif
  3969. //Device object found
  3970. //Now find file control name
  3971. MakeNewControlName(CtrlName,DevObjIt,
  3972. ControlsData,FileDevName,ControlsAllDevs,Controls);
  3973. DUMPN(_T("control name in file"),CtrlName);
  3974. WriteCtrlData(DevObjIt,CtrlName.data(),pFileName);
  3975. //Make section genre name
  3976. String GenreName;
  3977. LPCGUID lpAppGUID=NULL;
  3978. if(dwHow&DIAH_HWAPP)
  3979. lpAppGUID=&lpDiActionFormat->guidActionMap;
  3980. MakeGenreName(GenreName,FileDevName.data(),
  3981. lpDiActionFormat->dwGenre,lpAppGUID);
  3982. /*
  3983. bool bDelSect=false;
  3984. if(bOtherAppFirst&&(dwHow&DIAH_HWAPP))
  3985. {
  3986. bOtherAppFirst=false;
  3987. bDelSect=true;
  3988. }
  3989. if(bUserConfig&&(dwHow&DIAH_HWDEFAULT))
  3990. {
  3991. bUserConfig=false;
  3992. bDelSect=true;
  3993. }
  3994. //Delete section if necessary
  3995. if(bDelSect)
  3996. {
  3997. TRACE(_T("First write to this section, deleting section."));
  3998. if(!WritePrivateProfileString(GenreName.data(),NULL,
  3999. NULL,pFileName))
  4000. {
  4001. TRACE(_T("Error writing ini file.\n"));
  4002. throw MAP_EXCEPTION(
  4003. HRESULT_FROM_WIN32(GetLastError()));
  4004. }
  4005. //Put flag that this mapping exists
  4006. WritePrivateProfileInt(GenreName.data(),
  4007. MAPEXISTS,1,pFileName);
  4008. }
  4009. */
  4010. //Now update genre mapping
  4011. WritePrivateProfileIntX(GenreName.data(),CtrlName.data(),
  4012. GetFileSemantic(
  4013. lpDiActionFormat->rgoAction[dwAct].dwSemantic,
  4014. dwHowDev),
  4015. pFileName);
  4016. break;
  4017. }
  4018. }
  4019. }
  4020. if(lpdiDevImageInfoHeader)
  4021. {
  4022. m_bImageBufferSize=false;
  4023. m_dwImageBufferSize=0;
  4024. for(int i=0;i<(lpdiDevImageInfoHeader->dwBufferUsed/
  4025. lpdiDevImageInfoHeader->dwSizeImageInfo);i++)
  4026. {
  4027. LPDIDEVICEIMAGEINFO lpImageInfo=
  4028. &lpdiDevImageInfoHeader->lprgImageInfoArray[i];
  4029. DWORD dwFlags=lpImageInfo->dwFlags;
  4030. if(dwFlags&DIDIFT_CONFIGURATION)
  4031. {
  4032. WriteImageInfo(IMAGE_FILENAME,IMAGE_FORMAT,
  4033. FileDevName.data(),
  4034. lpImageInfo,true,(dwFlags&DIDIFT_DELETE)?true:false);
  4035. }
  4036. #if 0
  4037. else if(dwFlags&DIDIFT_SELECTION)
  4038. {
  4039. WriteImageInfo(SELECTION_FILENAME,SELECTION_FORMAT,
  4040. FileDevName.data(),
  4041. lpImageInfo,false,(dwFlags&DIDIFT_DELETE)?true:false);
  4042. }
  4043. else if(dwFlags&DIDIFT_VIEWSELECT)
  4044. {
  4045. WriteImageInfo(VIEWSELECT_FILENAME,VIEWSELECT_FORMAT,
  4046. FileDevName.data(),
  4047. lpImageInfo,true,(dwFlags&DIDIFT_DELETE)?true:false);
  4048. }
  4049. #endif
  4050. else if(dwFlags&DIDIFT_OVERLAY)
  4051. {
  4052. String CtrlName;
  4053. //Find device object with same offset
  4054. for(DEVICEOBJLIST::iterator DevObjIt=m_DevObjList.begin();
  4055. DevObjIt!=m_DevObjList.end();DevObjIt++)
  4056. {
  4057. if((DIDFT_FINDMASK&lpImageInfo->dwObjID)
  4058. ==(DIDFT_FINDMASK&DevObjIt->dwType))
  4059. {
  4060. //Device object found
  4061. //Now find file control name
  4062. String CtrlName;
  4063. MakeNewControlName(CtrlName,DevObjIt,
  4064. ControlsData,FileDevName,
  4065. ControlsAllDevs,Controls);
  4066. WriteCtrlData(DevObjIt,CtrlName.data(),pFileName);
  4067. //Write file name and format
  4068. WriteImageInfo(OVERLAY_FILENAME,
  4069. OVERLAY_FORMAT,CtrlName.data(),
  4070. lpImageInfo,true,
  4071. (dwFlags&DIDIFT_DELETE)?true:false);
  4072. //Write overlay rect
  4073. if(lpImageInfo->tszImagePath[0]||
  4074. (dwFlags&DIDIFT_DELETE))
  4075. {
  4076. //Get overlay rect
  4077. String OverlayRectKeyName=OVERLAY_RECT;
  4078. OverlayRectKeyName+=
  4079. _T(".")+N2Str(lpImageInfo->dwViewID);
  4080. if(dwFlags&DIDIFT_DELETE)
  4081. {
  4082. if(!WritePrivateProfileString(
  4083. CtrlName.data(),
  4084. OverlayRectKeyName.data(),
  4085. NULL,
  4086. m_VFileName.data()))
  4087. throw MAP_EXCEPTION(
  4088. HRESULT_FROM_WIN32(
  4089. GetLastError()));
  4090. }
  4091. else
  4092. WriteRect(CtrlName.data(),
  4093. OverlayRectKeyName.data(),
  4094. &lpImageInfo->rcOverlay,
  4095. m_VFileName.data());
  4096. }
  4097. //Write string alignment
  4098. String AlignKeyName=CONTROL_STRING_ALIGN;
  4099. AlignKeyName+=
  4100. _T(".")+N2Str(lpImageInfo->dwViewID);
  4101. String Align;
  4102. LPCTSTR pAlign=NULL;
  4103. if(!(dwFlags&DIDIFT_DELETE))
  4104. {
  4105. if(lpImageInfo->dwTextAlign&
  4106. DIDAL_TOPALIGNED)
  4107. Align=_T("T");
  4108. else if(lpImageInfo->dwTextAlign&
  4109. DIDAL_BOTTOMALIGNED)
  4110. Align=_T("B");
  4111. if(lpImageInfo->dwTextAlign&
  4112. DIDAL_LEFTALIGNED)
  4113. Align+=_T("L");
  4114. else if(lpImageInfo->dwTextAlign&
  4115. DIDAL_RIGHTALIGNED)
  4116. Align+=_T("R");
  4117. if(Align==_T(""))
  4118. Align=_T("C");
  4119. pAlign=Align.data();
  4120. }
  4121. if(!WritePrivateProfileString(
  4122. CtrlName.data(),
  4123. AlignKeyName.data(),
  4124. pAlign,
  4125. m_VFileName.data()))
  4126. throw MAP_EXCEPTION(
  4127. HRESULT_FROM_WIN32(GetLastError()));
  4128. //Write call out rect
  4129. String CallOutMaxKeyName=CALLOUTMAX;
  4130. CallOutMaxKeyName+=
  4131. _T(".")+N2Str(lpImageInfo->dwViewID);
  4132. if(dwFlags&DIDIFT_DELETE)
  4133. {
  4134. if(!WritePrivateProfileString(
  4135. CtrlName.data(),
  4136. CallOutMaxKeyName.data(),
  4137. NULL,
  4138. m_VFileName.data()))
  4139. throw MAP_EXCEPTION(
  4140. HRESULT_FROM_WIN32(
  4141. GetLastError()));
  4142. }
  4143. else
  4144. WriteRect(CtrlName.data(),
  4145. CallOutMaxKeyName.data(),
  4146. &lpImageInfo->rcCalloutRect,
  4147. m_VFileName.data());
  4148. //Write line data
  4149. String PointArrayKeyName=LINE_DATA;
  4150. PointArrayKeyName+=
  4151. _T(".")+N2Str(lpImageInfo->dwViewID);
  4152. if(dwFlags&DIDIFT_DELETE)
  4153. {
  4154. if(!WritePrivateProfileString(
  4155. CtrlName.data(),
  4156. PointArrayKeyName.data(),
  4157. NULL,
  4158. m_VFileName.data()))
  4159. throw MAP_EXCEPTION(
  4160. HRESULT_FROM_WIN32(
  4161. GetLastError()));
  4162. }
  4163. else
  4164. WritePointArray(
  4165. CtrlName.data(),
  4166. PointArrayKeyName.data(),
  4167. lpImageInfo->rgptCalloutLine,
  4168. lpImageInfo->dwcValidPts,
  4169. m_VFileName.data());
  4170. break;
  4171. }
  4172. }
  4173. }
  4174. else
  4175. throw MAP_EXCEPTION(E_CORRUPT_IMAGE_DATA);
  4176. }
  4177. }
  4178. //Write new list of controls into the file
  4179. if(Controls.size())
  4180. WriteListOfStrings(FileDevName.data(),CONTROLS,Controls,pFileName);
  4181. }
  4182. HRESULT CDIMapObj::
  4183. WriteVendorFileI(
  4184. LPDIACTIONFORMAT lpDiActionFormat,
  4185. LPDIDEVICEIMAGEINFOHEADER lpdiDevImageInfoHeader,
  4186. DWORD dwFlags)
  4187. {
  4188. try
  4189. {
  4190. WRITEVENDORFILE_ENTERED;
  4191. TRACE(_T("Parameters:\n"));
  4192. DUMP(lpDiActionFormat);
  4193. DUMP(lpdiDevImageInfoHeader);
  4194. //DUMP(lpdiDevImageInfoHeader);
  4195. TRACE(_T("\n"));
  4196. //Check if initialized
  4197. if(!m_bInitialized)
  4198. {
  4199. TRACE(_T("Object not initialized\n"));
  4200. throw MAP_EXCEPTION(DIERR_NOTINITIALIZED);
  4201. }
  4202. //Check lpDiActionFormat structure
  4203. //Check structure sizes
  4204. if(lpDiActionFormat&&(lpDiActionFormat->dwSize!=
  4205. sizeof(*lpDiActionFormat)))
  4206. {
  4207. TRACE(_T("lpDiActionFormat->dwSize is wrong size\n"));
  4208. throw MAP_EXCEPTION(E_INVALIDARG);
  4209. }
  4210. if(lpDiActionFormat&&(lpDiActionFormat->dwActionSize!=
  4211. sizeof(*(lpDiActionFormat->rgoAction))))
  4212. {
  4213. TRACE(_T("lpDiActionFormat->dwActionSize is wrong size\n"));
  4214. throw MAP_EXCEPTION(E_INVALIDARG);
  4215. }
  4216. //Check how many actions, should be more than 0
  4217. if(lpDiActionFormat&&!lpDiActionFormat->dwNumActions)
  4218. {
  4219. TRACE(_T("lpDiActionFormat->dwNumActions is 0\n"));
  4220. throw MAP_EXCEPTION(E_INVALIDARG);
  4221. }
  4222. //Check ptr to the action array
  4223. if(lpDiActionFormat&&!lpDiActionFormat->rgoAction)
  4224. {
  4225. TRACE(_T("lpDiActionFormat->rgoAction is NULL\n"));
  4226. throw MAP_EXCEPTION(E_INVALIDARG);
  4227. }
  4228. //Check lpdiDevImageInfoHeader structure
  4229. //Check structure sizes
  4230. if(lpdiDevImageInfoHeader&&
  4231. (lpdiDevImageInfoHeader->dwSize!=
  4232. sizeof(*lpdiDevImageInfoHeader)))
  4233. {
  4234. TRACE(_T("lpdiDevImageInfoHeader->dwSize is wrong size\n"));
  4235. throw MAP_EXCEPTION(E_INVALIDARG);
  4236. }
  4237. if(lpdiDevImageInfoHeader&&
  4238. (lpdiDevImageInfoHeader->dwSizeImageInfo!=
  4239. sizeof(*(lpdiDevImageInfoHeader->lprgImageInfoArray))))
  4240. {
  4241. TRACE(_T("lpdiDevImageInfoHeader->dwSizeImageInfo is wrong size\n"));
  4242. throw MAP_EXCEPTION(E_INVALIDARG);
  4243. }
  4244. //Check how many images, should be more than 0
  4245. if(lpdiDevImageInfoHeader&&!lpdiDevImageInfoHeader->dwBufferSize)
  4246. {
  4247. TRACE(_T("lpdiDevImageInfoHeader->dwBufferSize is 0\n"));
  4248. throw MAP_EXCEPTION(E_INVALIDARG);
  4249. }
  4250. //Check how many images, should be more than 0
  4251. if(lpdiDevImageInfoHeader&&!lpdiDevImageInfoHeader->dwBufferUsed)
  4252. {
  4253. TRACE(_T("lpdiDevImageInfoHeader->dwBufferUsed is 0\n"));
  4254. throw MAP_EXCEPTION(E_INVALIDARG);
  4255. }
  4256. //Check ptr to the image array
  4257. if(lpdiDevImageInfoHeader&&
  4258. !lpdiDevImageInfoHeader->lprgImageInfoArray)
  4259. {
  4260. TRACE(_T("lpdiDevImageInfoHeader->lprgImageInfoArray is NULL\n"));
  4261. throw MAP_EXCEPTION(E_INVALIDARG);
  4262. }
  4263. SaveActionMapUV(
  4264. lpDiActionFormat,
  4265. m_bVLoaded,
  4266. m_VFileName.data(),
  4267. m_VFileDevName,
  4268. m_VCtrlData,
  4269. lpdiDevImageInfoHeader,
  4270. DIAH_HWDEFAULT,DIAH_HWAPP,false);
  4271. LoadFileData(m_VFileName.data(),m_DeviceName.data(),
  4272. m_dwThisVendorID,m_dwThisProductID,
  4273. m_VFileDevName,m_VCtrlData,m_bVLoaded,NULL,NULL);
  4274. TRACE(_T("hRes=0x%x\n"),S_OK);
  4275. return S_OK;
  4276. }
  4277. catch(MapException E)
  4278. {
  4279. return E.GetResult();
  4280. }
  4281. catch(exception)
  4282. {
  4283. USETRACER();
  4284. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  4285. return E_FAIL;
  4286. }
  4287. }
  4288. HRESULT Map_New(REFIID riid,LPVOID *ppvOut)
  4289. {
  4290. CDIMapObj *lpDIMapObj=NULL;
  4291. try
  4292. {
  4293. HRESULT hRes=S_OK;
  4294. *ppvOut=NULL;
  4295. lpDIMapObj=new CDIMapObj;
  4296. hRes=lpDIMapObj->QueryInterface(riid,ppvOut);
  4297. if(hRes!=S_OK)
  4298. throw MAP_EXCEPTION(hRes);
  4299. return S_OK;
  4300. }
  4301. catch(MapException E)
  4302. {
  4303. delete lpDIMapObj;
  4304. return E.GetResult();
  4305. }
  4306. catch(exception)
  4307. {
  4308. delete lpDIMapObj;
  4309. USETRACER();
  4310. TRACE(_T("Internal error, hRes=0x%x\n"),E_FAIL);
  4311. return E_FAIL;
  4312. }
  4313. }