ActiveXWrapper.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. #include "ActiveXWrapper.h"
  2. #include "Logger.h"
  3. #include <sstream>
  4. #include <iomanip>
  5. #include <algorithm>
  6. #include <comutil.h> // 添加这个包含以使用_com_util::ConvertBSTRToString
  7. // ActiveXEventSink 实现
  8. ActiveXEventSink::ActiveXEventSink(CommEventCallback callback)
  9. : ref_count_(1), callback_(callback)
  10. {
  11. }
  12. ActiveXEventSink::~ActiveXEventSink()
  13. {
  14. }
  15. // 修复QueryInterface函数 - 支持ICommModifyKitEvents接口
  16. STDMETHODIMP ActiveXEventSink::QueryInterface(REFIID riid, void **ppvObject)
  17. {
  18. if (!ppvObject)
  19. {
  20. return E_POINTER;
  21. }
  22. *ppvObject = nullptr;
  23. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch))
  24. {
  25. *ppvObject = static_cast<IDispatch *>(this);
  26. AddRef();
  27. return S_OK;
  28. }
  29. // 支持事件接口
  30. if (IsEqualIID(riid, IID_ICommModifyKitEvents))
  31. {
  32. *ppvObject = static_cast<IDispatch *>(this);
  33. AddRef();
  34. return S_OK;
  35. }
  36. return E_NOINTERFACE;
  37. }
  38. STDMETHODIMP_(ULONG)
  39. ActiveXEventSink::AddRef()
  40. {
  41. return InterlockedIncrement(&ref_count_);
  42. }
  43. STDMETHODIMP_(ULONG)
  44. ActiveXEventSink::Release()
  45. {
  46. ULONG count = InterlockedDecrement(&ref_count_);
  47. if (count == 0)
  48. {
  49. delete this;
  50. }
  51. return count;
  52. }
  53. STDMETHODIMP ActiveXEventSink::GetTypeInfoCount(UINT *pctinfo)
  54. {
  55. *pctinfo = 0;
  56. return S_OK;
  57. }
  58. STDMETHODIMP ActiveXEventSink::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
  59. {
  60. return E_NOTIMPL;
  61. }
  62. STDMETHODIMP ActiveXEventSink::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
  63. {
  64. return E_NOTIMPL;
  65. }
  66. STDMETHODIMP ActiveXEventSink::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
  67. DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
  68. {
  69. // 清空并重写函数,只处理6个参数的情况
  70. // 6个参数从DISPPARAMS *pDispParams中解析出来
  71. // 检查参数是否有效
  72. if (!pDispParams)
  73. {
  74. LOG_ERROR("Invalid DISPPARAMS");
  75. return E_INVALIDARG;
  76. }
  77. // 检查参数数量是否为6
  78. if (pDispParams->cArgs != 6)
  79. {
  80. LOG_ERROR("Expected 6 parameters, but got " + std::to_string(pDispParams->cArgs));
  81. return E_INVALIDARG;
  82. }
  83. try
  84. {
  85. // 从pDispParams中解析6个参数
  86. VARIANT *args = pDispParams->rgvarg;
  87. // 解析参数(注意:VARIANT参数是逆序的)
  88. // 参数6: lpData (char*)
  89. char *lpData = nullptr;
  90. if (args[0].vt == VT_BYREF || args[0].vt == (VT_ARRAY | VT_UI1))
  91. {
  92. // 处理数组数据
  93. if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
  94. {
  95. SAFEARRAY *data = args[0].parray;
  96. BYTE *data_ptr;
  97. SafeArrayAccessData(data, reinterpret_cast<void **>(&data_ptr));
  98. lpData = reinterpret_cast<char *>(data_ptr);
  99. }
  100. }
  101. else if (args[0].vt == VT_BSTR)
  102. {
  103. // 处理字符串数据
  104. lpData = _com_util::ConvertBSTRToString(args[0].bstrVal);
  105. }
  106. // 参数5: dwSize (DWORD)
  107. DWORD dwSize = 0;
  108. if (args[1].vt == VT_I4 || args[1].vt == VT_UI4)
  109. {
  110. dwSize = static_cast<DWORD>(args[1].lVal);
  111. }
  112. // 参数4: Irp (DWORD)
  113. DWORD Irp = 0;
  114. if (args[2].vt == VT_I4 || args[2].vt == VT_UI4)
  115. {
  116. Irp = static_cast<DWORD>(args[2].lVal);
  117. }
  118. // 参数3: ComNumber (DWORD)
  119. DWORD ComNumber = 0;
  120. if (args[3].vt == VT_I4 || args[3].vt == VT_UI4)
  121. {
  122. ComNumber = static_cast<DWORD>(args[3].lVal);
  123. }
  124. // 参数2: dTime (TDateTime/double)
  125. // TDateTime dTime = 0.0;
  126. // if (args[4].vt == VT_R8)
  127. //{
  128. // dTime = static_cast<TDateTime>(args[4].dblVal);
  129. //}
  130. // 参数1: Sequence (int)
  131. int Sequence = 0;
  132. if (args[5].vt == VT_I4)
  133. {
  134. Sequence = args[5].lVal;
  135. }
  136. // 打印6个参数值的日志
  137. LOG_DEBUG("ActiveX event parameters:");
  138. // LOG_DEBUG(" Sequence: " + std::to_string(Sequence));
  139. // LOG_DEBUG(" dTime: " + std::to_string(dTime));
  140. LOG_DEBUG(" ComNumber: " + std::to_string(ComNumber));
  141. LOG_DEBUG(" Irp: " + std::to_string(Irp));
  142. LOG_DEBUG(" dwSize: " + std::to_string(dwSize));
  143. LOG_DEBUG(" lpData: " + std::to_string(reinterpret_cast<uintptr_t>(lpData)));
  144. // 调用回调函数
  145. if (callback_)
  146. {
  147. try
  148. {
  149. // 创建CommEventData结构以传递给回调函数
  150. CommEventData event_data;
  151. event_data.event_type = static_cast<CommEventType>(Irp);
  152. event_data.port = static_cast<int>(ComNumber);
  153. if (lpData && dwSize > 0)
  154. {
  155. event_data.data.assign(reinterpret_cast<BYTE *>(lpData), reinterpret_cast<BYTE *>(lpData) + dwSize);
  156. }
  157. event_data.data_size = dwSize;
  158. callback_(event_data);
  159. LOG_DEBUG("ActiveX event processed successfully");
  160. }
  161. catch (const std::exception &e)
  162. {
  163. LOG_ERROR("Error in ActiveX event callback: " + std::string(e.what()));
  164. // 释放分配的内存
  165. if (args[0].vt == VT_BSTR && lpData)
  166. {
  167. delete[] lpData;
  168. }
  169. else if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
  170. {
  171. SafeArrayUnaccessData(args[0].parray);
  172. }
  173. return E_FAIL;
  174. }
  175. }
  176. // 释放分配的内存
  177. if (args[0].vt == VT_BSTR && lpData)
  178. {
  179. delete[] lpData;
  180. }
  181. else if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
  182. {
  183. SafeArrayUnaccessData(args[0].parray);
  184. }
  185. }
  186. catch (const std::exception &e)
  187. {
  188. LOG_ERROR("Error processing ActiveX event: " + std::string(e.what()));
  189. return E_FAIL;
  190. }
  191. return S_OK;
  192. }
  193. // ActiveXWrapper 实现
  194. ActiveXWrapper::ActiveXWrapper()
  195. : activex_control_(nullptr), connection_point_(nullptr), connection_cookie_(0),
  196. event_sink_(nullptr), event_connected_(false)
  197. {
  198. }
  199. ActiveXWrapper::~ActiveXWrapper()
  200. {
  201. Cleanup();
  202. }
  203. bool ActiveXWrapper::Initialize()
  204. {
  205. if (initialized_)
  206. {
  207. return true;
  208. }
  209. // 初始化COM
  210. HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  211. if (FAILED(hr) && hr != S_FALSE)
  212. {
  213. LOG_ERROR("Failed to initialize COM, HRESULT: " + std::to_string(hr));
  214. return false;
  215. }
  216. // 使用正确的CLSID创建ActiveX控件
  217. hr = CoCreateInstance(CLSID_CommModifyKit, nullptr, CLSCTX_INPROC_SERVER,
  218. IID_IDispatch, reinterpret_cast<void **>(&activex_control_));
  219. if (FAILED(hr))
  220. {
  221. LOG_ERROR("Failed to create ActiveX control, HRESULT: " + std::to_string(hr));
  222. // 尝试使用ProgID创建
  223. CLSID clsid;
  224. hr = CLSIDFromProgID(L"PCommMKit.CommModifyKit", &clsid);
  225. if (SUCCEEDED(hr))
  226. {
  227. hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER,
  228. IID_IDispatch, reinterpret_cast<void **>(&activex_control_));
  229. }
  230. if (FAILED(hr))
  231. {
  232. LOG_ERROR("Failed to create ActiveX control using ProgID, HRESULT: " + std::to_string(hr));
  233. return false;
  234. }
  235. }
  236. if (!InitializeMethodIds())
  237. {
  238. LOG_ERROR("Failed to initialize method IDs");
  239. return false;
  240. }
  241. // 连接事件
  242. if (!ConnectEvents())
  243. {
  244. LOG_ERROR("Failed to connect events");
  245. return false;
  246. }
  247. initialized_ = true;
  248. LOG_INFO("ActiveX control initialized successfully");
  249. return true;
  250. }
  251. bool ActiveXWrapper::ConnectEvents()
  252. {
  253. if (!activex_control_)
  254. {
  255. return false;
  256. }
  257. // 获取连接点容器
  258. IConnectionPointContainer *cpc = nullptr;
  259. HRESULT hr = activex_control_->QueryInterface(IID_IConnectionPointContainer,
  260. reinterpret_cast<void **>(&cpc));
  261. if (FAILED(hr))
  262. {
  263. LOG_ERROR("Failed to get connection point container, HRESULT: " + std::to_string(hr));
  264. return false;
  265. }
  266. // 首先尝试直接查找事件接口的连接点
  267. hr = cpc->FindConnectionPoint(IID_ICommModifyKitEvents, &connection_point_);
  268. if (SUCCEEDED(hr))
  269. {
  270. LOG_INFO("Found connection point for ICommModifyKitEvents directly");
  271. }
  272. else
  273. {
  274. LOG_WARNING("Direct connection point lookup failed, HRESULT: " + std::to_string(hr) + ", trying enumeration");
  275. // 如果直接查找失败,枚举所有连接点
  276. IEnumConnectionPoints *enum_cp = nullptr;
  277. hr = cpc->EnumConnectionPoints(&enum_cp);
  278. if (SUCCEEDED(hr))
  279. {
  280. IConnectionPoint *cp = nullptr;
  281. ULONG fetched = 0;
  282. // 枚举所有连接点,查找正确的事件接口
  283. while (enum_cp->Next(1, &cp, &fetched) == S_OK && fetched > 0)
  284. {
  285. IID iid;
  286. if (SUCCEEDED(cp->GetConnectionInterface(&iid)))
  287. {
  288. // 记录找到的接口ID用于调试
  289. char iid_str[64];
  290. sprintf_s(iid_str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  291. iid.Data1, iid.Data2, iid.Data3,
  292. iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3],
  293. iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]);
  294. LOG_DEBUG("Found connection point with IID: " + std::string(iid_str));
  295. // 检查是否是我们需要的事件接口
  296. if (IsEqualIID(iid, IID_ICommModifyKitEvents))
  297. {
  298. connection_point_ = cp;
  299. connection_point_->AddRef();
  300. cp->Release(); // 释放枚举得到的引用
  301. LOG_INFO("Found ICommModifyKitEvents connection point through enumeration");
  302. break;
  303. }
  304. }
  305. cp->Release();
  306. }
  307. enum_cp->Release();
  308. }
  309. }
  310. cpc->Release();
  311. if (!connection_point_)
  312. {
  313. LOG_ERROR("Failed to find any connection point for ICommModifyKitEvents");
  314. return false;
  315. }
  316. // 创建事件接收器
  317. event_sink_ = new ActiveXEventSink([this](const CommEventData &event_data)
  318. {
  319. // 直接使用通用事件数据调用通用回调
  320. if (event_callback_) {
  321. event_callback_(event_data);
  322. } });
  323. // 连接事件接收器
  324. hr = connection_point_->Advise(event_sink_, &connection_cookie_);
  325. if (FAILED(hr))
  326. {
  327. LOG_ERROR("Failed to advise connection point, HRESULT: " + std::to_string(hr));
  328. event_sink_->Release();
  329. event_sink_ = nullptr;
  330. return false;
  331. }
  332. event_connected_ = true;
  333. LOG_INFO("ActiveX events connected successfully, cookie: " + std::to_string(connection_cookie_));
  334. return true;
  335. }
  336. void ActiveXWrapper::DisconnectEvents()
  337. {
  338. if (event_connected_ && connection_point_ && connection_cookie_ != 0)
  339. {
  340. connection_point_->Unadvise(connection_cookie_);
  341. connection_cookie_ = 0;
  342. event_connected_ = false;
  343. }
  344. if (connection_point_)
  345. {
  346. connection_point_->Release();
  347. connection_point_ = nullptr;
  348. }
  349. if (event_sink_)
  350. {
  351. event_sink_->Release();
  352. event_sink_ = nullptr;
  353. }
  354. }
  355. bool ActiveXWrapper::InitializeMethodIds()
  356. {
  357. if (!activex_control_)
  358. {
  359. return false;
  360. }
  361. // 获取方法的DISPID
  362. LPOLESTR method_names[] = {
  363. const_cast<LPOLESTR>(L"InitMonitor"),
  364. const_cast<LPOLESTR>(L"MonitorPort"),
  365. const_cast<LPOLESTR>(L"StopPort"),
  366. const_cast<LPOLESTR>(L"ReadData"),
  367. const_cast<LPOLESTR>(L"WriteData"),
  368. const_cast<LPOLESTR>(L"FreeMonitor"),
  369. const_cast<LPOLESTR>(L"GetLastError")};
  370. DISPID *method_ids[] = {
  371. &init_monitor_id_,
  372. &monitor_port_id_,
  373. &stop_port_id_,
  374. &read_data_id_,
  375. &write_data_id_,
  376. &free_monitor_id_,
  377. &get_last_error_id_};
  378. for (int i = 0; i < 7; i++)
  379. {
  380. HRESULT hr = activex_control_->GetIDsOfNames(IID_NULL, &method_names[i], 1,
  381. LOCALE_USER_DEFAULT, method_ids[i]);
  382. if (FAILED(hr))
  383. {
  384. LOG_ERROR("Failed to get method ID for method");
  385. return false;
  386. }
  387. }
  388. return true;
  389. }
  390. HRESULT ActiveXWrapper::InvokeMethod(DISPID dispid, VARIANT *params, int param_count, VARIANT *result)
  391. {
  392. if (!activex_control_)
  393. {
  394. return E_FAIL;
  395. }
  396. DISPPARAMS disp_params = {params, nullptr, param_count, 0};
  397. EXCEPINFO excep_info = {0};
  398. UINT arg_err = 0;
  399. return activex_control_->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
  400. DISPATCH_METHOD, &disp_params, result,
  401. &excep_info, &arg_err);
  402. }
  403. bool ActiveXWrapper::InitMonitor(const std::string &key)
  404. {
  405. if (!initialized_)
  406. {
  407. LOG_ERROR("ActiveX control not initialized");
  408. return false;
  409. }
  410. std::lock_guard<std::mutex> lock(mutex_);
  411. if (callback_initialized_)
  412. {
  413. return true;
  414. }
  415. // 转换字符串参数
  416. _bstr_t bstr_key(key.c_str());
  417. VARIANT param;
  418. VariantInit(&param);
  419. param.vt = VT_BSTR;
  420. param.bstrVal = bstr_key;
  421. VARIANT result;
  422. VariantInit(&result);
  423. HRESULT hr = InvokeMethod(init_monitor_id_, &param, 1, &result);
  424. bool success = false;
  425. if (SUCCEEDED(hr) && result.vt == VT_BOOL)
  426. {
  427. success = result.boolVal != VARIANT_FALSE;
  428. callback_initialized_ = success;
  429. }
  430. VariantClear(&param);
  431. VariantClear(&result);
  432. if (success)
  433. {
  434. LOG_INFO("InitMonitor succeeded");
  435. }
  436. else
  437. {
  438. LOG_ERROR("InitMonitor failed, error code: " + std::to_string(GetLastError()));
  439. }
  440. return success;
  441. }
  442. bool ActiveXWrapper::MonitorPort(int port)
  443. {
  444. if (!initialized_ || !callback_initialized_)
  445. {
  446. LOG_ERROR("ActiveX control not properly initialized");
  447. return false;
  448. }
  449. std::lock_guard<std::mutex> lock(mutex_);
  450. VARIANT param;
  451. VariantInit(&param);
  452. param.vt = VT_I4;
  453. param.lVal = port;
  454. VARIANT result;
  455. VariantInit(&result);
  456. HRESULT hr = InvokeMethod(monitor_port_id_, &param, 1, &result);
  457. bool success = false;
  458. if (SUCCEEDED(hr) && result.vt == VT_BOOL)
  459. {
  460. success = result.boolVal != VARIANT_FALSE;
  461. if (success)
  462. {
  463. monitored_ports_[port] = true;
  464. }
  465. }
  466. VariantClear(&param);
  467. VariantClear(&result);
  468. if (success)
  469. {
  470. LOG_INFO("MonitorPort succeeded for port " + std::to_string(port));
  471. }
  472. else
  473. {
  474. LOG_ERROR("MonitorPort failed for port " + std::to_string(port) + ", error code: " + std::to_string(GetLastError()));
  475. }
  476. return success;
  477. }
  478. bool ActiveXWrapper::StopPort(int port)
  479. {
  480. if (!initialized_)
  481. {
  482. LOG_ERROR("ActiveX control not initialized");
  483. return false;
  484. }
  485. std::lock_guard<std::mutex> lock(mutex_);
  486. VARIANT param;
  487. VariantInit(&param);
  488. param.vt = VT_I4;
  489. param.lVal = port;
  490. VARIANT result;
  491. VariantInit(&result);
  492. HRESULT hr = InvokeMethod(stop_port_id_, &param, 1, &result);
  493. bool success = false;
  494. if (SUCCEEDED(hr) && result.vt == VT_BOOL)
  495. {
  496. success = result.boolVal != VARIANT_FALSE;
  497. if (success)
  498. {
  499. monitored_ports_[port] = false;
  500. }
  501. }
  502. VariantClear(&param);
  503. VariantClear(&result);
  504. if (success)
  505. {
  506. LOG_INFO("StopPort succeeded for port " + std::to_string(port));
  507. }
  508. else
  509. {
  510. LOG_ERROR("StopPort failed for port " + std::to_string(port) + ", error code: " + std::to_string(GetLastError()));
  511. }
  512. return success;
  513. }
  514. // 修复ReadData函数 - 移除SafeArrayDestroy双重释放
  515. bool ActiveXWrapper::ReadData(int port, const std::string &hex_data)
  516. {
  517. if (!initialized_)
  518. {
  519. LOG_ERROR("ActiveX control not initialized");
  520. return false;
  521. }
  522. std::lock_guard<std::mutex> lock(mutex_);
  523. // 将十六进制字符串转换为字节数组
  524. std::vector<BYTE> bytes = Utils::ConvertHexStringToBytes(hex_data);
  525. // 使用辅助函数创建SafeArray
  526. SAFEARRAY *sa = CreateSafeArrayFromBytes(bytes);
  527. if (!sa)
  528. {
  529. LOG_ERROR("Failed to create SafeArray");
  530. return false;
  531. }
  532. // 准备参数
  533. VARIANT params[3];
  534. VariantInit(&params[0]);
  535. VariantInit(&params[1]);
  536. VariantInit(&params[2]);
  537. params[0].vt = VT_I4;
  538. params[0].lVal = port;
  539. params[1].vt = VT_ARRAY | VT_UI1;
  540. params[1].parray = sa;
  541. params[2].vt = VT_I4;
  542. params[2].lVal = static_cast<LONG>(bytes.size());
  543. VARIANT result;
  544. VariantInit(&result);
  545. // 调用ActiveX控件的ReadData方法
  546. HRESULT hr = InvokeMethod(read_data_id_, params, 3, &result);
  547. bool success = SUCCEEDED(hr);
  548. if (success && result.vt == VT_BOOL)
  549. {
  550. success = result.boolVal != VARIANT_FALSE;
  551. }
  552. // 只清理VARIANT,VariantClear会自动处理SafeArray
  553. for (int i = 0; i < 3; i++)
  554. {
  555. VariantClear(&params[i]);
  556. }
  557. VariantClear(&result);
  558. // 不要调用SafeArrayDestroy(sa) - 这会导致双重释放崩溃
  559. if (success)
  560. {
  561. LOG_DEBUG("ReadData succeeded for port " + std::to_string(port) + ", data: " + hex_data);
  562. }
  563. else
  564. {
  565. LOG_ERROR("ReadData failed for port " + std::to_string(port) + ", HRESULT: " + std::to_string(hr));
  566. }
  567. return success;
  568. }
  569. // 修复WriteData函数 - 移除SafeArrayDestroy双重释放
  570. bool ActiveXWrapper::WriteData(int port, const std::string &hex_data)
  571. {
  572. if (!initialized_)
  573. {
  574. LOG_ERROR("ActiveX control not initialized");
  575. return false;
  576. }
  577. std::lock_guard<std::mutex> lock(mutex_);
  578. // 将十六进制字符串转换为字节数组
  579. std::vector<BYTE> bytes = Utils::ConvertHexStringToBytes(hex_data);
  580. // 使用辅助函数创建SafeArray
  581. SAFEARRAY *sa = CreateSafeArrayFromBytes(bytes);
  582. if (!sa)
  583. {
  584. LOG_ERROR("Failed to create SafeArray");
  585. return false;
  586. }
  587. // 准备参数
  588. VARIANT params[3];
  589. VariantInit(&params[0]);
  590. VariantInit(&params[1]);
  591. VariantInit(&params[2]);
  592. params[0].vt = VT_I4;
  593. params[0].lVal = port;
  594. params[1].vt = VT_ARRAY | VT_UI1;
  595. params[1].parray = sa;
  596. params[2].vt = VT_I4;
  597. params[2].lVal = static_cast<LONG>(bytes.size());
  598. VARIANT result;
  599. VariantInit(&result);
  600. // 调用ActiveX控件的WriteData方法
  601. HRESULT hr = InvokeMethod(write_data_id_, params, 3, &result);
  602. bool success = SUCCEEDED(hr);
  603. if (success && result.vt == VT_BOOL)
  604. {
  605. success = result.boolVal != VARIANT_FALSE;
  606. }
  607. // 只清理VARIANT,VariantClear会自动处理SafeArray
  608. for (int i = 0; i < 3; i++)
  609. {
  610. VariantClear(&params[i]);
  611. }
  612. VariantClear(&result);
  613. // 不要调用SafeArrayDestroy(sa) - 这会导致双重释放崩溃
  614. if (success)
  615. {
  616. LOG_DEBUG("WriteData succeeded for port " + std::to_string(port) + ", data: " + hex_data);
  617. }
  618. else
  619. {
  620. LOG_ERROR("WriteData failed for port " + std::to_string(port) + ", HRESULT: " + std::to_string(hr));
  621. }
  622. return success;
  623. }
  624. bool ActiveXWrapper::FreeMonitor()
  625. {
  626. if (!initialized_)
  627. {
  628. return true;
  629. }
  630. std::lock_guard<std::mutex> lock(mutex_);
  631. VARIANT result;
  632. VariantInit(&result);
  633. HRESULT hr = InvokeMethod(free_monitor_id_, nullptr, 0, &result);
  634. bool success = SUCCEEDED(hr);
  635. if (success)
  636. {
  637. callback_initialized_ = false;
  638. monitored_ports_.clear();
  639. LOG_INFO("FreeMonitor succeeded");
  640. }
  641. else
  642. {
  643. LOG_ERROR("FreeMonitor failed");
  644. }
  645. VariantClear(&result);
  646. return success;
  647. }
  648. int ActiveXWrapper::GetLastError()
  649. {
  650. if (!initialized_)
  651. {
  652. return -1;
  653. }
  654. VARIANT result;
  655. VariantInit(&result);
  656. HRESULT hr = InvokeMethod(get_last_error_id_, nullptr, 0, &result);
  657. int error_code = -1;
  658. if (SUCCEEDED(hr) && result.vt == VT_I4)
  659. {
  660. error_code = result.lVal;
  661. }
  662. VariantClear(&result);
  663. return error_code;
  664. }
  665. void ActiveXWrapper::SetEventCallback(CommEventCallback callback)
  666. {
  667. // 调用基类的实现来设置回调
  668. CommWrapperBase::SetEventCallback(callback);
  669. // 设置ActiveX事件回调,将ActiveX事件数据转换为通用事件数据后再调用通用回调
  670. event_callback_ = [this](const CommEventData &event_data)
  671. {
  672. // 调用通用回调
  673. if (event_callback_)
  674. {
  675. event_callback_(event_data);
  676. }
  677. };
  678. }
  679. std::string ActiveXWrapper::GetErrorMessage(int error_code)
  680. {
  681. switch (error_code)
  682. {
  683. case -241:
  684. return "安装驱动失败";
  685. case -243:
  686. return "其他错误";
  687. case -244:
  688. return "驱动文件";
  689. case -255:
  690. return "绑定串口失败";
  691. case -254:
  692. return "第一次启动安装,必须以管理员权限运行";
  693. case -253:
  694. return "启动驱动服务失败";
  695. case -252:
  696. return "请检查Key是否有效";
  697. case -1:
  698. return "无效操作";
  699. case 0:
  700. return "成功";
  701. case 1:
  702. return "串口打开失败";
  703. case 2:
  704. return "串口配置失败";
  705. case 3:
  706. return "串口读取失败";
  707. case 4:
  708. return "串口写入失败";
  709. case 5:
  710. return "串口关闭失败";
  711. default:
  712. return "未知错误";
  713. }
  714. }
  715. bool ActiveXWrapper::IsPortMonitored(int port)
  716. {
  717. std::lock_guard<std::mutex> lock(mutex_);
  718. auto it = monitored_ports_.find(port);
  719. return it != monitored_ports_.end() && it->second;
  720. }
  721. SAFEARRAY *ActiveXWrapper::CreateSafeArrayFromBytes(const std::vector<BYTE> &bytes)
  722. {
  723. // 创建SafeArray来传递字节数组
  724. SAFEARRAYBOUND bounds[1];
  725. bounds[0].lLbound = 0;
  726. bounds[0].cElements = static_cast<ULONG>(bytes.size());
  727. SAFEARRAY *sa = SafeArrayCreate(VT_UI1, 1, bounds);
  728. if (!sa)
  729. {
  730. LOG_ERROR("Failed to create SafeArray");
  731. return nullptr;
  732. }
  733. // 将数据复制到SafeArray
  734. BYTE *data_ptr;
  735. HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void **>(&data_ptr));
  736. if (SUCCEEDED(hr))
  737. {
  738. memcpy(data_ptr, bytes.data(), bytes.size());
  739. SafeArrayUnaccessData(sa);
  740. }
  741. else
  742. {
  743. LOG_ERROR("Failed to access SafeArray data");
  744. SafeArrayDestroy(sa);
  745. return nullptr;
  746. }
  747. return sa;
  748. }
  749. void ActiveXWrapper::Cleanup()
  750. {
  751. if (initialized_)
  752. {
  753. FreeMonitor();
  754. DisconnectEvents();
  755. if (activex_control_)
  756. {
  757. activex_control_->Release();
  758. activex_control_ = nullptr;
  759. }
  760. // 释放COM
  761. CoUninitialize();
  762. initialized_ = false;
  763. LOG_INFO("ActiveX control cleaned up");
  764. }
  765. }