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.

881 lines
29 KiB

  1. /*---------------------------------------------------------------------------
  2. File: DCTInstaller.cpp
  3. Comments: implementation of COM object that installs the DCT agent service.
  4. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  5. Proprietary and confidential to Mission Critical Software, Inc.
  6. REVISION LOG ENTRY
  7. Revision By: Christy Boles
  8. Revised on 02/18/99 11:34:16
  9. ---------------------------------------------------------------------------
  10. */
  11. // DCTInstaller.cpp : Implementation of CDCTInstaller
  12. #include "stdafx.h"
  13. //#include "McsDispatcher.h"
  14. #include "Dispatch.h"
  15. #include "DInst.h"
  16. #include "Common.hpp"
  17. #include "Err.hpp"
  18. #include "ErrDct.hpp"
  19. #include "UString.hpp"
  20. #include "QProcess.hpp"
  21. #include "IsAdmin.hpp"
  22. #include "TSync.hpp"
  23. #include "TReg.hpp"
  24. #include "TInst.h"
  25. #include "TFile.hpp"
  26. #include "ResStr.h"
  27. #include "sd.hpp"
  28. #include "CommaLog.hpp"
  29. #include "folders.h"
  30. using namespace nsFolders;
  31. #include <lm.h>
  32. //#import "\bin\McsVarSetMin.tlb" no_namespace
  33. #import "VarSet.tlb" no_namespace rename("property", "aproperty")
  34. TErrorDct err;
  35. TError & errCommon = err;
  36. StringLoader gString;
  37. extern TErrorDct errLog;
  38. #ifdef OFA
  39. #define AGENT_EXE L"OFAAgent.exe"
  40. #define SERVICE_EXE L"OFAAgentService.exe"
  41. #else
  42. #define AGENT_EXE GET_STRING(IDS_AGENT_EXE)
  43. #define SERVICE_EXE GET_STRING(IDS_SERVICE_EXE)
  44. #endif
  45. #define MSVCP60_DLL GET_STRING(IDS_MSVCP60_DLL)
  46. #define WORKER_DLL GET_STRING(IDS_WORKER_DLL)
  47. #define VARSET_DLL GET_STRING(IDS_VARSET_DLL)
  48. #define DATA_FILE GET_STRING(IDS_DATA_FILE)
  49. #define RESOURCE_DLL L"McsDmRes.dll"
  50. #define MESSAGE_DLL L"McsDmMsg.dll"
  51. #define CACHE_FILE L"DCTCache"
  52. #define AGENT_INTEL_DIR GET_STRING(IDS_AGENT_INTEL_DIR)
  53. #define AGENT_ALPHA_DIR GET_STRING(IDS_AGENT_ALPHA_DIR)
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CDCTInstaller
  56. namespace {
  57. class workerDeleteFile {
  58. _bstr_t m_strFile;
  59. public:
  60. workerDeleteFile(_bstr_t strFile):m_strFile(strFile)
  61. {}
  62. ~workerDeleteFile()
  63. { ::DeleteFile(m_strFile); }
  64. };
  65. union Time {
  66. FILETIME m_stFileTime;
  67. LONGLONG m_llTime;
  68. };
  69. bool IsServiceInstalling(_bstr_t sDirSysTgt, _bstr_t strTemp1, _bstr_t strTemp2)
  70. {
  71. bool bRes = false;
  72. HANDLE hFind;
  73. WIN32_FIND_DATA findData1;
  74. if((hFind = FindFirstFile(strTemp1, &findData1)) != INVALID_HANDLE_VALUE)
  75. {
  76. WIN32_FIND_DATA findData2;
  77. ::FindClose(hFind);
  78. hFind = CreateFile(
  79. strTemp2, // pointer to name of the file
  80. GENERIC_WRITE, // access (read-write) mode
  81. 0, // share mode
  82. 0,
  83. // pointer to security attributes
  84. CREATE_ALWAYS, // how to create
  85. FILE_ATTRIBUTE_NORMAL, // file attributes
  86. 0 // handle to file with attributes to
  87. );
  88. if(hFind != INVALID_HANDLE_VALUE)
  89. {
  90. CloseHandle(hFind);
  91. hFind = FindFirstFile(strTemp2, &findData2);
  92. ::DeleteFile(strTemp2);
  93. if(hFind != INVALID_HANDLE_VALUE)
  94. {
  95. ::FindClose(hFind);
  96. // look at difference in file creation times
  97. Time t1, t2;
  98. t1.m_stFileTime = findData1.ftCreationTime;
  99. t2.m_stFileTime = findData2.ftCreationTime;
  100. LONGLONG lldiff = t2.m_llTime - t1.m_llTime;
  101. if((lldiff/10000000) <= 600)
  102. bRes = true;
  103. }
  104. }
  105. }
  106. if(!bRes)
  107. {
  108. hFind = CreateFile(
  109. strTemp1, // pointer to name of the file
  110. GENERIC_WRITE, // access (read-write) mode
  111. 0, // share mode
  112. 0,
  113. // pointer to security attributes
  114. CREATE_ALWAYS, // how to create
  115. FILE_ATTRIBUTE_NORMAL, // file attributes
  116. 0 // handle to file with attributes to
  117. );
  118. if(hFind != INVALID_HANDLE_VALUE)
  119. ::CloseHandle(hFind);
  120. }
  121. return bRes;
  122. }
  123. bool IsServiceRunning(_bstr_t strServer)
  124. {
  125. SC_HANDLE hScm = OpenSCManager(strServer, NULL, GENERIC_READ);
  126. if(!hScm)
  127. {
  128. err.DbgMsgWrite(ErrW,L"Could not open SCManager on %s : GetLastError() returned %d",
  129. (WCHAR*)strServer, GetLastError());
  130. return false;
  131. }
  132. CComBSTR bstrServiceName(L"OnePointFileAdminService");
  133. SC_HANDLE hSvc = OpenService(hScm, GET_STRING(IDS_SERVICE_NAME), GENERIC_READ);
  134. if(!hSvc)
  135. {
  136. if ( GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST )
  137. err.DbgMsgWrite(ErrW,L"Could not open service on %s : GetLastError() returned %d",
  138. (WCHAR*)strServer, GetLastError());
  139. CloseServiceHandle(hScm);
  140. return false;
  141. }
  142. CloseServiceHandle(hScm);
  143. SERVICE_STATUS status;
  144. BOOL bRes = QueryServiceStatus(hSvc, &status);
  145. if(!bRes)
  146. {
  147. err.DbgMsgWrite(ErrW,L"Could not get service status on %s : GetLastError() returned %d",
  148. (WCHAR*)strServer, GetLastError());
  149. CloseServiceHandle(hSvc);
  150. return false;
  151. }
  152. CloseServiceHandle(hSvc);
  153. if(status.dwCurrentState != SERVICE_STOPPED)
  154. return true;
  155. else
  156. return false;
  157. }
  158. }
  159. typedef struct {
  160. int majorVersion;
  161. int minorVersion;
  162. } OSVersion;
  163. OSVersion GetTargetOSVersion(LPWSTR sServerName)
  164. {
  165. DWORD rc = NERR_Success;
  166. SERVER_INFO_101 * servInfo = NULL;
  167. OSVersion osVersion = { 4, 0 };
  168. // Check version info
  169. rc = NetServerGetInfo(sServerName, 101, (LPBYTE *)&servInfo);
  170. if (rc == NERR_Success)
  171. {
  172. osVersion.majorVersion = servInfo->sv101_version_major;
  173. osVersion.minorVersion = servInfo->sv101_version_minor;
  174. NetApiBufferFree(servInfo);
  175. }
  176. return osVersion;
  177. }
  178. DWORD // ret- OS return code
  179. CDCTInstaller::GetLocalMachineName()
  180. {
  181. DWORD rc = 0;
  182. WKSTA_INFO_100 * buf = NULL;
  183. rc = NetWkstaGetInfo(NULL,100,(LPBYTE*)&buf);
  184. if ( ! rc )
  185. {
  186. safecopy(m_LocalComputer,L"\\\\");
  187. UStrCpy(m_LocalComputer+2,buf->wki100_computername);
  188. NetApiBufferFree(buf);
  189. }
  190. return rc;
  191. }
  192. DWORD // ret- OS return code
  193. GetPlugInDirectory(
  194. WCHAR * directory // out- directory where plug-in files are
  195. )
  196. {
  197. TRegKey key;
  198. DWORD rc;
  199. // Get the plug-ins directory from the registry
  200. rc = key.Open(GET_STRING(IDS_HKLM_DomainAdmin_Key),HKEY_LOCAL_MACHINE);
  201. if ( ! rc )
  202. {
  203. rc = key.ValueGetStr(L"PlugInDirectory",directory,MAX_PATH * (sizeof WCHAR));
  204. }
  205. return rc;
  206. }
  207. DWORD // ret- OS return code
  208. GetInstallationDirectory(
  209. WCHAR * directory // out- directory we were installed to
  210. )
  211. {
  212. TRegKey key;
  213. DWORD rc;
  214. // Get the plug-ins directory from the registry
  215. rc = key.Open(GET_STRING(IDS_HKLM_DomainAdmin_Key),HKEY_LOCAL_MACHINE);
  216. if ( ! rc )
  217. {
  218. rc = key.ValueGetStr(L"Directory",directory,MAX_PATH * (sizeof WCHAR));
  219. }
  220. return rc;
  221. }
  222. DWORD // ret- OS return code
  223. GetProgramFilesDirectory(
  224. WCHAR * directory, // out- location of program files directory
  225. WCHAR const * computer // in - computer to find PF directory on
  226. )
  227. {
  228. TRegKey hklm;
  229. TRegKey key;
  230. DWORD rc;
  231. rc = hklm.Connect(HKEY_LOCAL_MACHINE,computer);
  232. if ( ! rc )
  233. {
  234. rc = key.Open(REGKEY_CURRENT_VERSION,&hklm);
  235. }
  236. if ( !rc )
  237. {
  238. rc = key.ValueGetStr(REGVAL_PROGRAM_FILES_DIRECTORY,directory,MAX_PATH * (sizeof WCHAR));
  239. }
  240. return rc;
  241. }
  242. STDMETHODIMP // ret- HRESULT
  243. CDCTInstaller::InstallToServer(
  244. BSTR serverName, // in - computer name to install to
  245. BSTR configurationFile, // in - full path to job file (varset file, copied as part of install)
  246. BSTR bstrCacheFile // in - cache file name
  247. )
  248. {
  249. DWORD rcOs=0; // OS return code
  250. if ( ! *m_LocalComputer )
  251. {
  252. rcOs = GetLocalMachineName();
  253. if ( rcOs )
  254. {
  255. err.SysMsgWrite(ErrE,rcOs,DCT_MSG_NO_LOCAL_MACHINE_NAME_D,rcOs);
  256. return HRESULT_FROM_WIN32(rcOs);
  257. }
  258. }
  259. // Check for admin privileges on the server
  260. rcOs = IsAdminRemote((WCHAR*)serverName);
  261. if ( rcOs == ERROR_ACCESS_DENIED )
  262. {
  263. err.MsgWrite(ErrE,DCT_MSG_NOT_ADMIN_ON_SERVER_S,(WCHAR*)serverName);
  264. return HRESULT_FROM_WIN32(rcOs);
  265. }
  266. else if ( rcOs == ERROR_BAD_NET_NAME )
  267. {
  268. err.MsgWrite(ErrE,DCT_MSG_NO_ADMIN_SHARES_S,(WCHAR*)serverName);
  269. return HRESULT_FROM_WIN32(rcOs);
  270. }
  271. else if ( rcOs == ERROR_BAD_NETPATH )
  272. {
  273. err.MsgWrite(ErrE,DCT_MSG_COMPUTER_NOT_FOUND_S,(WCHAR*)serverName);
  274. return HRESULT_FROM_WIN32(rcOs);
  275. }
  276. else if( rcOs == RPC_S_SERVER_UNAVAILABLE)
  277. {
  278. err.SysMsgWrite(ErrE, rcOs, DCT_MSG_AGENT_INSTALL_RPC_SERVER_UNAVAILABLE,(WCHAR*)serverName, rcOs);
  279. return HRESULT_FROM_WIN32(rcOs);
  280. }
  281. else if ( rcOs )
  282. {
  283. err.SysMsgWrite(ErrE,rcOs,DCT_MSG_NO_ADMIN_SHARE_SD,(WCHAR*)serverName,rcOs);
  284. return HRESULT_FROM_WIN32(rcOs);
  285. }
  286. TDCTInstall x( serverName, m_LocalComputer );
  287. DWORD typeThis = 0;
  288. DWORD typeTarg = 0;
  289. BOOL bNoProgramFiles = FALSE;
  290. BOOL bShareCreated = FALSE;
  291. SHARE_INFO_502 shareInfo;
  292. errCommon = err;
  293. do // once or until break
  294. {
  295. typeThis = QProcessor( m_LocalComputer );
  296. typeTarg = QProcessor( serverName );
  297. //do not install to ALPHAs, atleast for Whistler Beta 2
  298. if (typeTarg == PROCESSOR_IS_ALPHA)
  299. return CO_E_NOT_SUPPORTED;
  300. // Set installation directories for source and target
  301. WCHAR sDirInstall[MAX_PATH];
  302. WCHAR sDirPlugIn[MAX_PATH];
  303. WCHAR sDirSrc[MAX_PATH];
  304. WCHAR sDirTgt[MAX_PATH];
  305. WCHAR sDirSysTgt[MAX_PATH];
  306. WCHAR sDirTgtProgramFiles[MAX_PATH];
  307. WCHAR sDirTgtProgramFilesLocal[MAX_PATH];
  308. WCHAR sDestination[MAX_PATH];
  309. WCHAR sSvc[MAX_PATH];
  310. SHARE_INFO_1 * shInfo1 = NULL;
  311. rcOs = GetInstallationDirectory(sDirInstall);
  312. if ( rcOs ) break;
  313. rcOs = GetPlugInDirectory(sDirPlugIn);
  314. if ( rcOs ) break;
  315. rcOs = GetProgramFilesDirectory(sDirTgtProgramFiles,serverName);
  316. if ( rcOs )
  317. {
  318. if ( rcOs != ERROR_FILE_NOT_FOUND )
  319. {
  320. break;
  321. }
  322. // this doesn't work on NT 3.51, so if we can't get the program files directory, we'll
  323. // create a directory off the system root.
  324. safecopy(sDirTgtProgramFiles,"\\ADMIN$");
  325. bNoProgramFiles = TRUE;
  326. rcOs = 0;
  327. }
  328. safecopy(sDirTgtProgramFilesLocal,sDirTgtProgramFiles);
  329. // See if the admin$ shares exist already
  330. if ( sDirTgtProgramFiles[1] == L':' && sDirTgtProgramFiles[2] == L'\\' )
  331. {
  332. BOOL bNeedToCreateShare = FALSE;
  333. sDirTgtProgramFiles[1] = L'$';
  334. sDirTgtProgramFiles[2] = 0;
  335. rcOs = NetShareGetInfo(serverName,sDirTgtProgramFiles,1,(LPBYTE*)&shInfo1);
  336. if ( rcOs )
  337. {
  338. if ( rcOs == NERR_NetNameNotFound )
  339. {
  340. bNeedToCreateShare = TRUE;
  341. }
  342. else
  343. {
  344. bNeedToCreateShare = FALSE;
  345. err.SysMsgWrite(ErrE,rcOs,DCT_MSG_ADMIN_SHARE_GETINFO_FAILED_SSD,serverName,sDirTgtProgramFiles,rcOs);
  346. // put the program files path name back like it was
  347. sDirTgtProgramFiles[1] = L':';
  348. sDirTgtProgramFiles[2] = L'\\';
  349. }
  350. }
  351. else
  352. {
  353. if ( shInfo1->shi1_type & STYPE_SPECIAL )
  354. {
  355. // the admin share exists -- we'll just use it
  356. bNeedToCreateShare = FALSE;
  357. // put the program files path name back like it was
  358. sDirTgtProgramFiles[1] = L':';
  359. sDirTgtProgramFiles[2] = L'\\';
  360. }
  361. else
  362. {
  363. err.MsgWrite(0,DCT_MSG_SHARE_IS_NOT_ADMIN_SHARE_SS,serverName,shInfo1->shi1_netname);
  364. bNeedToCreateShare = TRUE;
  365. }
  366. NetApiBufferFree(shInfo1);
  367. }
  368. if ( bNeedToCreateShare )
  369. {
  370. SECURITY_DESCRIPTOR emptySD;
  371. WCHAR shareName[LEN_Path];
  372. WCHAR remark[LEN_Path];
  373. BYTE emptyRelSD[LEN_Path];
  374. DWORD lenEmptyRelSD = DIM(emptyRelSD);
  375. sDirTgtProgramFiles[1] = L':';
  376. sDirTgtProgramFiles[2] = L'\\';
  377. memset(&emptySD,0,(sizeof SECURITY_DESCRIPTOR));
  378. InitializeSecurityDescriptor(&emptySD,SECURITY_DESCRIPTOR_REVISION);
  379. MakeSelfRelativeSD(&emptySD,emptyRelSD,&lenEmptyRelSD);
  380. TSD pSD((SECURITY_DESCRIPTOR*)emptyRelSD,McsShareSD,FALSE);
  381. PACL dacl = NULL;
  382. TACE ace(ACCESS_ALLOWED_ACE_TYPE,0,DACL_FULLCONTROL_MASK,GetWellKnownSid(1/*ADMINISTRATORS*/));
  383. DWORD lenInfo = (sizeof shareInfo);
  384. pSD.ACLAddAce(&dacl,&ace,0);
  385. pSD.SetDacl(dacl);
  386. UStrCpy(shareName,GET_STRING(IDS_HiddenShare));
  387. UStrCpy(remark,GET_STRING(IDS_HiddenShareRemark));
  388. memset(&shareInfo,0,(sizeof shareInfo));
  389. shareInfo.shi502_netname = shareName;
  390. shareInfo.shi502_type = STYPE_DISKTREE;
  391. shareInfo.shi502_remark = remark;
  392. shareInfo.shi502_max_uses = 1;
  393. shareInfo.shi502_path = sDirTgtProgramFiles;
  394. shareInfo.shi502_security_descriptor = pSD.MakeRelSD();
  395. rcOs = NetShareAdd(serverName,502,(LPBYTE)&shareInfo,&lenInfo);
  396. if ( rcOs )
  397. {
  398. err.SysMsgWrite(ErrE,rcOs,DCT_MSG_TEMP_SHARE_CREATE_FAILED_SSD,serverName,shareName,rcOs);
  399. break;
  400. }
  401. else
  402. {
  403. safecopy(sDirTgtProgramFiles,shareName);
  404. bShareCreated = TRUE;
  405. }
  406. free(shareInfo.shi502_security_descriptor);
  407. shareInfo.shi502_security_descriptor = NULL;
  408. }
  409. }
  410. else
  411. {
  412. // something went wrong...the program files directory is not in drive:\path format
  413. err.MsgWrite(ErrW,DCT_MSG_INVALID_PROGRAM_FILES_DIR_SS,serverName,sDirTgtProgramFiles);
  414. }
  415. // setup source directory name for install
  416. UStrCpy( sDirSrc, sDirInstall );
  417. switch ( typeTarg )
  418. {
  419. case PROCESSOR_IS_INTEL:
  420. if ( typeTarg != typeThis )
  421. {
  422. UStrCpy(sDirSrc + UStrLen(sDirSrc),AGENT_INTEL_DIR);
  423. UStrCpy(sDirPlugIn + UStrLen(sDirPlugIn),AGENT_INTEL_DIR);
  424. }
  425. break;
  426. case PROCESSOR_IS_ALPHA:
  427. if ( typeTarg != typeThis )
  428. {
  429. UStrCpy(sDirSrc + UStrLen(sDirSrc),AGENT_ALPHA_DIR);
  430. UStrCpy(sDirPlugIn + UStrLen(sDirPlugIn),AGENT_ALPHA_DIR);
  431. }
  432. break;
  433. default:
  434. rcOs = ERROR_CAN_NOT_COMPLETE;
  435. break;
  436. }
  437. if ( rcOs ) break;
  438. //if the target machine is downlevel (NT4), dispatch NT4, non-robust, agent files
  439. OSVersion osVersion = GetTargetOSVersion(serverName);
  440. if (osVersion.majorVersion == 4)
  441. {
  442. _bstr_t sAgentDir = GET_STRING(IDS_AGENT_NT4_DIR);
  443. if (UStrLen(sDirSrc) + sAgentDir.length() < MAX_PATH)
  444. wcscat(sDirSrc, (WCHAR*)sAgentDir);
  445. if (UStrLen(sDirPlugIn) + sAgentDir.length() < MAX_PATH)
  446. wcscat(sDirPlugIn, (WCHAR*)sAgentDir);
  447. }
  448. // setup target directory name for install
  449. UStrCpy( sDirTgt, serverName );
  450. UStrCpy( sDirTgt+UStrLen(sDirTgt), L"\\" );
  451. if ( sDirTgtProgramFiles[1] == L':' )
  452. {
  453. sDirTgtProgramFiles[1] = L'$';
  454. }
  455. UStrCpy(sDirTgt + UStrLen(sDirTgt),sDirTgtProgramFiles);
  456. #ifdef OFA
  457. UStrCpy(sDirTgt + UStrLen(sDirTgt),L"\\OnePointFileAdminAgent\\");
  458. #else
  459. UStrCpy(sDirTgt + UStrLen(sDirTgt),GET_STRING(IDS_AgentDirectoryName));
  460. #endif
  461. // record the result path (on the remote machine) into the dispatcher.csv so that migration driver
  462. // knows where to look for results remotely
  463. errLog.DbgMsgWrite(0,L"%ls\t%ls\t%ls",(WCHAR*)serverName,L"RemoteResultPath",sDirTgt);
  464. UStrCpy( sDirSysTgt, serverName );
  465. UStrCpy( sDirSysTgt+UStrLen(sDirSysTgt), L"\\ADMIN$\\System32\\" );
  466. _bstr_t strTemp1(sDirSysTgt), strTemp2(sDirSysTgt);
  467. strTemp1 += (BSTR)GET_STRING(IDS_TEMP_FILE_1);
  468. strTemp2 += (BSTR)GET_STRING(IDS_TEMP_FILE_2);
  469. if(IsServiceInstalling(sDirSysTgt, strTemp1, strTemp2))
  470. {
  471. err.MsgWrite(ErrE,DCT_MSG_AGENT_SERVICE_ALREADY_RUNNING,(WCHAR*)serverName);
  472. #ifdef OFA
  473. return 0x88070040;
  474. #else
  475. return HRESULT_FROM_WIN32(ERROR_SERVICE_ALREADY_RUNNING);
  476. #endif
  477. }
  478. workerDeleteFile wrk(strTemp1);
  479. if(IsServiceRunning(serverName))
  480. {
  481. err.MsgWrite(ErrE,DCT_MSG_AGENT_SERVICE_ALREADY_RUNNING,(WCHAR*)serverName);
  482. #ifdef OFA
  483. return 0x88070040;
  484. #else
  485. return HRESULT_FROM_WIN32(ERROR_SERVICE_ALREADY_RUNNING);
  486. #endif
  487. }
  488. if ( bNoProgramFiles )
  489. {
  490. #ifdef OFA
  491. UStrCpy(sSvc,"%systemroot%\\OnePointFileAdminAgent\\");
  492. #else
  493. UStrCpy(sSvc,"%systemroot%\\OnePointDomainAgent\\");
  494. #endif
  495. UStrCpy( sSvc + UStrLen(sSvc),SERVICE_EXE );
  496. }
  497. else
  498. {
  499. UStrCpy( sSvc, sDirTgtProgramFilesLocal );
  500. #ifdef OFA
  501. UStrCpy( sSvc + UStrLen(sSvc),L"\\OnePointFileAdminAgent\\");
  502. #else
  503. UStrCpy( sSvc + UStrLen(sSvc),L"\\OnePointDomainAgent\\");
  504. #endif
  505. UStrCpy( sSvc + UStrLen(sSvc),SERVICE_EXE );
  506. sSvc[1] = L':';
  507. }
  508. if ( UStrICmp(m_LocalComputer,serverName) )
  509. {
  510. x.SetServiceInformation(GET_STRING(IDS_DISPLAY_NAME),GET_STRING(IDS_SERVICE_NAME),sSvc,NULL);
  511. }
  512. else
  513. {
  514. safecopy(sSvc,sDirSrc);
  515. UStrCpy(sSvc + UStrLen(sSvc),GET_STRING(IDS_SERVICE_EXE));
  516. x.SetServiceInformation(GET_STRING(IDS_DISPLAY_NAME),GET_STRING(IDS_SERVICE_NAME),sSvc,NULL);
  517. }
  518. rcOs = x.ScmOpen();
  519. if ( rcOs ) break;
  520. x.ServiceStop();
  521. if ( UStrICmp( m_LocalComputer, serverName ) )
  522. {
  523. // Create the target directory, if it does not exist
  524. if ( ! CreateDirectory(sDirTgt,NULL) )
  525. {
  526. rcOs = GetLastError();
  527. if ( rcOs && rcOs != ERROR_ALREADY_EXISTS )
  528. {
  529. err.SysMsgWrite(ErrE,rcOs,DCT_MSG_CREATE_DIR_FAILED_SD,sDirTgt,rcOs);
  530. break;
  531. }
  532. else
  533. rcOs = 0;
  534. }
  535. // shared MCS files
  536. // source files
  537. TInstallFile varset(VARSET_DLL,sDirSrc);
  538. // target\system32 files
  539. TInstallFile varsettargetsys(VARSET_DLL,sDirSysTgt,TRUE);
  540. // target\OnePoint files
  541. TInstallFile varsettarget(VARSET_DLL,sDirTgt,TRUE);
  542. // agent specific files
  543. TInstallFile worker(WORKER_DLL,sDirSrc);
  544. TInstallFile agent(AGENT_EXE,sDirSrc);
  545. TInstallFile service(SERVICE_EXE,sDirSrc);
  546. TInstallFile resourceMsg(RESOURCE_DLL,sDirSrc);
  547. TInstallFile eventMsg(MESSAGE_DLL,sDirSrc);
  548. TInstallFile workertarget(WORKER_DLL,sDirTgt,TRUE);
  549. TInstallFile agenttarget(AGENT_EXE,sDirTgt,TRUE);
  550. TInstallFile servicetarget(SERVICE_EXE,sDirTgt,TRUE);
  551. TInstallFile resourceMsgtarget(RESOURCE_DLL,sDirTgt,TRUE);
  552. TInstallFile eventMsgtarget(MESSAGE_DLL,sDirTgt,TRUE);
  553. // copy msvcp60.dll from SystemFolder to the target if the server machine is win2k
  554. // the target folder is the same as the rest of files
  555. // Note: for IA64, they are bound to have Whistler on it so we don't need to copy msvcp60.dll over
  556. // for NT4, we're using static linking so no dependency on msvcp60.dll
  557. if (osVersion.majorVersion == 5 && osVersion.minorVersion == 0)
  558. {
  559. WCHAR* lpwSystemFolder = new WCHAR[MAX_PATH];
  560. if (lpwSystemFolder != NULL)
  561. {
  562. int requiredSize = GetSystemDirectory(lpwSystemFolder, MAX_PATH);
  563. if (requiredSize != 0)
  564. {
  565. if (requiredSize > MAX_PATH)
  566. {
  567. delete[] lpwSystemFolder;
  568. lpwSystemFolder = new WCHAR[requiredSize];
  569. if (lpwSystemFolder != NULL)
  570. {
  571. GetSystemDirectory(lpwSystemFolder, requiredSize);
  572. }
  573. }
  574. if (lpwSystemFolder != NULL)
  575. {
  576. TInstallFile msvcp60Src(MSVCP60_DLL, lpwSystemFolder);
  577. TInstallFile msvcp60Trgt(MSVCP60_DLL, sDirTgt, TRUE);
  578. #ifdef OFA
  579. if (msvcp60Src.CompareFile(&msvcp60Trgt) > 0)
  580. #endif
  581. {
  582. swprintf(sDestination, L"%s%s", sDirTgt, MSVCP60_DLL);
  583. rcOs = msvcp60Src.CopyTo(sDestination);
  584. }
  585. }
  586. }
  587. }
  588. if (lpwSystemFolder != NULL)
  589. delete[] lpwSystemFolder;
  590. if (rcOs)
  591. break;
  592. }
  593. #ifdef OFA
  594. if ( varset.CompareFile(&varsettargetsys) > 0 )
  595. #endif
  596. {
  597. swprintf(sDestination,L"%s%s",sDirTgt,VARSET_DLL);
  598. rcOs = varset.CopyTo(sDestination);
  599. if (rcOs)
  600. break;
  601. }
  602. #ifdef OFA
  603. if ( worker.CompareFile(&workertarget) > 0 )
  604. #endif
  605. {
  606. swprintf(sDestination,L"%s%s",sDirTgt,WORKER_DLL);
  607. rcOs = worker.CopyTo(sDestination);
  608. if (rcOs)
  609. break;
  610. }
  611. #ifdef OFA
  612. if ( agent.CompareFile(&agenttarget) > 0 )
  613. #endif
  614. {
  615. swprintf(sDestination,L"%s%s",sDirTgt,AGENT_EXE);
  616. rcOs = agent.CopyTo(sDestination);
  617. if (rcOs)
  618. break;
  619. }
  620. #ifdef OFA
  621. if ( service.CompareFile(&servicetarget) > 0 )
  622. #endif
  623. {
  624. swprintf(sDestination,L"%s%s",sDirTgt,SERVICE_EXE);
  625. rcOs = service.CopyTo(sDestination);
  626. if (rcOs)
  627. break;
  628. }
  629. #ifdef OFA
  630. if ( resourceMsg.CompareFile(&resourceMsgtarget) > 0 )
  631. #endif
  632. {
  633. swprintf(sDestination,L"%s%s",sDirTgt,RESOURCE_DLL);
  634. rcOs = resourceMsg.CopyTo(sDestination);
  635. if (rcOs)
  636. break;
  637. }
  638. #ifdef OFA
  639. if ( eventMsg.CompareFile(&eventMsgtarget) > 0 )
  640. #endif
  641. {
  642. swprintf(sDestination,L"%s%s",sDirTgt,MESSAGE_DLL);
  643. rcOs = eventMsg.CopyTo(sDestination);
  644. if (rcOs)
  645. break;
  646. }
  647. // Copy files needed for plug-ins
  648. if ( m_PlugInFileList )
  649. {
  650. TNodeListEnum e;
  651. TFileNode * pNode;
  652. for ( pNode = (TFileNode*)e.OpenFirst(m_PlugInFileList) ; pNode ; pNode = (TFileNode*)e.Next() )
  653. {
  654. TInstallFile plugInSource(pNode->FileName(),sDirPlugIn);
  655. TInstallFile plugInTarget(pNode->FileName(),sDirTgt,TRUE);
  656. swprintf(sDestination,L"%s%s",sDirTgt,pNode->FileName());
  657. rcOs = plugInSource.CopyTo(sDestination);
  658. if (rcOs)
  659. break;
  660. }
  661. e.Close();
  662. if (rcOs)
  663. break;
  664. }
  665. }
  666. else
  667. {
  668. safecopy(sDirTgt,sDirSrc);
  669. }
  670. // Copy the job file
  671. // separate the directory and filename
  672. WCHAR sConfigPath[MAX_PATH];
  673. safecopy(sConfigPath,(WCHAR*)configurationFile);
  674. WCHAR * lastslash = wcsrchr(sConfigPath,L'\\');
  675. if ( lastslash )
  676. {
  677. *lastslash = 0;
  678. }
  679. WCHAR const * sConfigFile = lastslash + 1;
  680. TInstallFile config(sConfigFile,sConfigPath);
  681. swprintf(sDestination,L"%s%s",sDirTgt,sConfigFile);
  682. rcOs = config.CopyTo(sDestination);
  683. if (rcOs)
  684. break;
  685. //
  686. // copy cache file if one is specified
  687. //
  688. if (SysStringLen(bstrCacheFile) > 0)
  689. {
  690. TInstallFile cache(bstrCacheFile, sConfigPath);
  691. swprintf(sDestination, L"%s%s", sDirTgt, bstrCacheFile);
  692. rcOs = cache.CopyTo(sDestination);
  693. if (rcOs)
  694. break;
  695. }
  696. // start the service
  697. rcOs = x.ServiceStart();
  698. } while ( FALSE );
  699. if ( bShareCreated )
  700. {
  701. DWORD rcDeleteShare = NetShareDel(serverName,GET_STRING(IDS_HiddenShare),0);
  702. if ( rcDeleteShare )
  703. {
  704. err.SysMsgWrite(ErrW,rcDeleteShare,DCT_MSG_SHARE_DEL_FAILED_SSD,serverName,GET_STRING(IDS_HiddenShare),rcDeleteShare);
  705. }
  706. }
  707. if ( rcOs && rcOs != E_ABORT )
  708. {
  709. if(rcOs == ERROR_BAD_NETPATH)
  710. {
  711. err.SysMsgWrite(
  712. ErrE,
  713. rcOs,
  714. DCT_MSG_AGENT_INSTALL_NETWORPATH_NOT_FOUND,
  715. (WCHAR*)serverName,
  716. rcOs);
  717. }
  718. else
  719. {
  720. err.SysMsgWrite(
  721. ErrE,
  722. rcOs,
  723. DCT_MSG_AGENT_INSTALL_FAILED_SD,
  724. (WCHAR*)serverName,
  725. rcOs);
  726. }
  727. }
  728. // always return an HRESULT
  729. return HRESULT_FROM_WIN32(rcOs);
  730. }
  731. // Installs the agent to a computer
  732. // VarSet input:
  733. // InstallToServer - computer to install agent on
  734. // ConfigurationFile - file containing varset for job, installed with agent
  735. //
  736. STDMETHODIMP // ret- HRESULT
  737. CDCTInstaller::Process(
  738. IUnknown * pWorkItem // in - varset containing data
  739. )
  740. {
  741. HRESULT hr = S_OK;
  742. IVarSetPtr pVarSet = pWorkItem;
  743. _bstr_t serverName;
  744. _bstr_t dataFile;
  745. _bstr_t strCacheFile;
  746. // Read the server name
  747. serverName = pVarSet->get(GET_BSTR(DCTVS_InstallToServer));
  748. dataFile = pVarSet->get(GET_BSTR(DCTVS_ConfigurationFile));
  749. strCacheFile = pVarSet->get(GET_BSTR(DCTVS_CacheFile));
  750. if ( serverName.length() )
  751. {
  752. int accountReference = 0; // indicates whether we have account reference report
  753. int joinDomainWithRename = 0; // indicates wether we are trying to join domain with rename
  754. _bstr_t text = pVarSet->get(GET_BSTR(DCTVS_Security_ReportAccountReferences));
  755. if (text.length())
  756. accountReference = 1;
  757. // the following test used to set joinDomainWithRename should be
  758. // parallel to what is being tested in ExecuteDCTJob function in dctagent.cpp
  759. text = pVarSet->get(GET_WSTR(DCTVS_LocalServer_RenameTo));
  760. if (text.length())
  761. {
  762. text = pVarSet->get(GET_WSTR(DCTVS_LocalServer_ChangeDomain));
  763. if ((WCHAR*)text && !UStrICmp(text, GET_STRING(IDS_YES)))
  764. {
  765. text = pVarSet->get(GET_WSTR(DCTVS_Options_TargetDomain));
  766. if ((WCHAR*)text)
  767. joinDomainWithRename = 1;
  768. }
  769. }
  770. errLog.DbgMsgWrite(0,L"%ls\t%ls\t%d,%d,%ls",(WCHAR*)serverName,L"JobFile",accountReference,joinDomainWithRename,(WCHAR*)dataFile);
  771. hr = InstallToServer(serverName,dataFile,strCacheFile);
  772. _bstr_t strChoice = pVarSet->get(GET_BSTR(DCTVS_Options_DeleteJobFile));
  773. if(strChoice == _bstr_t(GET_STRING(IDS_YES)))
  774. ::DeleteFile(dataFile);
  775. errLog.DbgMsgWrite(0,L"%ls\t%ls\t%ld",(WCHAR*)serverName,L"Install",HRESULT_CODE(hr));
  776. }
  777. return hr;
  778. }