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.

1005 lines
30 KiB

  1. // StressSvc.cpp : Implementation of WinMain
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f StressSvcps.mk in the project directory.
  5. #include "stdafx.h"
  6. #include "resource.h"
  7. #include <initguid.h>
  8. #include "StressSvc.h"
  9. #include "StressSvc_i.c"
  10. #include <stdio.h>
  11. #include <windows.h>
  12. #include <wtypes.h>
  13. #include <malloc.h>
  14. #include <wininet.h>
  15. #include <strsafe.h>
  16. #include <io.h>
  17. #include <fcntl.h>
  18. #include <cmnutil.hpp>
  19. //Globals
  20. TCHAR tszHostName[MAX_PATH];
  21. TCHAR tszRootDirectory[MAX_PATH];
  22. HANDLE g_hStopEvent = NULL;
  23. HANDLE g_hStopEvent1 = NULL;
  24. CServiceModule _Module;
  25. BEGIN_OBJECT_MAP(ObjectMap)
  26. END_OBJECT_MAP()
  27. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  28. {
  29. while (p1 != NULL && *p1 != NULL)
  30. {
  31. LPCTSTR p = p2;
  32. while (p != NULL && *p != NULL)
  33. {
  34. if (*p1 == *p)
  35. return CharNext(p1);
  36. p = CharNext(p);
  37. }
  38. p1 = CharNext(p1);
  39. }
  40. return NULL;
  41. }
  42. // Although some of these functions are big they are declared inline since they are only used once
  43. inline HRESULT CServiceModule::RegisterServer(BOOL bRegTypeLib, BOOL bService)
  44. {
  45. HRESULT hr = CoInitialize(NULL);
  46. if (FAILED(hr))
  47. return hr;
  48. // Remove any previous service since it may point to
  49. // the incorrect file
  50. // Uninstall();
  51. // Add service entries
  52. UpdateRegistryFromResource(IDR_StressSvc, TRUE);
  53. // Adjust the AppID for Local Server or Service
  54. CRegKey keyAppID;
  55. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
  56. if (lRes != ERROR_SUCCESS)
  57. return lRes;
  58. CRegKey key;
  59. lRes = key.Open(keyAppID, _T("{AC57FB6A-13ED-443D-9A9F-D34966576A62}"), KEY_WRITE);
  60. if (lRes != ERROR_SUCCESS)
  61. return lRes;
  62. key.DeleteValue(_T("LocalService"));
  63. if (bService)
  64. {
  65. key.SetValue(_T("StressSvc"), _T("LocalService"));
  66. key.SetValue(_T("-Service"), _T("ServiceParameters"));
  67. // Create service
  68. Install();
  69. }
  70. // Add object entries
  71. hr = CComModule::RegisterServer(bRegTypeLib);
  72. CoUninitialize();
  73. return hr;
  74. }
  75. inline HRESULT CServiceModule::UnregisterServer()
  76. {
  77. HRESULT hr = CoInitialize(NULL);
  78. if (FAILED(hr))
  79. return hr;
  80. // Remove service entries
  81. UpdateRegistryFromResource(IDR_StressSvc, FALSE);
  82. // Remove service
  83. Uninstall();
  84. // Remove object entries
  85. CComModule::UnregisterServer(TRUE);
  86. CoUninitialize();
  87. return S_OK;
  88. }
  89. inline void CServiceModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE h, UINT nServiceNameID, const GUID* plibid)
  90. {
  91. CComModule::Init(p, h, plibid);
  92. m_bService = TRUE;
  93. LoadString(h, nServiceNameID, m_szServiceName, sizeof(m_szServiceName) / sizeof(TCHAR));
  94. // set up the initial service status
  95. m_hServiceStatus = NULL;
  96. m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  97. m_status.dwCurrentState = SERVICE_STOPPED;
  98. m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  99. m_status.dwWin32ExitCode = 0;
  100. m_status.dwServiceSpecificExitCode = 0;
  101. m_status.dwCheckPoint = 0;
  102. m_status.dwWaitHint = 0;
  103. g_hStopEvent = CreateEvent(NULL, FALSE, FALSE, s_cszStopEvent);
  104. if(NULL == g_hStopEvent)
  105. {
  106. LogEvent( _T("Failed to create stop event: %s; hr=%ld"),
  107. s_cszStopEvent,
  108. GetLastError());
  109. }
  110. }
  111. LONG CServiceModule::Unlock()
  112. {
  113. LONG l = CComModule::Unlock();
  114. if (l == 0 && !m_bService)
  115. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  116. return l;
  117. }
  118. BOOL CServiceModule::IsInstalled()
  119. {
  120. BOOL bResult = FALSE;
  121. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  122. if (hSCM != NULL)
  123. {
  124. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
  125. if (hService != NULL)
  126. {
  127. bResult = TRUE;
  128. ::CloseServiceHandle(hService);
  129. }
  130. ::CloseServiceHandle(hSCM);
  131. }
  132. return bResult;
  133. }
  134. inline BOOL CServiceModule::Install()
  135. {
  136. if (IsInstalled())
  137. return TRUE;
  138. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  139. if (hSCM == NULL)
  140. {
  141. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  142. return FALSE;
  143. }
  144. // Get the executable file path
  145. TCHAR szFilePath[_MAX_PATH];
  146. ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
  147. SC_HANDLE hService = ::CreateService(
  148. hSCM, m_szServiceName, m_szServiceName,
  149. SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  150. SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
  151. szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
  152. if (hService == NULL)
  153. {
  154. ::CloseServiceHandle(hSCM);
  155. MessageBox(NULL, _T("Couldn't create service"), m_szServiceName, MB_OK);
  156. return FALSE;
  157. }
  158. ::CloseServiceHandle(hService);
  159. ::CloseServiceHandle(hSCM);
  160. return TRUE;
  161. }
  162. inline BOOL CServiceModule::Uninstall()
  163. {
  164. if (!IsInstalled())
  165. return TRUE;
  166. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  167. if (hSCM == NULL)
  168. {
  169. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  170. return FALSE;
  171. }
  172. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_STOP | DELETE);
  173. if (hService == NULL)
  174. {
  175. ::CloseServiceHandle(hSCM);
  176. MessageBox(NULL, _T("Couldn't open service"), m_szServiceName, MB_OK);
  177. return FALSE;
  178. }
  179. SERVICE_STATUS status;
  180. ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
  181. BOOL bDelete = ::DeleteService(hService);
  182. ::CloseServiceHandle(hService);
  183. ::CloseServiceHandle(hSCM);
  184. if (bDelete)
  185. return TRUE;
  186. MessageBox(NULL, _T("Service could not be deleted"), m_szServiceName, MB_OK);
  187. return FALSE;
  188. }
  189. ///////////////////////////////////////////////////////////////////////////////////////
  190. // Logging functions
  191. void CServiceModule::LogEvent(LPCTSTR pFormat, ...)
  192. {
  193. TCHAR chMsg[256];
  194. HANDLE hEventSource;
  195. LPTSTR lpszStrings[1];
  196. va_list pArg;
  197. va_start(pArg, pFormat);
  198. if (StringCbVPrintf(chMsg,sizeof chMsg, pFormat, pArg) != S_OK)
  199. {
  200. return;
  201. }
  202. va_end(pArg);
  203. lpszStrings[0] = chMsg;
  204. if (m_bService)
  205. {
  206. /* Get a handle to use with ReportEvent(). */
  207. hEventSource = RegisterEventSource(NULL, m_szServiceName);
  208. if (hEventSource != NULL)
  209. {
  210. /* Write to event log. */
  211. ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  212. DeregisterEventSource(hEventSource);
  213. }
  214. }
  215. else
  216. {
  217. // As we are not running as a service, just write the error to the console.
  218. _putts(chMsg);
  219. }
  220. }
  221. //////////////////////////////////////////////////////////////////////////////////////////////
  222. // Service startup and registration
  223. inline void CServiceModule::Start()
  224. {
  225. SERVICE_TABLE_ENTRY st[] =
  226. {
  227. { m_szServiceName, _ServiceMain },
  228. { NULL, NULL }
  229. };
  230. if (m_bService && !::StartServiceCtrlDispatcher(st))
  231. {
  232. m_bService = FALSE;
  233. }
  234. if (m_bService == FALSE)
  235. Run();
  236. }
  237. inline void CServiceModule::ServiceMain(DWORD /* dwArgc */, LPTSTR* /* lpszArgv */)
  238. {
  239. // Register the control request handler
  240. m_status.dwCurrentState = SERVICE_START_PENDING;
  241. m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
  242. if (m_hServiceStatus == NULL)
  243. {
  244. LogEvent(_T("Handler not installed"));
  245. return;
  246. }
  247. SetServiceStatus(SERVICE_START_PENDING);
  248. m_status.dwWin32ExitCode = S_OK;
  249. m_status.dwCheckPoint = 0;
  250. m_status.dwWaitHint = 0;
  251. // When the Run function returns, the service has stopped.
  252. Run();
  253. SetServiceStatus(SERVICE_STOPPED);
  254. LogEvent(_T("Service stopped"));
  255. }
  256. inline void CServiceModule::Handler(DWORD dwOpcode)
  257. {
  258. switch (dwOpcode)
  259. {
  260. case SERVICE_CONTROL_STOP:
  261. SetServiceStatus(SERVICE_STOP_PENDING);
  262. if(g_hStopEvent)
  263. {
  264. if( (FALSE == SetEvent( g_hStopEvent )) || (FALSE == SetEvent( g_hStopEvent1 )) )
  265. {
  266. LogEvent( _T("Unable to signal Stop Event; Error: %ld"), GetLastError());
  267. }
  268. CloseHandle( g_hStopEvent );
  269. }
  270. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  271. break;
  272. case SERVICE_CONTROL_PAUSE:
  273. break;
  274. case SERVICE_CONTROL_CONTINUE:
  275. break;
  276. case SERVICE_CONTROL_INTERROGATE:
  277. break;
  278. case SERVICE_CONTROL_SHUTDOWN:
  279. break;
  280. default:
  281. LogEvent(_T("Bad service request"));
  282. }
  283. }
  284. void WINAPI CServiceModule::_ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
  285. {
  286. _Module.ServiceMain(dwArgc, lpszArgv);
  287. }
  288. void WINAPI CServiceModule::_Handler(DWORD dwOpcode)
  289. {
  290. _Module.Handler(dwOpcode);
  291. }
  292. void CServiceModule::SetServiceStatus(DWORD dwState)
  293. {
  294. m_status.dwCurrentState = dwState;
  295. ::SetServiceStatus(m_hServiceStatus, &m_status);
  296. }
  297. void CServiceModule::Run()
  298. {
  299. _Module.dwThreadID = GetCurrentThreadId();
  300. HRESULT hr = CoInitialize(NULL);
  301. // If you are running on NT 4.0 or higher you can use the following call
  302. // instead to make the EXE free threaded.
  303. // This means that calls come in on a random RPC thread
  304. // HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  305. _ASSERTE(SUCCEEDED(hr));
  306. // This provides a NULL DACL which will allow access to everyone.
  307. CSecurityDescriptor sd;
  308. sd.InitializeFromThreadToken();
  309. hr = CoInitializeSecurity(sd, -1, NULL, NULL,
  310. RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
  311. _ASSERTE(SUCCEEDED(hr));
  312. hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
  313. _ASSERTE(SUCCEEDED(hr));
  314. LogEvent(_T("Service started"));
  315. if (m_bService)
  316. SetServiceStatus(SERVICE_RUNNING);
  317. //-------------------------
  318. try
  319. {
  320. SearchRootDirectory();
  321. }
  322. catch(...)
  323. {
  324. LogEvent(_T("Stress Service Crashed!!!!!"));
  325. }
  326. //-------------------------
  327. MSG msg;
  328. while (GetMessage(&msg, 0, 0, 0))
  329. DispatchMessage(&msg);
  330. _Module.RevokeClassObjects();
  331. CoUninitialize();
  332. }
  333. /////////////////////////////////////////////////////////////////////////////
  334. //
  335. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
  336. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  337. {
  338. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  339. _Module.Init(ObjectMap, hInstance, IDS_SERVICENAME, &LIBID_STRESSSVCLib);
  340. _Module.m_bService = TRUE;
  341. TCHAR szTokens[] = _T("-/");
  342. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  343. while (lpszToken != NULL)
  344. {
  345. if (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  346. NORM_IGNORECASE,
  347. lpszToken,
  348. -1,
  349. _T("UnregServer"),
  350. -1 ) == CSTR_EQUAL)
  351. ///if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  352. return _Module.UnregisterServer();
  353. // Register as Local Server
  354. if (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  355. NORM_IGNORECASE,
  356. lpszToken,
  357. -1,
  358. _T("RegServer"),
  359. -1 ) == CSTR_EQUAL)
  360. //if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  361. return _Module.RegisterServer(TRUE, FALSE);
  362. // Register as Service
  363. if (CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  364. NORM_IGNORECASE,
  365. lpszToken,
  366. -1,
  367. _T("Service"),
  368. -1 ) == CSTR_EQUAL)
  369. // if (lstrcmpi(lpszToken, _T("Service"))==0)
  370. return _Module.RegisterServer(TRUE, TRUE);
  371. lpszToken = FindOneOf(lpszToken, szTokens);
  372. }
  373. // Are we Service or Local Server
  374. CRegKey keyAppID;
  375. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
  376. if (lRes != ERROR_SUCCESS)
  377. return lRes;
  378. CRegKey key;
  379. lRes = key.Open(keyAppID, _T("{AC57FB6A-13ED-443D-9A9F-D34966576A62}"), KEY_READ);
  380. if (lRes != ERROR_SUCCESS)
  381. return lRes;
  382. TCHAR szValue[_MAX_PATH];
  383. DWORD dwLen = _MAX_PATH;
  384. lRes = key.QueryValue(szValue, _T("LocalService"), &dwLen);
  385. _Module.m_bService = FALSE;
  386. if (lRes == ERROR_SUCCESS)
  387. _Module.m_bService = TRUE;
  388. _Module.Start();
  389. // When we get here, the service has been stopped
  390. return _Module.m_status.dwWin32ExitCode;
  391. }
  392. BOOL
  393. CServiceModule::GetRegData()
  394. {
  395. HKEY hHKLM;
  396. HKEY hPrimaryKey = NULL;
  397. BOOL Status = TRUE;
  398. BYTE Buffer[MAX_PATH * sizeof TCHAR];
  399. DWORD BufferSize = 0;
  400. DWORD Type;
  401. if(!RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hHKLM))
  402. {
  403. if(!RegOpenKeyEx(hHKLM,_T("Software\\Microsoft\\StressSvc"), 0, KEY_ALL_ACCESS, &hPrimaryKey))
  404. {
  405. // Get the input queue directory path
  406. BufferSize = MAX_PATH * sizeof TCHAR;
  407. ZeroMemory(Buffer, MAX_PATH * sizeof TCHAR);
  408. if (RegQueryValueEx(hPrimaryKey,_T("HostName"), 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  409. {
  410. LogEvent(_T("Failed to get HostName value from registry."));
  411. Status = FALSE;
  412. }
  413. else
  414. {
  415. if (StringCbCopy (tszHostName, sizeof tszHostName,(TCHAR *) Buffer)!= S_OK)
  416. {
  417. LogEvent (_T("Failed to copy HostName reg value to tszHostName"));
  418. Status = FALSE;
  419. }
  420. }
  421. BufferSize = MAX_PATH * sizeof TCHAR;
  422. ZeroMemory(Buffer, MAX_PATH * sizeof TCHAR);
  423. // Now get the Primary Queue connection string
  424. if (RegQueryValueEx(hPrimaryKey,_T("RootDirectory"), 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  425. {
  426. LogEvent(_T("Failed to get PrimaryQueue value from registry."));
  427. Status = FALSE;
  428. }
  429. else
  430. {
  431. if (StringCbCopy(tszRootDirectory,sizeof tszRootDirectory, (TCHAR *) Buffer)!= S_OK)
  432. {
  433. LogEvent (_T("Failed to copy RootDirectory reg value to tszRootDirectory"));
  434. Status = FALSE;
  435. }
  436. }
  437. RegCloseKey(hPrimaryKey);
  438. }
  439. RegCloseKey(hHKLM);
  440. }
  441. return Status;
  442. }
  443. void
  444. CServiceModule::SearchRootDirectory(void)
  445. /*
  446. Function: SearchDirectory
  447. Purpose: Recursively search a series of directories to locate .cab files.
  448. When a .cab file is found calles GetResponseUrl to process the file.
  449. Parameters:
  450. in tszSearchDirectory - Directory in which to begin serarching for cab files.
  451. Returns:
  452. NONE
  453. */
  454. {
  455. HANDLE hFindFile = INVALID_HANDLE_VALUE;
  456. WIN32_FIND_DATA FindData;
  457. TCHAR tszSearchDir[MAX_PATH];
  458. TCHAR tszSubDir[MAX_PATH];
  459. TCHAR *temp = NULL;
  460. int iRetCode = 0;
  461. // HANDLE hStopEvent = NULL;
  462. DWORD dwWaitResult = 0;
  463. TCHAR tszCurrentFileName[MAX_PATH];
  464. if (!GetRegData())
  465. {
  466. LogEvent(_T("Failed to read ServiceParams."));
  467. goto Done;
  468. }
  469. g_hStopEvent1 = OpenEvent(EVENT_ALL_ACCESS, FALSE, s_cszStopEvent);
  470. if (g_hStopEvent1 == NULL)
  471. {
  472. LogEvent(_T("Failed to open stop event. Terminating"));
  473. goto Done;
  474. }
  475. while (1) // Start the infinit service loop
  476. {
  477. if (StringCbCopy (tszSearchDir, sizeof tszSearchDir, tszRootDirectory) == S_OK)
  478. {
  479. if (StringCbCat (tszSearchDir, sizeof tszSearchDir, _T("\\*.*")) == S_OK)
  480. {
  481. hFindFile = FindFirstFile(tszSearchDir, &FindData);
  482. if (hFindFile != INVALID_HANDLE_VALUE)
  483. {
  484. do
  485. {
  486. dwWaitResult = WaitForSingleObject(g_hStopEvent1, 200);
  487. switch (dwWaitResult)
  488. {
  489. case WAIT_OBJECT_0:
  490. // we're stopping return immediately
  491. goto Done;
  492. break;
  493. case WAIT_FAILED:
  494. // we hit an error somewhere log the event and return
  495. LogEvent (_T(" Failed wait in recursive search: ErrorCode: %d"), GetLastError());
  496. goto Done;
  497. break;
  498. default:
  499. break;
  500. }
  501. if (FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  502. {
  503. // Skip the . and .. directories all directories trigger a recursive call
  504. if ( (_tcscmp (FindData.cFileName, _T("."))) && (_tcscmp (FindData.cFileName, _T(".."))) )
  505. {
  506. // We have a directory
  507. if (StringCbPrintf(tszSubDir, sizeof tszSubDir, _T("%s\\%s"), tszRootDirectory, FindData.cFileName) == S_OK)
  508. {
  509. //LogEvent(_T("Searching directory: %s"), tszSubDir);
  510. if (SearchDirectory(tszSubDir) == 1)
  511. goto Done;
  512. }
  513. }
  514. }
  515. else
  516. {
  517. // check to see if this file as a .cab extenstion
  518. temp = FindData.cFileName + _tcslen(FindData.cFileName) -3;
  519. if (!_tcscmp (temp, _T(".cab")))
  520. {
  521. // we have a cab. Now lets process it
  522. if (StringCbPrintf(tszCurrentFileName, sizeof tszCurrentFileName, _T("%s\\%s"),tszRootDirectory, FindData.cFileName) == S_OK)
  523. {
  524. //LogEvent(_T("Main() Processing file: %s"), tszCurrentFileName);
  525. if (GetResponseURL(tszCurrentFileName)) // This function returns TRUE on success
  526. {
  527. RenameCabFile(tszCurrentFileName);
  528. }
  529. }
  530. }
  531. }
  532. } while (FindNextFile(hFindFile, &FindData));
  533. FindClose (hFindFile);
  534. }
  535. }
  536. }
  537. }
  538. Done:
  539. // we can jump here from inside the find file loop so if the handle is not closed close it.
  540. if (hFindFile != INVALID_HANDLE_VALUE)
  541. FindClose(hFindFile);
  542. CloseHandle(g_hStopEvent1);
  543. // We are done return up the chain.
  544. }
  545. int
  546. CServiceModule::SearchDirectory(TCHAR * tszDirectory)
  547. /*
  548. Function: SearchDirectory
  549. Purpose: Recursively search a series of directories to locate .cab files.
  550. When a .cab file is found calles GetResponseUrl to process the file.
  551. Parameters:
  552. in tszSearchDirectory - Directory in which to begin serarching for cab files.
  553. Returns:
  554. NONE
  555. */
  556. {
  557. // recursive function to search a directory for cab files.
  558. HANDLE hFindFile = INVALID_HANDLE_VALUE;
  559. WIN32_FIND_DATA FindData;
  560. TCHAR tszSearchDir[MAX_PATH];
  561. TCHAR tszSubDir[MAX_PATH];
  562. TCHAR *temp = NULL;
  563. int iRetCode = 0;
  564. HANDLE hStopEvent = NULL;
  565. TCHAR tszCurrentFileName[255];
  566. DWORD dwWaitResult = 0;
  567. int Status = 0;
  568. /* hStopEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, s_cszStopEvent);
  569. if (hStopEvent == NULL)
  570. {
  571. LogEvent(_T("Failed to open stop event. Terminating"));
  572. Status = 1;
  573. goto Done;
  574. }
  575. */
  576. if (StringCbCopy (tszSearchDir, sizeof tszSearchDir, tszDirectory) == S_OK)
  577. {
  578. if (StringCbCat (tszSearchDir, sizeof tszSearchDir, _T("\\*.*")) == S_OK)
  579. {
  580. //LogEvent(_T("Current Search Path: %s"), tszSearchDir);
  581. hFindFile = FindFirstFile(tszSearchDir, &FindData);
  582. if (hFindFile != INVALID_HANDLE_VALUE)
  583. {
  584. do
  585. {
  586. dwWaitResult = WaitForSingleObject(g_hStopEvent1, 200);
  587. switch (dwWaitResult)
  588. {
  589. case WAIT_OBJECT_0:
  590. // we're stopping return immediately
  591. Status = 1; // Signal the rest of the functions up the chain to stop.
  592. goto Done;
  593. break;
  594. case WAIT_FAILED:
  595. // we hit an error somewhere log the event and return
  596. LogEvent (_T(" Failed wait in recursive search: ErrorCode: %d"), GetLastError());
  597. Status = 1; // We have an unrecoverable failure shut down
  598. goto Done;
  599. break;
  600. default:
  601. break;
  602. }
  603. if (FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
  604. {
  605. // Skip the . and .. directories all directories trigger a recursive call
  606. if ( (_tcscmp (FindData.cFileName, _T("."))) && (_tcscmp (FindData.cFileName, _T(".."))) )
  607. {
  608. // We have another directory
  609. // recursively call this function with the new direcory name.
  610. if (StringCbPrintf(tszSubDir, sizeof tszSubDir, _T("%s\\%s"), tszDirectory, FindData.cFileName) == S_OK)
  611. {
  612. //LogEvent(_T("Recursively Searching subdir: %s"), tszSubDir);
  613. if (SearchDirectory(tszSubDir) == 1)
  614. {
  615. goto Done;
  616. }
  617. }
  618. }
  619. }
  620. else
  621. {
  622. // check to see if this file as a .cab extenstion
  623. temp = FindData.cFileName + _tcslen(FindData.cFileName) -3;
  624. //LogEvent(_T("Checking Extension on file: %s extension is: %s"), FindData.cFileName,temp);
  625. if (!_tcscmp (temp, _T("cab")))
  626. {
  627. // we have a cab. Now lets process it
  628. if (StringCbPrintf(tszCurrentFileName, sizeof tszCurrentFileName, _T("%s\\%s"),tszDirectory, FindData.cFileName) == S_OK)
  629. {
  630. //LogEvent(_T("Calling renamefile for: %s"), FindData.cFileName);
  631. RenameFile(tszDirectory, FindData.cFileName, tszCurrentFileName);
  632. //LogEvent(_T("NewFileName is: %s"),tszCurrentFileName);
  633. if (GetResponseURL(tszCurrentFileName)) // This function returns TRUE on success
  634. {
  635. RenameCabFile(tszCurrentFileName);
  636. }
  637. }
  638. }
  639. }
  640. } while (FindNextFile(hFindFile, &FindData));
  641. FindClose(hFindFile);
  642. }
  643. }
  644. }
  645. Done:
  646. // we can jump here from inside the find file loop so if the handle is not closed close it.
  647. if (hFindFile != INVALID_HANDLE_VALUE)
  648. FindClose(hFindFile);
  649. // CloseHandle(hStopEvent);
  650. return Status;
  651. // We are done return up the chain.
  652. }
  653. void
  654. CServiceModule::RenameCabFile(TCHAR * tFileName)
  655. /*
  656. Function: RenameCabFile
  657. Purpose: Rename a file from .cab to .old
  658. Parameters:
  659. in tFileName - Name of file to rename to .old
  660. Returns:
  661. NONE
  662. */
  663. {
  664. TCHAR tNewFileName[MAX_PATH];
  665. BOOL bSuccess = FALSE;
  666. int iStatus = 0;
  667. // Verify incomming pointer
  668. if (!tFileName)
  669. return;
  670. ZeroMemory(tNewFileName, sizeof tNewFileName);
  671. if(_tcslen(tFileName) < MAX_PATH)
  672. {
  673. if (StringCbCopy(tNewFileName, sizeof tNewFileName,tFileName) == S_OK)
  674. {
  675. if (StringCbCat(tNewFileName,sizeof tNewFileName, _T(".old")) == S_OK)
  676. {
  677. bSuccess = CopyFile(tFileName, tNewFileName, true);
  678. if(bSuccess)
  679. {
  680. bSuccess = DeleteFile(tFileName);
  681. if (!bSuccess)
  682. iStatus = -1;
  683. }
  684. else
  685. bSuccess = -1;
  686. }
  687. else
  688. bSuccess = -1;
  689. }
  690. else
  691. bSuccess = -1;
  692. }
  693. else
  694. bSuccess = -1;
  695. return;
  696. }
  697. BOOL
  698. CServiceModule::GetResponseURL(TCHAR *RemoteFileName)
  699. /*
  700. Function: GetResponseURL
  701. Purpose: Process the RemoteFileName file through the OCA System
  702. Parameters:
  703. in HostName - Name of IIS server hosting the OCA_Extension dll
  704. in RemoteFileName - Name of file to process.
  705. Returns:
  706. NONE
  707. */
  708. {
  709. HINTERNET hRedirUrl = NULL;
  710. HINTERNET hSession = NULL;
  711. TCHAR IsapiUrl[512];
  712. if (StringCbPrintfW(IsapiUrl, sizeof IsapiUrl, L"http://%s/isapi/oca_extension.dll?id=%s&Type=6",tszHostName, RemoteFileName) != S_OK)
  713. {
  714. return FALSE;
  715. }
  716. hSession = InternetOpenW(L"Stresssvc_Control", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  717. if (!hSession)
  718. {
  719. LogEvent(_T("Failed InternetOpenW"));
  720. return FALSE;
  721. }
  722. hRedirUrl = InternetOpenUrlW(hSession,
  723. IsapiUrl,
  724. NULL,
  725. 0,
  726. INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID,
  727. 0);
  728. if(!hRedirUrl)
  729. {
  730. InternetCloseHandle(hSession);
  731. LogEvent(_T("Failed InternetOpenW"));
  732. return FALSE;
  733. }
  734. InternetCloseHandle(hRedirUrl);
  735. InternetCloseHandle(hSession);
  736. return TRUE;
  737. }
  738. BOOL
  739. OpenRegFileFromCab(
  740. TCHAR *CabFile,
  741. HANDLE *FileHandle
  742. )
  743. {
  744. CHAR RegFile[2 * MAX_PATH];
  745. TCHAR *tszRegFile = NULL;
  746. PSTR AnsiFile = NULL;
  747. INT_PTR CabFh;
  748. HRESULT Status;
  749. #ifdef UNICODE
  750. if ((Status = WideToAnsi(CabFile, &AnsiFile)) != S_OK)
  751. {
  752. return FALSE;
  753. }
  754. #else
  755. AnsiFile = CabFile;
  756. #endif
  757. Status = ExpandDumpCab(AnsiFile,
  758. _O_CREAT | _O_EXCL | _O_TEMPORARY,
  759. "registry.txt",
  760. RegFile, DIMA(RegFile),
  761. &CabFh);
  762. if (Status != S_OK)
  763. {
  764. goto exitRegFileOpen;
  765. }
  766. #ifdef UNICODE
  767. if ((AnsiToWide(RegFile, &tszRegFile)) != S_OK)
  768. {
  769. goto exitRegFileOpen;
  770. }
  771. #else
  772. tszRegFile = RegFile;
  773. #endif
  774. *FileHandle = CreateFile(tszRegFile, GENERIC_READ,
  775. FILE_SHARE_READ | FILE_SHARE_WRITE |
  776. FILE_SHARE_DELETE,
  777. NULL,
  778. OPEN_EXISTING,
  779. FILE_ATTRIBUTE_NORMAL,
  780. NULL);
  781. if (*FileHandle == NULL || *FileHandle == INVALID_HANDLE_VALUE)
  782. {
  783. Status = E_FAIL;
  784. }
  785. if (CabFh >= 0)
  786. {
  787. // no longer needed
  788. _close((int)CabFh);
  789. }
  790. exitRegFileOpen:
  791. #ifdef UNICODE
  792. if (AnsiFile)
  793. {
  794. FreeAnsi(AnsiFile);
  795. }
  796. if (tszRegFile)
  797. {
  798. FreeWide(tszRegFile);
  799. }
  800. #endif
  801. return Status == S_OK;
  802. }
  803. BOOL
  804. GetStressId(
  805. HANDLE hRegFile,
  806. PULONG StressId
  807. )
  808. {
  809. const char cszStressIdTag[] = "StressID:(DWORD)";
  810. ULONG SizeLow, SizeHigh;
  811. SizeLow = GetFileSize(hRegFile, &SizeHigh);
  812. // Sanity check
  813. if (SizeHigh != 0 || SizeLow > 0x10000)
  814. {
  815. return FALSE;
  816. }
  817. PSTR szRegFile = (PSTR) malloc(SizeLow+1);
  818. ULONG BytesRead;
  819. if (!szRegFile)
  820. {
  821. return FALSE;
  822. }
  823. szRegFile[SizeLow] = 0;
  824. if (ReadFile(hRegFile, szRegFile, SizeLow, &BytesRead,
  825. NULL) == FALSE)
  826. {
  827. free (szRegFile);
  828. return FALSE;
  829. }
  830. PSTR szId;
  831. if (szId = strstr(szRegFile, cszStressIdTag))
  832. {
  833. szId += DIMA(cszStressIdTag);
  834. free (szRegFile);
  835. return sscanf(szId, "%lx", StressId);
  836. }
  837. free (szRegFile);
  838. return FALSE;
  839. }
  840. // Rename cab based on stressid contained in the reg.txt file in the cab
  841. BOOL
  842. RenameFile(TCHAR *CurrentPath,
  843. TCHAR *CurrentName,
  844. TCHAR *NewName)
  845. {
  846. BOOL Status = TRUE;
  847. HANDLE FileHandle;
  848. TCHAR CabFile[MAX_PATH];
  849. ULONG StressID;
  850. if (StringCbCopy(CabFile, sizeof(CabFile), CurrentPath) != S_OK ||
  851. StringCbCat(CabFile, sizeof(CabFile), _T("\\")) != S_OK ||
  852. StringCbCat(CabFile, sizeof(CabFile), CurrentName) != S_OK)
  853. {
  854. return FALSE;
  855. }
  856. // Rename cab based on stressid contained in the reg.txt file in the cab
  857. // Extract the reg.txt file.
  858. if (!OpenRegFileFromCab(CabFile, &FileHandle))
  859. {
  860. return FALSE;
  861. }
  862. // Get StressID(StressID)
  863. if ((Status = GetStressId(FileHandle, &StressID)) == FALSE)
  864. {
  865. return FALSE;
  866. }
  867. CloseHandle(FileHandle);
  868. // Build new file name
  869. TCHAR NewFileName[MAX_PATH];
  870. StringCbPrintf(NewFileName,sizeof (NewFileName),_T("%s\\%08lX_%s"), CurrentPath,StressID,CurrentName);
  871. if ((Status = CopyFile (CabFile, NewFileName, TRUE)) == TRUE)
  872. {
  873. Status = DeleteFile(CabFile);
  874. }
  875. StringCbCopy(NewName, 255 * sizeof TCHAR, NewFileName);
  876. return Status;
  877. }