Global.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. #include "stdafx.h"
  2. #include "Global.h"
  3. #include <tchar.h>
  4. #include <direct.h>
  5. #include <SetupAPI.h>
  6. #include <InitGuid.h>
  7. #include <WinIoCtl.h>
  8. #pragma comment(lib, "SetupAPI.lib")
  9. //////////////////////////////////////////////////////////////////////////
  10. // dll相关;
  11. HMODULE g_hdll = NULL;
  12. irc_IsAppRunning g_IsAppRunning = NULL;
  13. irc_StartIRApp g_StartIRApp = NULL;
  14. irc_CloseApp g_CloseApp = NULL;
  15. irc_Connect g_Connect = NULL;
  16. irc_DisConnect g_DisConnect = NULL;
  17. irc_loadSignalDataSet g_loadSignalDataSet = NULL;
  18. irc_getDeviceNames g_getDeviceNames = NULL;
  19. irc_getSignalsName g_getSignalsName = NULL;
  20. irc_sendSignal g_sendSignal = NULL;
  21. irc_sendSignals g_sendSignals = NULL;
  22. irc_sendRepeatsSignal g_sendRepeatsSignal = NULL;
  23. int g_nIRControl = 0;
  24. BOOL LoadLogLibarary()
  25. {
  26. if (g_hdll == NULL)
  27. {
  28. g_hdll = (HMODULE)LoadLibrary(_T("IRControl.dll"));
  29. if (!g_hdll)
  30. return FALSE;
  31. }
  32. g_sendRepeatsSignal = (irc_sendRepeatsSignal)GetProcAddress(g_hdll, "sendRepeatsSignal");
  33. if (!g_sendRepeatsSignal)
  34. {
  35. FreeLogLibarary();
  36. return FALSE;
  37. }
  38. g_sendSignals = (irc_sendSignals)GetProcAddress(g_hdll, "sendSignals");
  39. if (!g_sendSignals)
  40. {
  41. FreeLogLibarary();
  42. return FALSE;
  43. }
  44. g_sendSignal = (irc_sendSignal)GetProcAddress(g_hdll, "sendSignal");
  45. if (!g_sendSignal)
  46. {
  47. FreeLogLibarary();
  48. return FALSE;
  49. }
  50. g_loadSignalDataSet = (irc_loadSignalDataSet)GetProcAddress(g_hdll, "loadSignalDataSet");
  51. if (!g_loadSignalDataSet)
  52. {
  53. FreeLogLibarary();
  54. return FALSE;
  55. }
  56. g_IsAppRunning = (irc_IsAppRunning)GetProcAddress(g_hdll, "IsAppRunning");
  57. if (!g_IsAppRunning)
  58. {
  59. FreeLogLibarary();
  60. return FALSE;
  61. }
  62. g_StartIRApp = (irc_StartIRApp)GetProcAddress(g_hdll, "StartIRApp");
  63. if (!g_StartIRApp)
  64. {
  65. FreeLogLibarary();
  66. return FALSE;
  67. }
  68. g_CloseApp = (irc_CloseApp)GetProcAddress(g_hdll, "CloseApp");
  69. if (!g_CloseApp)
  70. {
  71. FreeLogLibarary();
  72. return FALSE;
  73. }
  74. g_getDeviceNames = (irc_getDeviceNames)GetProcAddress(g_hdll, "getDeviceNames");
  75. if (!g_getDeviceNames)
  76. {
  77. FreeLogLibarary();
  78. return FALSE;
  79. }
  80. g_Connect = (irc_Connect)GetProcAddress(g_hdll, "Connect");
  81. if (!g_Connect)
  82. {
  83. FreeLogLibarary();
  84. return FALSE;
  85. }
  86. g_getSignalsName = (irc_getSignalsName)GetProcAddress(g_hdll, "getSignalsName");
  87. if (!g_getSignalsName)
  88. {
  89. FreeLogLibarary();
  90. return FALSE;
  91. }
  92. g_DisConnect = (irc_DisConnect)GetProcAddress(g_hdll, "DisConnect");
  93. if (!g_DisConnect)
  94. {
  95. FreeLogLibarary();
  96. return FALSE;
  97. }
  98. // 导出全局变量;
  99. g_nIRControl = *(int*)GetProcAddress(g_hdll, "nIRControl");
  100. if (!g_CloseApp)
  101. {
  102. FreeLogLibarary();
  103. return FALSE;
  104. }
  105. return TRUE;
  106. }
  107. void FreeLogLibarary()
  108. {
  109. if (g_hdll)
  110. {
  111. if (FreeLibrary(g_hdll))
  112. {
  113. g_hdll = NULL;
  114. g_IsAppRunning = NULL;
  115. g_StartIRApp = NULL;
  116. g_CloseApp = NULL;
  117. g_Connect = NULL;
  118. g_getDeviceNames = NULL;
  119. g_getSignalsName = NULL;
  120. g_loadSignalDataSet = NULL;
  121. g_sendSignal = NULL;
  122. g_sendSignals = NULL;
  123. g_sendRepeatsSignal = NULL;
  124. g_DisConnect = NULL;
  125. }
  126. }
  127. }
  128. //////////////////////////////////////////////////////////////////////////
  129. namespace Global
  130. {
  131. //////////////////////////////////////////////////////////////////////////
  132. // 全局变量;
  133. TCHAR g_szCurModuleDir[MAX_PATH] = { 0 };
  134. TCHAR g_szCurModulePath[MAX_PATH] = { 0 };
  135. TCHAR g_szFna[MAX_PATH] = { 0 };
  136. TCHAR g_szConfig[MAX_PATH] = { 0 };
  137. STConfig g_Config;
  138. //////////////////////////////////////////////////////////////////////////
  139. // 全局函数;
  140. /************************************************************************/
  141. /* 函数:WriteTextLog[7/28/2009 Jeff];
  142. /* 描述:写文本日志;
  143. /* 参数:;
  144. /* [IN] :;
  145. /* 返回:void;
  146. /* 注意:;
  147. /* 示例:;
  148. /*
  149. /* 修改:;
  150. /* 日期:;
  151. /* 内容:;
  152. /************************************************************************/
  153. void WriteTextLog(const TCHAR* format, ...)
  154. {
  155. // 解析出日志路径;
  156. TCHAR szlogpath[MAX_PATH] = { 0 };
  157. _stprintf_s(szlogpath, _T("%s%s.txt"), g_szCurModuleDir, g_szFna);
  158. // 打开或创建文件;
  159. FILE* fp = NULL;
  160. //if (_taccess(szlogpath, 0) != -1)
  161. #ifndef UNICODE
  162. if (_access(szlogpath, 0) != -1)
  163. #else
  164. if (_taccess(szlogpath, 0) != -1)
  165. #endif
  166. {// 存在;
  167. if (0 == _tfopen_s(&fp, szlogpath, _T("a+")))
  168. // 移动到末尾;
  169. fseek(fp, 0, SEEK_END);
  170. }
  171. else
  172. {// 不存在;
  173. _tfopen_s(&fp, szlogpath, _T("w+"));
  174. }
  175. if (fp == NULL)
  176. return;
  177. // 格式化前设置语言区域;
  178. TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
  179. _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
  180. // 格式化日志内容;
  181. va_list args = NULL;
  182. int len = 0;
  183. TCHAR* buffer = NULL;
  184. va_start(args, format);
  185. // _vscprintf doesn't count. terminating '\0'
  186. len = _vsctprintf(format, args) + 1;
  187. buffer = (TCHAR*)malloc(len * sizeof(TCHAR));
  188. _vstprintf_s(buffer, len, format, args);
  189. // 将日志内容输入到文件中;
  190. // 获取今年年份;
  191. __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
  192. struct tm gmtm = { 0 };
  193. localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
  194. _ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year + 1990, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, buffer);
  195. // 关闭文件,释放资源并设置回原语言区域;
  196. free(buffer);
  197. fclose(fp);
  198. _tsetlocale(LC_CTYPE, old_locale);
  199. free(old_locale);//还原区域设定;
  200. }
  201. int ReadReg(char* path, char* key, char* value)
  202. {
  203. HKEY hKey;
  204. int ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_QUERY_VALUE, &hKey);
  205. if (ret != ERROR_SUCCESS)
  206. {
  207. return 1;
  208. }
  209. //读取KEY
  210. DWORD dwType = REG_SZ; //数据类型
  211. DWORD cbData = 256;
  212. ret = RegQueryValueEx(hKey, key, NULL, &dwType, (LPBYTE)value, &cbData);
  213. if (ret != ERROR_SUCCESS)
  214. {
  215. RegCloseKey(hKey);
  216. return 1;
  217. }
  218. RegCloseKey(hKey);
  219. return 0;
  220. }
  221. // 读取配置文件-预留;
  222. void GetConfig()
  223. {
  224. TCHAR szConfigpath[MAX_PATH] = { 0 };
  225. _stprintf_s(szConfigpath, _T("%sConfig.ini"), Global::g_szCurModuleDir);
  226. _tcscpy_s(g_szConfig, szConfigpath);
  227. TCHAR szValue[MAX_PATH] = { 0 };
  228. // 读取配置内容;
  229. g_Config.bGenerics = GetPrivateProfileInt(_T("ir-device"), _T("generics"), 0, szConfigpath);
  230. GetPrivateProfileString(_T("ir-device"), _T("redratpath"), NULL, szValue, MAX_PATH, szConfigpath);
  231. g_Config.redratpath = szValue;
  232. memset(szValue, 0, MAX_PATH);
  233. GetPrivateProfileString(_T("ir-device"), _T("signal"), NULL, szValue, MAX_PATH, szConfigpath);
  234. g_Config.signaldir = szValue;
  235. memset(szValue, 0, MAX_PATH);
  236. GetPrivateProfileString(_T("ir-device"), _T("use-signal"), NULL, szValue, MAX_PATH, szConfigpath);
  237. g_Config.use_signal = szValue;
  238. memset(szValue, 0, MAX_PATH);
  239. }
  240. BOOL GetOrientation(IN Image* pImg)
  241. {
  242. if (pImg == NULL) return FALSE;
  243. UINT totalBufferSize;
  244. UINT numProperties;
  245. pImg->GetPropertySize(&totalBufferSize, &numProperties);
  246. // Allocate the buffer that will receive the property items.
  247. PropertyItem* pAllItems = (PropertyItem*)malloc(totalBufferSize);
  248. // Fill the buffer.
  249. pImg->GetAllPropertyItems(totalBufferSize, numProperties, pAllItems);
  250. // Print the id data member of each property item.
  251. for (UINT j = 0; j < numProperties; ++j)
  252. {
  253. if (PropertyTagOrientation == pAllItems[j].id)
  254. {
  255. short* ptrLong = (short*)(pAllItems[j].value);
  256. int ret = (int)*ptrLong;
  257. free(pAllItems);
  258. return ret;
  259. }
  260. }
  261. free(pAllItems);
  262. return TRUE;
  263. }
  264. /************************************************************************/
  265. /*
  266. 函数:GetEncoderClsid
  267. 描述:获取GDI+支持的图像格式编码器种类,以及所有种类编码器信息;
  268. 参数:
  269. IN: format 要获取的图像格式;
  270. OUT: pClsid 返回符合条件的图像编码器信息;
  271. 返回:成功返回编码器索引,否则返回-1;
  272. */
  273. /************************************************************************/
  274. int GetEncoderClsid(IN CONST WCHAR* format, OUT CLSID* pClsid)
  275. {
  276. // GDI+支持的图像编码器数量;
  277. UINT numEncoders = 0;
  278. // GDI+所有图像格式编码器详细信息所需要的空间大小;
  279. UINT nSize = 0;
  280. ImageCodecInfo* pImageCodecInfo = NULL;
  281. // 2.获取GDI+支持的所有图像格式编码器详细信息所需要的空间大小;
  282. GetImageEncodersSize(&numEncoders, &nSize);
  283. if (nSize == 0)
  284. return -1;
  285. //3.为ImageCodecInfo数组分配足额空间;
  286. pImageCodecInfo = (ImageCodecInfo*)(malloc(nSize));
  287. if (pImageCodecInfo == NULL)
  288. return -1;
  289. //4.获取所有的图像编码器信息;
  290. GetImageEncoders(numEncoders, nSize, pImageCodecInfo);
  291. //5.查找符合的图像编码器的Clsid;
  292. for (UINT i = 0; i < numEncoders; ++i)
  293. {
  294. if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0)
  295. {
  296. *pClsid = pImageCodecInfo[i].Clsid;
  297. free(pImageCodecInfo);
  298. return i; // Success
  299. }
  300. }
  301. //6.释放步骤3分配的内存;
  302. free(pImageCodecInfo);
  303. return -1;
  304. }
  305. BOOL LoadImgFromFile(IN Image** pImg, LPCTSTR lpPath)
  306. {
  307. if (!PathFileExists(lpPath))
  308. return FALSE;
  309. if (*pImg)
  310. delete* pImg;
  311. *pImg = NULL;
  312. #ifdef UNICODE
  313. * pImg = Image::FromFile(lpPath);
  314. #else
  315. BSTR strtmp = _bstr_t(lpPath);
  316. *pImg = Image::FromFile(strtmp, TRUE);
  317. SysFreeString(strtmp);
  318. #endif
  319. return (*pImg ? TRUE : FALSE);
  320. }
  321. BOOL LoadImgFromBuffer(IN Image** pImg, IN BYTE* pBuffer, IN CONST INT& nBufLen)
  322. {
  323. if (pBuffer == NULL)
  324. return FALSE;
  325. if (*pImg)
  326. delete* pImg;
  327. *pImg = NULL;
  328. HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, nBufLen);
  329. if (hMemery == NULL)
  330. return FALSE;
  331. BYTE* pMem = (BYTE*)GlobalLock(hMemery);
  332. memcpy(pMem, pBuffer, nBufLen);
  333. IStream* pstream = NULL;
  334. CreateStreamOnHGlobal(hMemery, TRUE, &pstream);
  335. *pImg = Image::FromStream(pstream);
  336. GlobalUnlock(hMemery);
  337. pstream->Release();
  338. return (*pImg ? TRUE : FALSE);
  339. }
  340. // 先以只读方式从文件中读取二进制流出来,可以做到不独占文件;
  341. BOOL LoadImgFromBuffer(IN Image** pImg, LPCTSTR lpPath)
  342. {
  343. if (!PathFileExists(lpPath))
  344. return FALSE;
  345. if (*pImg)
  346. delete* pImg;
  347. *pImg = NULL;
  348. return LoadImgFromFile(pImg, lpPath);
  349. CFile fp;
  350. CFileException e;
  351. BOOL bRet = FALSE;
  352. if (fp.Open(lpPath, CFile::modeRead, &e))
  353. {
  354. DWORD dwLength = (DWORD)fp.GetLength();
  355. BYTE* pData = new BYTE[dwLength];
  356. fp.Read(pData, dwLength);
  357. fp.Close();
  358. bRet = LoadImgFromBuffer(pImg, pData, dwLength);
  359. if (pData)
  360. delete[]pData;
  361. }
  362. return bRet;
  363. }
  364. /************************************************************************/
  365. /* 函数:LoadImgFromResource[9/21/2016 IT];
  366. /* 描述:从资源中加载;
  367. /* 参数:;
  368. /* [IN] :;
  369. /* [OUT] :;
  370. /* [IN/OUT] :;
  371. /* 返回:void;
  372. /* 注意:;
  373. /* 示例:;
  374. /*
  375. /* 修改:;
  376. /* 日期:;
  377. /* 内容:;
  378. /************************************************************************/
  379. Image* LoadImgFromResource(IN HMODULE hModule, IN LPCTSTR lpName, IN LPCTSTR lpType)
  380. {
  381. HGLOBAL hGlobal = NULL;
  382. HRSRC hSource = NULL;
  383. LPVOID lpBuffer = NULL;
  384. DWORD dwSize = 0;
  385. // 1.定位我们的自定义资源,这里因为我们是从本模块定位资源,所以将句柄简单地置为NULL即可
  386. hSource = FindResource(hModule, lpName, lpType);
  387. if (hSource == NULL)
  388. {
  389. _tprintf(_T("载入资源失败:%s"), lpName);
  390. return NULL;
  391. }
  392. // 2.获取资源的大小;
  393. dwSize = (UINT)SizeofResource(NULL, hSource);
  394. // 3.加载资源;
  395. hGlobal = LoadResource(NULL, hSource);
  396. if (hGlobal == NULL)
  397. {
  398. _tprintf(_T("载入资源失败:%s"), lpName);
  399. return NULL;
  400. }
  401. // 4.锁定资源,获取buffer;
  402. lpBuffer = LockResource(hGlobal);
  403. if (lpBuffer == NULL)
  404. {
  405. _tprintf(_T("载入资源失败:%s"), lpName);
  406. return NULL;
  407. }
  408. // lpFileFullName需要先判断文件是否存在??不需要;
  409. Image* pImg = NULL;
  410. LoadImgFromBuffer(&pImg, (BYTE*)lpBuffer, dwSize);
  411. UnlockResource(hGlobal);
  412. FreeResource(hGlobal);
  413. return pImg;
  414. }
  415. BOOL SaveImgByRotate(LPCTSTR lpszFileName, BYTE* pBuffer, const INT& nBufLen, BOOL bHoriontal, BOOL bVertically)
  416. {
  417. Image* pImg = NULL;
  418. HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, nBufLen);
  419. if (hMemery == NULL)
  420. return FALSE;
  421. BYTE* pMem = NULL;
  422. pMem = (BYTE*)GlobalLock(hMemery);
  423. if (pMem == NULL)
  424. return FALSE;
  425. memcpy(pMem, pBuffer, nBufLen);
  426. IStream* pstream = NULL;
  427. HRESULT hr = CreateStreamOnHGlobal(hMemery, TRUE, &pstream);
  428. if (pstream == NULL)
  429. return FALSE;
  430. pImg = Image::FromStream(pstream);
  431. GlobalUnlock(hMemery);
  432. pstream->Release();
  433. if (bHoriontal && !bVertically)
  434. pImg->RotateFlip(RotateNoneFlipX);// 水平翻转;
  435. else if (bHoriontal && bVertically)
  436. pImg->RotateFlip(Rotate180FlipNone);// 270度;
  437. else if (!bHoriontal && bVertically)
  438. pImg->RotateFlip(Rotate180FlipX);// 垂直翻转;
  439. CString strNewfile = lpszFileName;
  440. // 需要判断路径是否存在,不存在创建目录;
  441. int nIndex = strNewfile.ReverseFind(_T('\\'));
  442. if (nIndex == -1)
  443. return FALSE;
  444. if (!PathFileExists(strNewfile.Left(nIndex)))
  445. {
  446. // 如果文件夹不存在,创建;
  447. SHCreateDirectoryEx(NULL, strNewfile.Left(nIndex), NULL);
  448. }
  449. nIndex = strNewfile.ReverseFind(_T('.'));
  450. if (nIndex == -1)
  451. return FALSE;
  452. Status stat = GenericError;
  453. CLSID encoderClsid = { 0 };
  454. BSTR newfile = strNewfile.AllocSysString();
  455. strNewfile = strNewfile.Mid(nIndex + 1);
  456. if (strNewfile.CompareNoCase(_T("bmp")) == 0)
  457. {
  458. GetEncoderClsid(L"image/bmp", &encoderClsid);
  459. stat = pImg->Save(newfile, &encoderClsid, NULL);
  460. }
  461. else if (strNewfile.CompareNoCase(_T("png")) == 0)
  462. {
  463. GetEncoderClsid(L"image/png", &encoderClsid);
  464. stat = pImg->Save(newfile, &encoderClsid, NULL);
  465. }
  466. else// if ( strNewfile.CompareNoCase(_T("jpeg")) == 0 )
  467. {
  468. GetEncoderClsid(L"image/jpeg", &encoderClsid);
  469. EncoderParameters encoderParameters;
  470. encoderParameters.Count = 1;
  471. encoderParameters.Parameter[0].Guid = EncoderQuality;
  472. encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
  473. encoderParameters.Parameter[0].NumberOfValues = 1;
  474. // Save the image as a JPEG with quality level 100.
  475. ULONG uQuality = 100;
  476. encoderParameters.Parameter[0].Value = &uQuality;
  477. stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
  478. }
  479. if (pImg)
  480. delete pImg;
  481. pImg = NULL;
  482. SysFreeString(newfile);
  483. return stat == Ok ? TRUE : FALSE;
  484. }
  485. void MKDIR(LPCTSTR dir)
  486. {
  487. //////////////////////////////////////////////////////////////////////////
  488. // 创建目录;
  489. int nleft = 0;
  490. int nIndex = -1;
  491. TString strdir = dir;
  492. if (strdir.at(strdir.size() - 1) != _T('\\'))
  493. strdir.append(_T("\\"));
  494. // 共享路径和硬盘盘符;
  495. if (_tcscmp(strdir.substr(0, 2).c_str(), _T("\\\\")) == 0)
  496. nleft = strdir.find_first_of(_T("\\"), 2) + 1; // 去除共享主机名;
  497. else if (strdir.at(2) == _T('\\'))
  498. nleft = 3;
  499. do
  500. {
  501. nIndex = strdir.substr(nleft, -1).find_first_of(_T("\\"));
  502. if (nIndex != TString::npos)
  503. {
  504. if (_tmkdir(strdir.substr(0, nIndex + nleft).c_str()) == -1 && (errno != EEXIST))
  505. {
  506. WriteTextLog(_T("创建目录失败:%s,错误码:%d"), strdir.substr(0, nIndex + nleft).c_str(), errno);
  507. break;
  508. }
  509. nleft += nIndex + 1;
  510. }
  511. } while (nIndex != -1);
  512. }
  513. // hModule 模块句柄 NULL表示当前模块;
  514. bool GetVersion(OUT WORD* pdwFileVersion, OUT WORD* pdwProductVerion)
  515. {
  516. TCHAR szFilePath[MAX_PATH] = { 0 };
  517. DWORD dwRet = GetModuleFileName(NULL, szFilePath, MAX_PATH);
  518. if (dwRet == 0)
  519. return false;
  520. VS_FIXEDFILEINFO* pVi = NULL;
  521. DWORD dwHandle = 0;
  522. int size = GetFileVersionInfoSize(szFilePath, &dwHandle);
  523. if (size > 0)
  524. {
  525. BYTE* buffer = new BYTE[size];
  526. memset(buffer, 0, size);
  527. if (GetFileVersionInfo(szFilePath, dwHandle, size, buffer))
  528. {
  529. if (VerQueryValue(buffer, _T("\\"), (LPVOID*)&pVi, (PUINT)&size))
  530. {
  531. pdwFileVersion[0] = HIWORD(pVi->dwFileVersionMS);
  532. pdwFileVersion[1] = LOWORD(pVi->dwFileVersionMS);
  533. pdwFileVersion[2] = HIWORD(pVi->dwFileVersionLS);
  534. pdwFileVersion[3] = LOWORD(pVi->dwFileVersionLS);
  535. pdwProductVerion[0] = HIWORD(pVi->dwProductVersionMS);
  536. pdwProductVerion[1] = LOWORD(pVi->dwProductVersionMS);
  537. pdwProductVerion[2] = HIWORD(pVi->dwProductVersionLS);
  538. pdwProductVerion[3] = LOWORD(pVi->dwProductVersionLS);
  539. delete[]buffer;
  540. return true;
  541. }
  542. }
  543. delete[]buffer;
  544. }
  545. return false;
  546. }
  547. }