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.

802 lines
20 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. // File: NetworkTools.cpp
  3. //
  4. // Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // Purpose:
  7. // NetworkTools.cpp: Helper functions that send/receive data.
  8. //
  9. // History:
  10. // 02/22/01 DennisCh Created
  11. //
  12. //////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////////////////////////////
  14. //
  15. // Includes
  16. //
  17. //////////////////////////////////////////////////////////////////////
  18. //
  19. // Project headers
  20. //
  21. #include "NetworkTools.h"
  22. #include "ServerCommands.h"
  23. //
  24. // Win32 headers
  25. //
  26. //////////////////////////////////////////////////////////////////////
  27. //
  28. // Globals and statics
  29. //
  30. //////////////////////////////////////////////////////////////////////
  31. extern ServerCommands g_objServerCommands; // Declared in WinHttpStressScheduler.cpp
  32. extern HWND g_hWnd; // Declared in WinHttpStressScheduler.cpp
  33. ////////////////////////////////////////////////////////////
  34. // Function: NetworkTools__GetFileNameFromURL(LPTSTR)
  35. //
  36. // Purpose:
  37. // Returns the filename requested from an URL without a querystring.
  38. // For example, if szURL="http://dennisch/files/test.exe" we return "test.exe"
  39. //
  40. ////////////////////////////////////////////////////////////
  41. BOOL
  42. NetworkTools__GetFileNameFromURL(
  43. LPTSTR szURL, // [IN] Full URL containing the file
  44. LPTSTR szBuffer, // [OUT] Buffer to store the filename from the URL
  45. DWORD dwBufferSize // [IN] Size of buffer szFileName
  46. )
  47. {
  48. TCHAR *pLastSlash;
  49. INT iCharToLookFor;
  50. if (0 >= _tcslen(szURL))
  51. return FALSE;
  52. ZeroMemory(szBuffer, dwBufferSize);
  53. pLastSlash = NULL;
  54. iCharToLookFor = _T('/');
  55. // get the last instance of '/'
  56. pLastSlash = _tcsrchr(szURL, iCharToLookFor);
  57. // skip the last '/'
  58. pLastSlash++;
  59. if (!pLastSlash)
  60. return FALSE;
  61. // copy the filename.extension to the buffer
  62. _tcscpy(szBuffer, pLastSlash);
  63. return TRUE;
  64. }
  65. ////////////////////////////////////////////////////////////
  66. // Function: NetworkTools__SendResponse(LPTSTR, LPTSTR, LPTSTR)
  67. //
  68. // Purpose:
  69. // Sends a message to the Command Server results page
  70. // via header/headervalue and/or POST data.
  71. //
  72. ////////////////////////////////////////////////////////////
  73. BOOL
  74. NetworkTools__POSTResponse(
  75. LPTSTR szURL, // [IN] string containing URL to POST to
  76. LPSTR szPostData, // [IN] string containing POST data to send. can be NULL
  77. LPTSTR szHeader // [IN] string containing header(s) to send. can be NULL
  78. )
  79. {
  80. BOOL bResult = TRUE;
  81. HINTERNET hRoot = NULL;
  82. HINTERNET hSession = NULL;
  83. HINTERNET hRequest = NULL;
  84. URL_COMPONENTSW urlComponents;
  85. // Allocate space for URL components
  86. ZeroMemory(&urlComponents, sizeof(urlComponents));
  87. urlComponents.dwSchemeLength = MAX_PATH;
  88. urlComponents.lpszScheme = new TCHAR[MAX_PATH];
  89. urlComponents.dwHostNameLength = MAX_PATH;
  90. urlComponents.lpszHostName = new TCHAR[MAX_PATH];
  91. urlComponents.dwUrlPathLength = MAX_PATH;
  92. urlComponents.lpszUrlPath = new TCHAR[MAX_PATH];
  93. urlComponents.dwExtraInfoLength = MAX_PATH;
  94. urlComponents.lpszExtraInfo = new TCHAR[MAX_PATH];
  95. urlComponents.dwUserNameLength = MAX_PATH;
  96. urlComponents.lpszUserName = new TCHAR[MAX_PATH];
  97. urlComponents.dwPasswordLength = MAX_PATH;
  98. urlComponents.lpszPassword = new TCHAR[MAX_PATH];
  99. urlComponents.nPort = 0;
  100. urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
  101. // crack the Command Server URL to be used later
  102. if (!WinHttpCrackUrl(
  103. szURL,
  104. _tcslen(szURL),
  105. ICU_ESCAPE,
  106. &urlComponents)
  107. )
  108. {
  109. bResult = FALSE;
  110. goto Exit;
  111. }
  112. hRoot = WinHttpOpen(
  113. STRESS_SCHEDULER_USER_AGENT,
  114. WINHTTP_ACCESS_TYPE_NO_PROXY,
  115. NULL,
  116. NULL,
  117. 0);
  118. if (!hRoot)
  119. {
  120. bResult = FALSE;
  121. goto Exit;
  122. }
  123. hSession = WinHttpConnect(
  124. hRoot,
  125. urlComponents.lpszHostName,
  126. // If the URL in urlComponents uses standard HTTP or HTTPS ports then use INTERNET_DEFAULT_PORT. Otherwise use the non-standard port gleaned from the URL.
  127. ((urlComponents.nPort == 80) || (urlComponents.nPort == 443)) ? INTERNET_DEFAULT_PORT : urlComponents.nPort,
  128. 0);
  129. if (!hSession)
  130. {
  131. bResult = FALSE;
  132. goto Exit;
  133. }
  134. // Build a full URL with path and querystring
  135. TCHAR szFullPath[MAX_PATH*2];
  136. _tcsncpy(szFullPath, urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
  137. szFullPath[urlComponents.dwUrlPathLength] = _T('\0');
  138. _tcsncat(szFullPath, urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength);
  139. hRequest = WinHttpOpenRequest(
  140. hSession,
  141. _T("POST"),
  142. szFullPath,
  143. NULL,
  144. NULL,
  145. NULL,
  146. // if the URL in urlComponents uses HTTPS then pass in WINHTTP_FLAG_SECURE to this param. Otherwise, 0.
  147. (0 == _tcsnicmp(urlComponents.lpszScheme, _T("https"), 5)) ? WINHTTP_FLAG_SECURE : 0);
  148. if (!hRequest)
  149. {
  150. bResult = FALSE;
  151. goto Exit;
  152. }
  153. // Set reasonable timeouts just in case
  154. if (!WinHttpSetTimeouts(hRequest, 5000, 5000, 5000, 5000))
  155. {
  156. bResult = FALSE;
  157. goto Exit;
  158. }
  159. // Set result header if not NULL
  160. if (szHeader)
  161. {
  162. if (!WinHttpAddRequestHeaders(
  163. hRequest,
  164. szHeader,
  165. _tcsclen(szHeader),
  166. WINHTTP_ADDREQ_FLAG_ADD))
  167. {
  168. bResult = FALSE;
  169. goto Exit;
  170. }
  171. }
  172. bResult = WinHttpSendRequest(
  173. hRequest,
  174. _T("Content-Type: application/x-www-form-urlencoded"),
  175. -1L,
  176. szPostData,
  177. strlen(szPostData),
  178. strlen(szPostData),
  179. 0);
  180. if (!WinHttpReceiveResponse(hRequest, NULL))
  181. {
  182. bResult = FALSE;
  183. goto Exit;
  184. }
  185. Exit:
  186. if (hRequest)
  187. WinHttpCloseHandle(hRequest);
  188. if (hSession)
  189. WinHttpCloseHandle(hSession);
  190. if (hRoot)
  191. WinHttpCloseHandle(hRoot);
  192. delete [] urlComponents.lpszScheme;
  193. delete [] urlComponents.lpszHostName;
  194. delete [] urlComponents.lpszUrlPath;
  195. delete [] urlComponents.lpszExtraInfo;
  196. delete [] urlComponents.lpszPassword;
  197. delete [] urlComponents.lpszUserName;
  198. return bResult;
  199. }
  200. ////////////////////////////////////////////////////////////
  201. // Function: NetworkTools__URLDownloadToFile(LPCTSTR, LPCTSTR, LPCTSTR)
  202. //
  203. // Purpose:
  204. // Downloads a file pointed to by the URL. Returns TRUE if succesfully downloaded.
  205. // FALSE if not. If the file is in use (ERROR_SHARING_VIOLATION) then we'll
  206. // return TRUE because the file is already on the system and is valid.
  207. //
  208. ////////////////////////////////////////////////////////////
  209. BOOL
  210. NetworkTools__URLDownloadToFile(
  211. LPCTSTR szURL, // [IN] Fully qualified URL pointing to the file to download
  212. LPCTSTR szTargetDir, // [IN] A relative path to the directory to put szTargetFile in. If NULL, then it'll be put in the app's current dir.
  213. LPCTSTR szTargetFile // [IN] Name of the file to download to. Can be NULL. File will be placed in szTargetDir. If it already exists, then we'll try to overwrite it.
  214. )
  215. {
  216. HANDLE hFile = NULL;
  217. BOOL bResult = TRUE;
  218. HINTERNET hRoot = NULL;
  219. HINTERNET hSession = NULL;
  220. HINTERNET hRequest = NULL;
  221. URL_COMPONENTSW urlComponents;
  222. // Allocate space for URL components
  223. ZeroMemory(&urlComponents, sizeof(urlComponents));
  224. urlComponents.dwSchemeLength = MAX_PATH;
  225. urlComponents.lpszScheme = new TCHAR[MAX_PATH];
  226. urlComponents.dwHostNameLength = MAX_PATH;
  227. urlComponents.lpszHostName = new TCHAR[MAX_PATH];
  228. urlComponents.dwUrlPathLength = MAX_PATH;
  229. urlComponents.lpszUrlPath = new TCHAR[MAX_PATH];
  230. urlComponents.dwExtraInfoLength = MAX_PATH;
  231. urlComponents.lpszExtraInfo = new TCHAR[MAX_PATH];
  232. urlComponents.dwUserNameLength = MAX_PATH;
  233. urlComponents.lpszUserName = new TCHAR[MAX_PATH];
  234. urlComponents.dwPasswordLength = MAX_PATH;
  235. urlComponents.lpszPassword = new TCHAR[MAX_PATH];
  236. urlComponents.nPort = 0;
  237. urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
  238. // crack the Command Server URL to be used later
  239. if (!WinHttpCrackUrl(
  240. szURL,
  241. _tcslen(szURL),
  242. ICU_ESCAPE,
  243. &urlComponents)
  244. )
  245. {
  246. bResult = FALSE;
  247. goto Exit;
  248. }
  249. hRoot = WinHttpOpen(
  250. STRESS_SCHEDULER_USER_AGENT,
  251. WINHTTP_ACCESS_TYPE_NO_PROXY,
  252. NULL,
  253. NULL,
  254. 0);
  255. if (!hRoot)
  256. {
  257. bResult = FALSE;
  258. goto Exit;
  259. }
  260. hSession = WinHttpConnect(
  261. hRoot,
  262. urlComponents.lpszHostName,
  263. // If the URL in urlComponents uses standard HTTP or HTTPS ports then use INTERNET_DEFAULT_PORT. Otherwise use the non-standard port gleaned from the URL.
  264. ((urlComponents.nPort == 80) || (urlComponents.nPort == 443)) ? INTERNET_DEFAULT_PORT : urlComponents.nPort,
  265. 0);
  266. if (!hSession)
  267. {
  268. bResult = FALSE;
  269. goto Exit;
  270. }
  271. // Build a full URL with path and querystring
  272. TCHAR szFullPath[MAX_PATH*2];
  273. _tcsncpy(szFullPath, urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
  274. szFullPath[urlComponents.dwUrlPathLength] = _T('\0');
  275. _tcsncat(szFullPath, urlComponents.lpszExtraInfo, urlComponents.dwExtraInfoLength);
  276. hRequest = WinHttpOpenRequest(
  277. hSession,
  278. _T("GET"),
  279. szFullPath,
  280. NULL,
  281. NULL,
  282. NULL,
  283. // if the URL in urlComponents uses HTTPS then pass in WINHTTP_FLAG_SECURE to this param. Otherwise, 0.
  284. (0 == _tcsnicmp(urlComponents.lpszScheme, _T("https"), 5)) ? WINHTTP_FLAG_SECURE : 0);
  285. if (!hRequest)
  286. {
  287. bResult = FALSE;
  288. goto Exit;
  289. }
  290. // Set reasonable timeouts just in case
  291. if (!WinHttpSetTimeouts(hRequest, 5000, 5000, 5000, 5000))
  292. {
  293. bResult = FALSE;
  294. goto Exit;
  295. }
  296. bResult = WinHttpSendRequest(
  297. hRequest,
  298. NULL,
  299. 0,
  300. NULL,
  301. 0,
  302. 0,
  303. 0);
  304. if (!WinHttpReceiveResponse(hRequest, NULL))
  305. {
  306. bResult = FALSE;
  307. goto Exit;
  308. }
  309. // **********************************
  310. // **********************************
  311. // ** Get the filename and extenstion
  312. // ** from the URL
  313. // **
  314. TCHAR szFileName[MAX_PATH]; // name of the new file to write to. will be created in szCurrentDir
  315. ZeroMemory(szFileName, sizeof(szFileName));
  316. // check to see if the user provided a filename to write to
  317. if (szTargetFile)
  318. _tcsncpy(szFileName, szTargetFile, MAX_PATH);
  319. else
  320. {
  321. // user did not specify a filename to write to, so we use the original one from the URL
  322. if (!NetworkTools__GetFileNameFromURL(urlComponents.lpszUrlPath, szFileName, sizeof(szFileName)))
  323. {
  324. bResult = FALSE;
  325. goto Exit;
  326. }
  327. }
  328. // **********************************
  329. // **********************************
  330. // ** Create the directory where the file will reside and set it as the current directory
  331. // **
  332. // if user specified NULL, then we put the file in the current dir.
  333. // else we set the current directory as the one specified
  334. if (szTargetDir)
  335. {
  336. // create the dir. don't care if it fails because it already exists...
  337. CreateDirectory(szTargetDir, NULL);
  338. SetCurrentDirectory(szTargetDir);
  339. }
  340. // create the file to download to.
  341. hFile = CreateFile(
  342. // if the user doesn't specify the filename to write to, use the one from the URL
  343. szFileName,
  344. GENERIC_WRITE,
  345. 0,
  346. NULL,
  347. CREATE_ALWAYS,
  348. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
  349. NULL);
  350. if ((hFile == INVALID_HANDLE_VALUE) || !hFile)
  351. {
  352. // We won't return FALSE if the file is in use. This means the file is valid.
  353. if (ERROR_SHARING_VIOLATION == GetLastError())
  354. {
  355. // File is in use that means winhttp is ok. we'll stress the old version
  356. bResult = TRUE;
  357. goto Exit;
  358. }
  359. else
  360. {
  361. bResult = FALSE;
  362. goto Exit;
  363. }
  364. }
  365. // **********************************
  366. // **********************************
  367. // ** Read data from net to file.
  368. // **
  369. LPVOID lpBuffer;
  370. DWORD dwBytesToRead, dwBytesRead;
  371. // read 64K chunks at a time
  372. lpBuffer = NULL;
  373. lpBuffer = new LPVOID[65536];
  374. ZeroMemory(lpBuffer, 65536);
  375. dwBytesToRead = 65536;
  376. dwBytesRead = 65536;
  377. while (WinHttpReadData(hRequest, lpBuffer, dwBytesToRead, &dwBytesRead) && (0 != dwBytesRead))
  378. {
  379. WriteFile(hFile, lpBuffer, dwBytesRead, &dwBytesRead, NULL);
  380. dwBytesRead = 0;
  381. ZeroMemory(lpBuffer, sizeof(lpBuffer));
  382. }
  383. delete [] lpBuffer;
  384. Exit:
  385. if (hRequest)
  386. WinHttpCloseHandle(hRequest);
  387. if (hSession)
  388. WinHttpCloseHandle(hSession);
  389. if (hRoot)
  390. WinHttpCloseHandle(hRoot);
  391. if (hFile && (hFile != INVALID_HANDLE_VALUE))
  392. CloseHandle(hFile);
  393. // restore the current directory from the one that we created the new file in.
  394. SetCurrentDirectory(g_objServerCommands.Get_CurrentWorkingDirectory());
  395. delete [] urlComponents.lpszScheme;
  396. delete [] urlComponents.lpszHostName;
  397. delete [] urlComponents.lpszUrlPath;
  398. delete [] urlComponents.lpszExtraInfo;
  399. delete [] urlComponents.lpszPassword;
  400. delete [] urlComponents.lpszUserName;
  401. return bResult;
  402. }
  403. ////////////////////////////////////////////////////////////
  404. // Function: NetworkTools__CopyFile(LPCTSTR, LPCTSTR)
  405. //
  406. // Purpose:
  407. // Wrapper for CopyFile. Copies file szSource to szDestination.
  408. // We'll always overwite the file if it already exists.
  409. //
  410. ////////////////////////////////////////////////////////////
  411. BOOL
  412. NetworkTools__CopyFile(
  413. LPCTSTR szSource,
  414. LPCTSTR szDestination
  415. )
  416. {
  417. BOOL bResult = TRUE;
  418. if (!szSource || !szDestination)
  419. {
  420. bResult = FALSE;
  421. goto Exit;
  422. }
  423. bResult = CopyFile(szSource, szDestination, TRUE);
  424. Exit:
  425. return bResult;
  426. }
  427. ////////////////////////////////////////////////////////////
  428. // Function: NetworkTools__PageHeap(BOOL, LPCTSTR)
  429. //
  430. // Purpose:
  431. // Enables/Disables pageheap.
  432. //
  433. ////////////////////////////////////////////////////////////
  434. BOOL
  435. NetworkTools__PageHeap(
  436. BOOL bEnable, // [IN] Enables/Disables pageheap.
  437. LPCTSTR szAppName, // [IN] The executable to enable or disable.
  438. LPCTSTR szCommandLine // [IN] Command line for pageheap.
  439. )
  440. {
  441. BOOL bResult = TRUE;
  442. HINSTANCE hExe = NULL;
  443. LPTSTR szPHCommand = new TCHAR[MAX_PATH];
  444. if (bEnable)
  445. {
  446. hExe = ShellExecute(g_hWnd, _T("open"), _T("pageheap.exe"), szCommandLine, NULL, SW_SHOWMINIMIZED);
  447. }
  448. else
  449. {
  450. ZeroMemory(szPHCommand, MAX_PATH);
  451. _tcscpy(szPHCommand, _T("/disable "));
  452. _tcscat(szPHCommand, szAppName);
  453. hExe = ShellExecute(g_hWnd, _T("open"), _T("pageheap.exe"), szPHCommand, NULL, SW_SHOWMINIMIZED);
  454. }
  455. // Error if HINSTANCE <= 32.
  456. if (32 >= (INT) hExe)
  457. bResult = FALSE;
  458. delete [] szPHCommand;
  459. return bResult;
  460. }
  461. ////////////////////////////////////////////////////////////
  462. // Function: NetworkTools__UMDH(LPCTSTR, DWORD, LPCTSTR)
  463. //
  464. // Purpose:
  465. // Enables/Disables UMDH.
  466. //
  467. ////////////////////////////////////////////////////////////
  468. BOOL
  469. NetworkTools__UMDH(
  470. BOOL bEnable, // [IN] Enables/Disables UMDH.
  471. LPCTSTR szAppName, // [IN] The executable to dump.
  472. LPCTSTR szCommandLine, // [IN] Command line for UMDH.
  473. LPCTSTR szLogFile, // [IN] Logfile to create
  474. DWORD dwPID // [IN] The PID of the process to dump
  475. )
  476. {
  477. BOOL bResult = TRUE;
  478. HINSTANCE hExe = NULL;
  479. LPTSTR szCommand = new TCHAR[MAX_PATH];
  480. // build command line and run: "GFLAGS -i <stressExe name> +ust"
  481. ZeroMemory(szCommand, MAX_PATH);
  482. _tcscpy(szCommand, _T("-i "));
  483. _tcscat(szCommand, szAppName);
  484. _tcscat(szCommand, _T(" +ust"));
  485. hExe = ShellExecute(g_hWnd, _T("open"), DEBUGGER_TOOLS_PATH _T("gflags.exe"), szCommand, NULL, SW_SHOWMINIMIZED);
  486. // build the UMDH command line
  487. ZeroMemory(szCommand, MAX_PATH);
  488. _tcscpy(szCommand, _T("-f:stuff.log"));
  489. hExe = ShellExecute(g_hWnd, _T("open"), DEBUGGER_TOOLS_PATH _T("umdh.exe"), szCommand, NULL, SW_SHOWMINIMIZED);
  490. // Error if HINSTANCE <= 32.
  491. if (32 >= (INT) hExe)
  492. bResult = FALSE;
  493. delete [] szCommand;
  494. return bResult;
  495. }
  496. ////////////////////////////////////////////////////////////
  497. // Function: NetworkTools__SendLog(LPSTR, LPSTR, LPTSTR, DWORD)
  498. //
  499. // Purpose:
  500. // Sends a log to the Command Server. Takes the log type string and log string.
  501. // Sends the stressInstance ID and client machine name as part of the POST request.
  502. // If this is a general message, then the stressInstanceID should be set to zero. Otherwise
  503. // if and ID is supplied, then stressAdmin will log this to the stressInstanceLog table.
  504. // You can also add headers too.
  505. //
  506. ////////////////////////////////////////////////////////////
  507. BOOL
  508. NetworkTools__SendLog(
  509. LPSTR szLogType,
  510. LPSTR szLogText,
  511. LPTSTR szExtraHeaders,
  512. DWORD dwStressInstanceID
  513. )
  514. {
  515. BOOL bResult = TRUE;
  516. LPSTR szPostLogData = NULL;
  517. CHAR szStressInstanceID[10];
  518. LPSTR szDllVersion = new CHAR[MAX_PATH];
  519. LPSTR szNumber = new CHAR[10];
  520. DWORD dwPostLogDataSize = 0;
  521. if (!szLogType || !szLogText || !g_objServerCommands.Get_ClientMachineName())
  522. {
  523. OutputDebugStringA("NetworkTools__SendLog: ERROR: szLogType, szLogText, or g_objServerCommands.Get_ClientMachineName() is NULL.");
  524. bResult = FALSE;
  525. goto Exit;
  526. }
  527. dwPostLogDataSize = sizeof(FIELDNAME__STRESSINSTANCE_ID) + MAX_PATH;
  528. dwPostLogDataSize += sizeof(FIELDNAME__LOG_TEXT) + strlen(szLogText);
  529. dwPostLogDataSize += sizeof(FIELDNAME__USERINFO_MACHINENAME) + strlen(g_objServerCommands.Get_ClientMachineName());
  530. dwPostLogDataSize += strlen(szLogType);
  531. dwPostLogDataSize += sizeof(FIELDNAME__TESTINFO_TEST_DLL_VERSION) + MAX_PATH;
  532. szPostLogData = new CHAR[dwPostLogDataSize];
  533. ZeroMemory(szPostLogData, dwPostLogDataSize);
  534. // ***************************
  535. // ** add the client's machine name
  536. strcpy(szPostLogData, FIELDNAME__USERINFO_MACHINENAME);
  537. strcat(szPostLogData, g_objServerCommands.Get_ClientMachineName());
  538. // ***************************
  539. // ** add the stressInstance ID if valid
  540. if (0 < dwStressInstanceID)
  541. {
  542. strcat(szPostLogData, "&" FIELDNAME__STRESSINSTANCE_ID);
  543. strcat(szPostLogData, _itoa(dwStressInstanceID, szStressInstanceID, 10));
  544. }
  545. // ***************************
  546. // ** add the log type data
  547. strcat(szPostLogData, "&");
  548. strcat(szPostLogData, szLogType);
  549. // ***************************
  550. // ** add the test dll version info
  551. if (
  552. g_objServerCommands.Get_TestDllFileName() &&
  553. NetworkTools__GetDllVersion(g_objServerCommands.Get_TestDllFileName(), szDllVersion, MAX_PATH)
  554. )
  555. {
  556. strcat(szPostLogData, "&" FIELDNAME__TESTINFO_TEST_DLL_VERSION);
  557. strcat(szPostLogData, szDllVersion);
  558. }
  559. // ***************************
  560. // ** add the log text data
  561. strcat(szPostLogData, "&" FIELDNAME__LOG_TEXT);
  562. strcat(szPostLogData, szLogText);
  563. // ***************************
  564. // ** Send the data
  565. bResult = NetworkTools__POSTResponse(STRESS_COMMAND_SERVER_LOGURL, szPostLogData, szExtraHeaders);
  566. //OutputDebugStringA(szPostLogData);
  567. Exit:
  568. if (szPostLogData)
  569. delete [] szPostLogData;
  570. delete [] szDllVersion;
  571. delete [] szNumber;
  572. return bResult;
  573. }
  574. ////////////////////////////////////////////////////////////
  575. // Function: NetworkTools__GetDllVersion(LPTSTR, LPSTR, DWORD)
  576. //
  577. // Purpose:
  578. // Takes a DLL name and return the version as an ASCII string.
  579. //
  580. ////////////////////////////////////////////////////////////
  581. BOOL
  582. NetworkTools__GetDllVersion(
  583. LPTSTR lpszDllName,
  584. LPSTR szVersionBuffer,
  585. DWORD dwVersionBufferSize
  586. )
  587. {
  588. BOOL bResult = TRUE;
  589. DWORD dwHandle;
  590. DWORD dwVersionSize;
  591. LPSTR szVersionInfo = NULL;
  592. LPSTR szVersionOutput = NULL;
  593. UINT uiLength;
  594. ZeroMemory(szVersionBuffer, dwVersionBufferSize);
  595. dwVersionSize = GetFileVersionInfoSize(lpszDllName, &dwHandle);
  596. if (0 >= dwVersionSize)
  597. {
  598. bResult = FALSE;
  599. goto Exit;
  600. }
  601. // allocate new buffer for the query
  602. szVersionInfo = new CHAR[dwVersionSize];
  603. ZeroMemory(szVersionInfo, dwVersionSize);
  604. if (!GetFileVersionInfo(lpszDllName, NULL, dwVersionSize, szVersionInfo))
  605. {
  606. bResult = FALSE;
  607. goto Exit;
  608. }
  609. // *****************************
  610. // ** build the version info query string
  611. struct LANGANDCODEPAGE {
  612. WORD wLanguage;
  613. WORD wCodePage;
  614. } *lpTranslate;
  615. CHAR szVersionQuery[200];
  616. ZeroMemory(szVersionQuery, 200);
  617. // Read the list of languages and code pages.
  618. VerQueryValueA(szVersionInfo,
  619. "\\VarFileInfo\\Translation",
  620. (LPVOID*)&lpTranslate,
  621. &uiLength);
  622. // build the ver info query string that contains the language bits
  623. sprintf(szVersionQuery, "\\StringFileInfo\\%04x%04x\\ProductVersion", lpTranslate->wLanguage, lpTranslate->wCodePage);
  624. // *****************************
  625. // ** Get the version and copy to buffer
  626. uiLength = 0;
  627. if (!VerQueryValueA(szVersionInfo, szVersionQuery, (VOID **) &szVersionOutput, &uiLength))
  628. {
  629. bResult = FALSE;
  630. goto Exit;
  631. }
  632. // copy the version info string to the buffer
  633. strncpy(szVersionBuffer, (LPSTR) szVersionOutput, dwVersionBufferSize-1);
  634. Exit:
  635. if (szVersionInfo)
  636. delete [] szVersionInfo;
  637. return bResult;
  638. }