Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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