Source code of Windows XP (NT5)
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.

1083 lines
26 KiB

  1. // emsvc.cpp : Implementation of WinMain
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f emsvcps.mk in the project directory.
  5. #include "stdafx.h"
  6. #include "resource.h"
  7. #include <initguid.h>
  8. #include "emsvc.h"
  9. #include "emsvc_i.c"
  10. #include <stdio.h>
  11. #include "EmManager.h"
  12. #include "EmDebugSession.h"
  13. #ifdef _DEBUG
  14. #define _CRTDBG_MAP_ALLOC
  15. #include <stdlib.h>
  16. #include <crtdbg.h>
  17. #endif
  18. #include "EmFile.h"
  19. CServiceModule _Module;
  20. BEGIN_OBJECT_MAP(ObjectMap)
  21. OBJECT_ENTRY(CLSID_EmManager, CEmManager)
  22. OBJECT_ENTRY(CLSID_EmDebugSession, CEmDebugSession)
  23. OBJECT_ENTRY(CLSID_EmFile, CEmFile)
  24. END_OBJECT_MAP()
  25. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  26. {
  27. while (p1 != NULL && *p1 != NULL)
  28. {
  29. LPCTSTR p = p2;
  30. while (p != NULL && *p != NULL)
  31. {
  32. if (*p1 == *p)
  33. return CharNext(p1);
  34. p = CharNext(p);
  35. }
  36. p1 = CharNext(p1);
  37. }
  38. return NULL;
  39. }
  40. // Although some of these functions are big they are declared inline since they are only used once
  41. inline HRESULT CServiceModule::RegisterServer(BOOL bRegTypeLib, BOOL bService)
  42. {
  43. ATLTRACE(_T("CServiceModule::RegisterServer\n"));
  44. HRESULT hr = CoInitialize(NULL);
  45. if (FAILED(hr))
  46. return hr;
  47. // Remove any previous service since it may point to
  48. // the incorrect file
  49. Uninstall();
  50. // Add service entries
  51. UpdateRegistryFromResource(IDR_Emsvc, TRUE);
  52. // Adjust the AppID for Local Server or Service
  53. CRegKey keyAppID;
  54. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
  55. if (lRes != ERROR_SUCCESS)
  56. return lRes;
  57. CRegKey key;
  58. lRes = key.Open(keyAppID, _T("{D48CD754-320F-4DCF-8CDA-7318CB03837D}"), KEY_WRITE);
  59. if (lRes != ERROR_SUCCESS)
  60. return lRes;
  61. key.DeleteValue(_T("LocalService"));
  62. if (bService)
  63. {
  64. key.SetValue(_T("emsvc"), _T("LocalService"));
  65. key.SetValue(_T("-Service"), _T("ServiceParameters"));
  66. // Create service
  67. Install();
  68. }
  69. // Add object entries
  70. hr = CComModule::RegisterServer(bRegTypeLib);
  71. CoUninitialize();
  72. return hr;
  73. }
  74. inline HRESULT CServiceModule::UnregisterServer()
  75. {
  76. ATLTRACE(_T("CServiceModule::UnregisterServer\n"));
  77. HRESULT hr = CoInitialize(NULL);
  78. if (FAILED(hr))
  79. return hr;
  80. // Remove service entries
  81. UpdateRegistryFromResource(IDR_Emsvc, 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. ATLTRACE(_T("CServiceModule::Init\n"));
  92. CComModule::Init(p, h, plibid);
  93. m_bService = TRUE;
  94. LoadString(h, nServiceNameID, m_szServiceName, sizeof(m_szServiceName) / sizeof(TCHAR));
  95. // set up the initial service status
  96. m_hServiceStatus = NULL;
  97. m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  98. m_status.dwCurrentState = SERVICE_STOPPED;
  99. m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  100. m_status.dwWin32ExitCode = 0;
  101. m_status.dwServiceSpecificExitCode = 0;
  102. m_status.dwCheckPoint = 0;
  103. m_status.dwWaitHint = 0;
  104. }
  105. LONG CServiceModule::Unlock()
  106. {
  107. ATLTRACE(_T("CServiceModule::Unlock\n"));
  108. LONG l = CComModule::Unlock();
  109. if (l == 0 && !m_bService)
  110. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  111. ATLTRACE(_T("CServiceModule::Unlock - Lock count l = %d\n"), l);
  112. return l;
  113. }
  114. BOOL CServiceModule::IsInstalled()
  115. {
  116. ATLTRACE(_T("CServiceModule::IsInstalled\n"));
  117. BOOL bResult = FALSE;
  118. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  119. if (hSCM != NULL)
  120. {
  121. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
  122. if (hService != NULL)
  123. {
  124. bResult = TRUE;
  125. ::CloseServiceHandle(hService);
  126. }
  127. ::CloseServiceHandle(hSCM);
  128. }
  129. return bResult;
  130. }
  131. inline BOOL CServiceModule::Install()
  132. {
  133. ATLTRACE(_T("CServiceModule::Install\n"));
  134. if (IsInstalled())
  135. return TRUE;
  136. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  137. if (hSCM == NULL)
  138. {
  139. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  140. return FALSE;
  141. }
  142. // Get the executable file path
  143. TCHAR szFilePath[_MAX_PATH];
  144. ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
  145. SC_HANDLE hService = ::CreateService(
  146. hSCM, m_szServiceName, m_szServiceName,
  147. SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  148. SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
  149. szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
  150. if (hService == NULL)
  151. {
  152. ::CloseServiceHandle(hSCM);
  153. MessageBox(NULL, _T("Couldn't create service"), m_szServiceName, MB_OK);
  154. return FALSE;
  155. }
  156. ::CloseServiceHandle(hService);
  157. ::CloseServiceHandle(hSCM);
  158. return TRUE;
  159. }
  160. inline BOOL CServiceModule::Uninstall()
  161. {
  162. ATLTRACE(_T("CServiceModule::Uninstall\n"));
  163. if (!IsInstalled())
  164. return TRUE;
  165. SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  166. if (hSCM == NULL)
  167. {
  168. MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
  169. return FALSE;
  170. }
  171. SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_STOP | DELETE);
  172. if (hService == NULL)
  173. {
  174. ::CloseServiceHandle(hSCM);
  175. MessageBox(NULL, _T("Couldn't open service"), m_szServiceName, MB_OK);
  176. return FALSE;
  177. }
  178. SERVICE_STATUS status;
  179. ::ControlService(hService, SERVICE_CONTROL_STOP, &status);
  180. BOOL bDelete = ::DeleteService(hService);
  181. ::CloseServiceHandle(hService);
  182. ::CloseServiceHandle(hSCM);
  183. if (bDelete)
  184. return TRUE;
  185. MessageBox(NULL, _T("Service could not be deleted"), m_szServiceName, MB_OK);
  186. return FALSE;
  187. }
  188. ///////////////////////////////////////////////////////////////////////////////////////
  189. // Logging functions
  190. void CServiceModule::LogEvent(LPCTSTR pFormat, ...)
  191. {
  192. ATLTRACE(_T("CServiceModule::LogEvent\n"));
  193. TCHAR chMsg[256];
  194. HANDLE hEventSource;
  195. LPTSTR lpszStrings[1];
  196. va_list pArg;
  197. va_start(pArg, pFormat);
  198. _vstprintf(chMsg, pFormat, pArg);
  199. va_end(pArg);
  200. lpszStrings[0] = chMsg;
  201. if (m_bService)
  202. {
  203. /* Get a handle to use with ReportEvent(). */
  204. hEventSource = RegisterEventSource(NULL, m_szServiceName);
  205. if (hEventSource != NULL)
  206. {
  207. /* Write to event log. */
  208. ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  209. DeregisterEventSource(hEventSource);
  210. }
  211. }
  212. else
  213. {
  214. // As we are not running as a service, just write the error to the console.
  215. _putts(chMsg);
  216. }
  217. }
  218. //////////////////////////////////////////////////////////////////////////////////////////////
  219. // Service startup and registration
  220. inline void CServiceModule::Start()
  221. {
  222. ATLTRACE(_T("CServiceModule::Start\n"));
  223. SERVICE_TABLE_ENTRY st[] =
  224. {
  225. { m_szServiceName, _ServiceMain },
  226. { NULL, NULL }
  227. };
  228. if (m_bService && !::StartServiceCtrlDispatcher(st))
  229. {
  230. m_bService = FALSE;
  231. }
  232. if (m_bService == FALSE)
  233. Run();
  234. }
  235. inline void CServiceModule::ServiceMain(DWORD /* dwArgc */, LPTSTR* /* lpszArgv */)
  236. {
  237. ATLTRACE(_T("CServiceModule::ServiceMain\n"));
  238. // Register the control request handler
  239. m_status.dwCurrentState = SERVICE_START_PENDING;
  240. m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
  241. if (m_hServiceStatus == NULL)
  242. {
  243. LogEvent(_T("Handler not installed"));
  244. return;
  245. }
  246. SetServiceStatus(SERVICE_START_PENDING);
  247. m_status.dwWin32ExitCode = S_OK;
  248. m_status.dwCheckPoint = 0;
  249. m_status.dwWaitHint = 0;
  250. // When the Run function returns, the service has stopped.
  251. Run();
  252. SetServiceStatus(SERVICE_STOPPED);
  253. LogEvent(_T("Service stopped"));
  254. }
  255. inline void CServiceModule::Handler(DWORD dwOpcode)
  256. {
  257. ATLTRACE(_T("CServiceModule::Handler\n"));
  258. switch (dwOpcode)
  259. {
  260. case SERVICE_CONTROL_STOP:
  261. SetServiceStatus(SERVICE_STOP_PENDING);
  262. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  263. break;
  264. case SERVICE_CONTROL_PAUSE:
  265. break;
  266. case SERVICE_CONTROL_CONTINUE:
  267. break;
  268. case SERVICE_CONTROL_INTERROGATE:
  269. break;
  270. case SERVICE_CONTROL_SHUTDOWN:
  271. break;
  272. default:
  273. LogEvent(_T("Bad service request"));
  274. }
  275. }
  276. void WINAPI CServiceModule::_ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
  277. {
  278. _Module.ServiceMain(dwArgc, lpszArgv);
  279. }
  280. void WINAPI CServiceModule::_Handler(DWORD dwOpcode)
  281. {
  282. _Module.Handler(dwOpcode);
  283. }
  284. void CServiceModule::SetServiceStatus(DWORD dwState)
  285. {
  286. m_status.dwCurrentState = dwState;
  287. ::SetServiceStatus(m_hServiceStatus, &m_status);
  288. }
  289. void CServiceModule::Run()
  290. {
  291. ATLTRACE(_T("CServiceModule::Run - Begin\n"));
  292. _Module.dwThreadID = GetCurrentThreadId();
  293. if(FAILED(GetEmFilePath( EMOBJ_LOGFILE, m_bstrLogFilePath ))) {
  294. LogEvent(_T("%s"), _T("Log file path not present."));
  295. return;
  296. }
  297. m_bstrLogFileExt = _T ( ".dbl" );
  298. if(FAILED(GetEmFilePath( EMOBJ_MINIDUMP, m_bstrDumpFilePath ))) {
  299. LogEvent(_T("%s"), _T("Dump file path not present."));
  300. }
  301. m_bstrDumpFileExt = _T ( ".dmp" );
  302. if(FAILED(GetEmFilePath( EMOBJ_CMDSET, m_bstrEcxFilePath ))) {
  303. LogEvent(_T("%s"), _T("Ecx file path not present in the registry. Was unable to create one."));
  304. }
  305. m_bstrEcxFileExt = _T( ".ecx" ); //GetEmFileExt( EMOBJ_CMDSET );
  306. if(FAILED(GetEmFilePath( EMOBJ_MSINFO, m_bstrMsInfoFilePath ))) {
  307. LogEvent(_T("%s"), _T("MsInfo file path not present in the registry. Was unable to create one."));
  308. }
  309. m_bstrMsInfoFileExt = _T( ".nfo" ); //GetEmFileExt( EMOBJ_CMDSET );
  310. m_SessionManager.InitSessionsFromLog( _T("EmSess.log"), STAT_SESS_STOPPED);
  311. HRESULT hr = CoInitialize(NULL);
  312. // If you are running on NT 4.0 or higher you can use the following call
  313. // instead to make the EXE free threaded.
  314. // This means that calls come in on a random RPC thread
  315. //HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  316. _ASSERTE(SUCCEEDED(hr));
  317. // This provides a NULL DACL which will allow access to everyone.
  318. CSecurityDescriptor sd;
  319. sd.InitializeFromThreadToken();
  320. hr = CoInitializeSecurity(sd, -1, NULL, NULL,
  321. RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
  322. _ASSERTE(SUCCEEDED(hr));
  323. hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER+CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
  324. _ASSERTE(SUCCEEDED(hr));
  325. LogEvent(_T("Service started"));
  326. if (m_bService)
  327. SetServiceStatus(SERVICE_RUNNING);
  328. MSG msg;
  329. while (GetMessage(&msg, 0, 0, 0))
  330. DispatchMessage(&msg);
  331. m_SessionManager.PersistSessions(_T("EmSess.log"));
  332. _Module.RevokeClassObjects();
  333. m_SessionManager.StopAllThreads();
  334. ATLTRACE(_T("CServiceModule::Run - before CoUninitialize \n"));
  335. CoUninitialize();
  336. ATLTRACE(_T("CServiceModule::Run - After CoUninitialize\n"));
  337. }
  338. /////////////////////////////////////////////////////////////////////////////
  339. //
  340. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
  341. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  342. {
  343. ATLTRACE(_T("WinManin::lpCmdLine = %s\n"), lpCmdLine);
  344. lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
  345. _Module.Init(ObjectMap, hInstance, IDS_SERVICENAME, &LIBID_EMSVCLib);
  346. _Module.m_bService = TRUE;
  347. #ifdef _DEBUG
  348. _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_CRT_DF );
  349. #endif
  350. TCHAR szTokens[] = _T("-/");
  351. LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
  352. while (lpszToken != NULL)
  353. {
  354. if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
  355. return _Module.UnregisterServer();
  356. // Register as Local Server
  357. if (lstrcmpi(lpszToken, _T("RegServer"))==0)
  358. return _Module.RegisterServer(TRUE, FALSE);
  359. // Register as Service
  360. if (lstrcmpi(lpszToken, _T("Service"))==0)
  361. return _Module.RegisterServer(TRUE, TRUE);
  362. lpszToken = FindOneOf(lpszToken, szTokens);
  363. }
  364. // Are we Service or Local Server
  365. CRegKey keyAppID;
  366. LONG lRes = keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_READ);
  367. if (lRes != ERROR_SUCCESS)
  368. return lRes;
  369. CRegKey key;
  370. lRes = key.Open(keyAppID, _T("{D48CD754-320F-4DCF-8CDA-7318CB03837D}"), KEY_READ);
  371. if (lRes != ERROR_SUCCESS)
  372. return lRes;
  373. TCHAR szValue[_MAX_PATH];
  374. DWORD dwLen = _MAX_PATH;
  375. lRes = key.QueryValue(szValue, _T("LocalService"), &dwLen);
  376. _Module.m_bService = FALSE;
  377. if (lRes == ERROR_SUCCESS)
  378. _Module.m_bService = TRUE;
  379. _Module.Start();
  380. ATLTRACE(_T("WinManin:: Service Stop\n"));
  381. // When we get here, the service has been stopped
  382. return _Module.m_status.dwWin32ExitCode;
  383. }
  384. HRESULT
  385. CServiceModule::GetEmDirectory
  386. (
  387. EmObjectType eObjectType,
  388. LPTSTR pszDirectory,
  389. LONG cchDirectory,
  390. LPTSTR pszExt,
  391. LONG cchExt
  392. )
  393. {
  394. ATLTRACE(_T("CServiceModule::GetEmDirectory - EmObjectType = %d\n"), eObjectType);
  395. HRESULT hr = S_OK;
  396. LPCTSTR pszSrcDirectory = NULL;
  397. LPCTSTR pszSrcExt = NULL;
  398. switch ( eObjectType ) {
  399. case EMOBJ_LOGFILE:
  400. pszSrcDirectory = m_bstrLogFilePath;
  401. pszSrcExt = m_bstrLogFileExt;
  402. break;
  403. case EMOBJ_MINIDUMP:
  404. case EMOBJ_USERDUMP:
  405. pszSrcDirectory = m_bstrDumpFilePath;
  406. pszSrcExt = m_bstrDumpFileExt;
  407. break;
  408. case EMOBJ_CMDSET:
  409. pszSrcDirectory = m_bstrEcxFilePath;
  410. pszSrcExt = m_bstrEcxFileExt;
  411. break;
  412. case EMOBJ_MSINFO:
  413. pszSrcDirectory = m_bstrMsInfoFilePath;
  414. pszSrcExt = m_bstrMsInfoFileExt;
  415. break;
  416. default:
  417. hr = E_FAIL;
  418. }
  419. if ( SUCCEEDED(hr) ) {
  420. if ( pszDirectory && pszSrcDirectory ) // a-kjaw, bug ID: 296022
  421. _tcsncpy ( pszDirectory, pszSrcDirectory, cchDirectory );
  422. if ( pszExt && pszSrcExt ) // a-kjaw, bug ID: 296021
  423. _tcsncpy ( pszExt, pszSrcExt, cchExt );
  424. }
  425. return (hr);
  426. }
  427. void __stdcall _com_issue_error( HRESULT hr )
  428. {
  429. throw _com_error ( hr );
  430. }
  431. HRESULT
  432. CServiceModule::GetPathFromReg
  433. (
  434. IN HKEY hKeyParent,
  435. IN LPCTSTR lpszKeyName,
  436. IN LPCTSTR lpszQueryKey,
  437. OUT LPTSTR pszDirectory,
  438. IN OUT ULONG *cchDirectory
  439. )
  440. {
  441. ATLTRACE(_T("CServiceModule::GetPathFromReg\n"));
  442. HRESULT hr = E_FAIL;
  443. DWORD dwLastRet = 0L;
  444. CRegKey registry;
  445. do {
  446. dwLastRet = registry.Open(hKeyParent, lpszKeyName, KEY_READ);
  447. if(dwLastRet != ERROR_SUCCESS) {
  448. hr = HRESULT_FROM_WIN32(dwLastRet);
  449. break;
  450. }
  451. dwLastRet = registry.QueryValue(pszDirectory, lpszQueryKey, cchDirectory);
  452. hr = HRESULT_FROM_WIN32(dwLastRet);
  453. }
  454. while( false );
  455. if(HKEY(registry) != NULL) {
  456. registry.Close();
  457. }
  458. return S_OK;
  459. }
  460. HRESULT
  461. CServiceModule::CreateEmDirectory
  462. (
  463. IN OUT LPTSTR lpDirName,
  464. IN LONG ccDirName,
  465. IN LPCTSTR lpParentDirPath
  466. )
  467. {
  468. ATLTRACE(_T("CServiceModule::CreateEmDirectory\n"));
  469. HRESULT hr = S_OK;
  470. DWORD dwLastRet = 0L;
  471. TCHAR szDirPath[_MAX_PATH] = _T("");
  472. LONG ccDirPath = _MAX_PATH;
  473. do {
  474. if( lpDirName == NULL ) {
  475. hr = E_INVALIDARG;
  476. break;
  477. }
  478. if( GetCurrentDirectory( ccDirPath, szDirPath ) == 0 ) {
  479. hr = HRESULT_FROM_WIN32(GetLastError());
  480. break;
  481. }
  482. if( !lpParentDirPath ) { lpParentDirPath = szDirPath; }
  483. _stprintf( szDirPath, _T("%s\\%s"), lpParentDirPath, lpDirName );
  484. CreateDirectory( szDirPath, NULL );
  485. dwLastRet = GetLastError();
  486. if( dwLastRet != 0 && dwLastRet != ERROR_ALREADY_EXISTS ) {
  487. hr = HRESULT_FROM_WIN32(dwLastRet);
  488. break;
  489. }
  490. _tcsncpy( lpDirName, szDirPath, ccDirName );
  491. hr = S_OK;
  492. }
  493. while ( false );
  494. return hr;
  495. }
  496. HRESULT
  497. CServiceModule::RegisterDir
  498. (
  499. IN HKEY hKeyParent,
  500. IN LPCTSTR lpszKeyName,
  501. IN LPCTSTR lpszNamedValue,
  502. IN LPCTSTR lpValue
  503. )
  504. {
  505. ATLTRACE(_T("CServiceModule::RegisterDir\n"));
  506. HRESULT hr = E_FAIL;
  507. CRegKey registry;
  508. do {
  509. if( registry.Create(hKeyParent, lpszKeyName) != ERROR_SUCCESS ) {
  510. hr = HRESULT_FROM_WIN32(GetLastError());
  511. break;
  512. }
  513. if( registry.SetValue( lpValue, lpszNamedValue ) != ERROR_SUCCESS ) {
  514. hr = HRESULT_FROM_WIN32(GetLastError());
  515. break;
  516. }
  517. hr = S_OK;
  518. }
  519. while( false );
  520. if( HKEY(registry) != NULL ) {
  521. registry.Close();
  522. }
  523. return hr;
  524. }
  525. HRESULT
  526. CServiceModule::CreateEmDirAndRegister
  527. (
  528. IN OUT LPTSTR lpDirName,
  529. IN LONG ccDirName,
  530. IN HKEY hKeyParent,
  531. IN LPCTSTR lpszKeyName,
  532. IN LPCTSTR lpszNamedValue
  533. )
  534. {
  535. ATLTRACE(_T("CServiceModule::CreateEmDirAndRegister\n"));
  536. HRESULT hr = E_FAIL;
  537. hr = CreateEmDirectory( lpDirName, ccDirName );
  538. if( FAILED(hr) ) return hr;
  539. hr = RegisterDir( hKeyParent, lpszKeyName, lpszNamedValue, lpDirName );
  540. return hr;
  541. }
  542. HRESULT
  543. CServiceModule::GetEmFilePath
  544. (
  545. IN short nFileType,
  546. OUT bstr_t& bstrFilePath
  547. )
  548. {
  549. ATLTRACE(_T("CServiceModule::GetEmFilePath\n"));
  550. HRESULT hr = E_FAIL;
  551. TCHAR szDirectory[_MAX_PATH+1] = _T("");
  552. ULONG lDirectory = _MAX_PATH;
  553. LPCTSTR lpValueName = NULL;
  554. LPCTSTR lpDir = NULL;
  555. bstrFilePath = _T("");
  556. switch( nFileType )
  557. {
  558. case EMOBJ_LOGFILE:
  559. lpValueName = _T("LogDir");
  560. lpDir = _T("Logs");
  561. break;
  562. case EMOBJ_MINIDUMP:
  563. case EMOBJ_USERDUMP:
  564. lpValueName = _T("DumpDir");
  565. lpDir = _T("Dump");
  566. break;
  567. case EMOBJ_CMDSET:
  568. lpValueName = _T("CmdDir");
  569. lpDir = _T("Ecx");
  570. break;
  571. case EMOBJ_MSINFO:
  572. lpValueName = _T("MSInfoDir");
  573. lpDir = _T("MSInfo");
  574. break;
  575. }
  576. hr = GetPathFromReg (
  577. HKEY_LOCAL_MACHINE,
  578. _T("SYSTEM\\currentcontrolset\\services\\EMSVC\\Parameters\\Session"),
  579. lpValueName,
  580. szDirectory,
  581. &lDirectory
  582. );
  583. if( _tcscmp(szDirectory, _T("")) == 0 ) {
  584. _tcscpy(szDirectory, lpDir);
  585. lDirectory = _MAX_PATH;
  586. hr = CreateEmDirAndRegister(
  587. szDirectory,
  588. lDirectory,
  589. HKEY_LOCAL_MACHINE,
  590. _T("SYSTEM\\CurrentControlSet\\Services\\EMSVC\\Parameters\\Session"),
  591. lpValueName
  592. );
  593. }
  594. else {
  595. //
  596. // Just try to create the directory once,
  597. // if it is already present, this api returns
  598. // an error..
  599. //
  600. CreateDirectory( (LPTSTR)szDirectory, NULL );
  601. }
  602. if(SUCCEEDED(hr)) bstrFilePath = szDirectory;
  603. return hr;
  604. }
  605. bool
  606. CServiceModule::DateFromTm
  607. (
  608. IN WORD wYear,
  609. IN WORD wMonth,
  610. IN WORD wDay,
  611. IN WORD wHour,
  612. IN WORD wMinute,
  613. IN WORD wSecond,
  614. OUT DATE& dtDest
  615. )
  616. {
  617. // Validate year and month (ignore day of week and milliseconds)
  618. if (wYear > 9999 || wMonth < 1 || wMonth > 12)
  619. return false;
  620. // Check for leap year and set the number of days in the month
  621. BOOL bLeapYear = ((wYear & 3) == 0) &&
  622. ((wYear % 100) != 0 || (wYear % 400) == 0);
  623. int nDaysInMonth =
  624. MonthDays[wMonth] - MonthDays[wMonth-1] +
  625. ((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);
  626. // Finish validating the date
  627. if (wDay < 1 || wDay > nDaysInMonth ||
  628. wHour > 23 || wMinute > 59 ||
  629. wSecond > 59)
  630. {
  631. return FALSE;
  632. }
  633. // Cache the date in days and time in fractional days
  634. long nDate;
  635. double dblTime;
  636. //It is a valid date; make Jan 1, 1AD be 1
  637. nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
  638. MonthDays[wMonth-1] + wDay;
  639. // If leap year and it's before March, subtract 1:
  640. if (wMonth <= 2 && bLeapYear)
  641. --nDate;
  642. // Offset so that 12/30/1899 is 0
  643. nDate -= 693959L;
  644. dblTime = (((long)wHour * 3600L) + // hrs in seconds
  645. ((long)wMinute * 60L) + // mins in seconds
  646. ((long)wSecond)) / 86400.;
  647. dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);
  648. return TRUE;
  649. }
  650. DATE
  651. CServiceModule::GetCurrentTime()
  652. {
  653. time_t timeSrc = ::time(NULL);
  654. DATE dt;
  655. // Convert time_t to struct tm
  656. tm *ptm = localtime(&timeSrc);
  657. if (ptm != NULL)
  658. {
  659. DateFromTm(
  660. (WORD)(ptm->tm_year + 1900),
  661. (WORD)(ptm->tm_mon + 1),
  662. (WORD)ptm->tm_mday,
  663. (WORD)ptm->tm_hour,
  664. (WORD)ptm->tm_min,
  665. (WORD)ptm->tm_sec,
  666. dt
  667. );
  668. }
  669. return dt;
  670. }
  671. DATE
  672. CServiceModule::GetDateFromFileTm
  673. (
  674. IN const FILETIME& filetimeSrc
  675. )
  676. {
  677. DATE dt = 0L;
  678. // Assume UTC FILETIME, so convert to LOCALTIME
  679. FILETIME filetimeLocal;
  680. if (!FileTimeToLocalFileTime( &filetimeSrc, &filetimeLocal)){ return (dt = 0L); }
  681. // Take advantage of SYSTEMTIME -> FILETIME conversion
  682. SYSTEMTIME systime;
  683. if(!FileTimeToSystemTime(&filetimeLocal, &systime)) { return (dt = 0L); }
  684. CServiceModule::DateFromTm(
  685. (WORD)(systime.wYear),
  686. (WORD)(systime.wMonth),
  687. (WORD)systime.wDay,
  688. (WORD)systime.wHour,
  689. (WORD)systime.wMinute,
  690. (WORD)systime.wSecond,
  691. dt
  692. );
  693. return dt;
  694. }
  695. HRESULT
  696. CServiceModule::GetTempEmFileName
  697. (
  698. IN short nObjType,
  699. OUT BSTR &bstrFileName
  700. )
  701. {
  702. HRESULT hr = E_FAIL;
  703. LPCTSTR lpszFileName = NULL;
  704. TCHAR szFilePath[_MAX_PATH + 1] = _T(""),
  705. szFileName[_MAX_FNAME + 1] = _T(""),
  706. szFileExt[_MAX_EXT + 1] = _T("");
  707. TCHAR szId[100] = _T(""); //
  708. DWORD dwBuffSize = 0L;
  709. __try
  710. {
  711. switch( nObjType )
  712. {
  713. case EMOBJ_MSINFO:
  714. lpszFileName = _T("MSInfo");
  715. break;
  716. }
  717. bstrFileName = NULL;
  718. hr = _Module.GetEmDirectory( EMOBJ_MSINFO, szFilePath, _MAX_PATH, szFileExt, _MAX_EXT );
  719. if( FAILED(hr) ) { goto qGetFileName; }
  720. CreateDirectory( szFilePath, NULL );
  721. // path\\filename_id.ext
  722. _stprintf( szFileName, _T("%s\\%s_%d%s"), szFilePath, lpszFileName, GetEmUniqueId(), szFileExt );
  723. bstrFileName = SysAllocString( szFileName );
  724. if( !bstrFileName ) { hr = E_OUTOFMEMORY; goto qGetFileName; }
  725. hr = S_OK;
  726. qGetFileName:
  727. if( FAILED(hr) ) {}
  728. }
  729. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  730. hr = E_UNEXPECTED;
  731. _ASSERTE( false );
  732. }
  733. return hr;
  734. }
  735. HRESULT
  736. CServiceModule::GetCompName
  737. (
  738. OUT BSTR &bstrCompName
  739. )
  740. {
  741. HRESULT hr = E_FAIL;
  742. TCHAR szMachineName[MAX_COMPUTERNAME_LENGTH] = _T("");
  743. DWORD dwBuffSize = MAX_COMPUTERNAME_LENGTH;
  744. __try
  745. {
  746. dwBuffSize = MAX_COMPUTERNAME_LENGTH;
  747. if( !GetComputerName( szMachineName, &dwBuffSize ) ) {
  748. hr = HRESULT_FROM_WIN32( GetLastError() );
  749. goto qGetCompName;
  750. }
  751. bstrCompName = SysAllocString( szMachineName );
  752. if( !bstrCompName ) { hr = E_OUTOFMEMORY; goto qGetCompName; }
  753. hr = S_OK;
  754. qGetCompName:
  755. if( FAILED(hr) ) {}
  756. }
  757. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  758. hr = E_UNEXPECTED;
  759. _ASSERTE( false );
  760. }
  761. return hr;
  762. }
  763. HRESULT
  764. CServiceModule::GetCDBInstallDir
  765. (
  766. OUT LPTSTR lpCdbDir,
  767. IN ULONG *pccCdbDir
  768. )
  769. {
  770. return GetEmInstallDir( lpCdbDir, pccCdbDir );
  771. }
  772. HRESULT
  773. CServiceModule::GetEmInstallDir
  774. (
  775. OUT LPTSTR lpEmDir,
  776. IN OUT ULONG *pccEmDir
  777. )
  778. {
  779. HRESULT hr = E_FAIL;
  780. LPCTSTR lpValueName = _T("EmDir");
  781. __try
  782. {
  783. if( !lpEmDir || *pccEmDir <= 0 ) { hr = E_INVALIDARG; goto qGetEmInstallDir; }
  784. hr = GetPathFromReg (
  785. HKEY_LOCAL_MACHINE,
  786. _T("SYSTEM\\currentcontrolset\\services\\EMSVC\\Parameters\\Session"),
  787. lpValueName,
  788. lpEmDir,
  789. pccEmDir
  790. );
  791. if( FAILED(hr) ) { goto qGetEmInstallDir; }
  792. hr = S_OK;
  793. qGetEmInstallDir:
  794. if( FAILED(hr) ) { }
  795. }
  796. __except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
  797. hr = E_UNEXPECTED;
  798. _ASSERTE( false );
  799. }
  800. return hr;
  801. }
  802. HRESULT
  803. CServiceModule::GetMsInfoPath
  804. (
  805. OUT LPTSTR lpMsInfoPath,
  806. IN OUT ULONG *pccMsInfoPath
  807. )
  808. {
  809. LPCTSTR lpszMsInfoRegKey = _T("Software\\Microsoft\\Shared Tools\\MSInfo");
  810. LPCTSTR lpszPath = _T("Path");
  811. return GetPathFromReg(
  812. HKEY_LOCAL_MACHINE,
  813. lpszMsInfoRegKey,
  814. lpszPath,
  815. lpMsInfoPath,
  816. pccMsInfoPath
  817. );
  818. }
  819. HRESULT
  820. CServiceModule::GetOsVersion
  821. (
  822. OUT DWORD *pdwOsVer
  823. )
  824. {
  825. _ASSERTE( pdwOsVer != NULL );
  826. HRESULT hr = E_FAIL;
  827. OSVERSIONINFO osvi;
  828. ZeroMemory( (void *)&osvi, sizeof(OSVERSIONINFO) );
  829. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  830. if( !GetVersionEx (&osvi) ) {
  831. hr = HRESULT_FROM_WIN32(GetLastError());
  832. goto qGetOsVersion;
  833. }
  834. if( osvi.dwPlatformId & VER_PLATFORM_WIN32_NT ) {
  835. if( osvi.dwMajorVersion == 4 &&
  836. osvi.dwMinorVersion == 0 ) {
  837. *pdwOsVer = WINOS_NT4;
  838. }
  839. else if( osvi.dwMajorVersion == 5 &&
  840. osvi.dwMinorVersion == 0 ) {
  841. *pdwOsVer = WINOS_WIN2K;
  842. }
  843. }
  844. hr = S_OK;
  845. qGetOsVersion:
  846. if( FAILED(hr) ) { if( pdwOsVer ) *pdwOsVer = 0L; }
  847. return hr;
  848. }