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.

304 lines
9.0 KiB

  1. // smcys.cpp : Implementation of CSMCys
  2. #include "stdafx.h"
  3. #include "SMCys.h"
  4. #ifndef ASSERT
  5. #define ASSERT _ASSERT
  6. #endif
  7. #include "setupapi.h"
  8. #include "shlobj.h"
  9. #include "fileperms.h"
  10. const TCHAR* pszaMainFilePath[] =
  11. {
  12. _T("BOMSnap.dll"),
  13. _T("BackSnap.dll"),
  14. _T("servmgmt.msc"),
  15. _T("wizchain.dll"),
  16. _T("au_accnt.dll"),
  17. _T("addusr.exe"),
  18. _T("servhome.htm"),
  19. _T("")
  20. };
  21. const TCHAR* pszaImagesFilePath[] =
  22. {
  23. _T("backup.gif"),
  24. _T("doc.gif"),
  25. _T("folder.gif"),
  26. _T("nt_brand.gif"),
  27. _T("bg.gif"),
  28. _T("cysprint.gif"),
  29. _T("cysuser.gif"),
  30. _T("")
  31. };
  32. tstring AddBS( const TCHAR *szDirIn )
  33. {
  34. if (!szDirIn || !_tcslen( szDirIn ))
  35. return _T("");
  36. tstring str = szDirIn;
  37. // Do another MBCS ANSI safe comparison
  38. const TCHAR *szTemp = szDirIn;
  39. const UINT iSize = _tcsclen( szDirIn ) - 1;
  40. for( UINT ui = 0; ui < iSize; ui++ )
  41. szTemp = CharNext( szTemp );
  42. if (_tcsncmp( szTemp, _T("\\"), 1))
  43. str += _T("\\");
  44. return str;
  45. }
  46. BOOL DirExists( const TCHAR *szDir )
  47. {
  48. _ASSERT( szDir );
  49. if (!szDir || !_tcslen( szDir ))
  50. return FALSE;
  51. DWORD dw = GetFileAttributes( szDir );
  52. if (dw != INVALID_FILE_ATTRIBUTES)
  53. {
  54. if (dw & FILE_ATTRIBUTE_DIRECTORY)
  55. {
  56. return TRUE;
  57. }
  58. }
  59. return FALSE;
  60. }
  61. HRESULT RegisterFile( tstring strFile )
  62. {
  63. HRESULT hr = E_FAIL;
  64. HMODULE hDLL = LoadLibrary( strFile.c_str() );
  65. if( hDLL )
  66. {
  67. HRESULT (STDAPICALLTYPE * lpDllEntryPoint)(void);
  68. (FARPROC&)lpDllEntryPoint = GetProcAddress( hDLL, "DllRegisterServer" );
  69. if( lpDllEntryPoint )
  70. {
  71. hr = (*lpDllEntryPoint)();
  72. }
  73. FreeLibrary( hDLL );
  74. }
  75. return hr;
  76. }
  77. // ----------------------------------------------------------------------------
  78. // Constructor
  79. // ----------------------------------------------------------------------------
  80. CSMCys::CSMCys()
  81. {
  82. }
  83. // ----------------------------------------------------------------------------
  84. // Destructor
  85. // ----------------------------------------------------------------------------
  86. CSMCys::~CSMCys()
  87. {
  88. }
  89. // ----------------------------------------------------------------------------
  90. // Install()
  91. // ----------------------------------------------------------------------------
  92. HRESULT CSMCys::Install( BSTR bstrDiskName )
  93. {
  94. if( !bstrDiskName ) return E_POINTER;
  95. // Create the Administration directory
  96. tstring strMainInstallPath = _T("");
  97. tstring strImagesInstallPath = _T("");
  98. TCHAR szSysDir[MAX_PATH+1] = {0};
  99. tstring strKey = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
  100. tstring strValue = _T("SourcePath");
  101. TCHAR szSuggDir[MAX_PATH] = {0};
  102. tstring strDirectory = _T("");
  103. CRegKey cReg;
  104. if( cReg.Open( HKEY_LOCAL_MACHINE, strKey.c_str() ) == ERROR_SUCCESS )
  105. {
  106. DWORD dwRegCount = MAX_PATH;
  107. if( cReg.QueryValue(szSuggDir, strValue.c_str(), &dwRegCount) != ERROR_SUCCESS )
  108. {
  109. szSuggDir[0] = _T('\0');
  110. }
  111. else
  112. {
  113. strDirectory = AddBS(szSuggDir);
  114. #if defined(_M_IA64)
  115. strDirectory += _T("ia64");
  116. #else
  117. strDirectory += _T("i386");
  118. #endif
  119. }
  120. cReg.Close();
  121. }
  122. // Create ADministration Folder
  123. if( !SHGetSpecialFolderPath( ::GetForegroundWindow(), szSysDir, CSIDL_SYSTEM, TRUE ) )
  124. {
  125. return E_FAIL;
  126. }
  127. strMainInstallPath = szSysDir;
  128. strMainInstallPath += _T("\\Administration");
  129. if( !DirExists( strMainInstallPath.c_str() ) && !CreateDirectory( strMainInstallPath.c_str(), NULL ) )
  130. {
  131. return E_FAIL;
  132. }
  133. // Set permissions on Admin Folder
  134. HRESULT hrAdmin = AddPermissionToPath( strMainInstallPath.c_str(), DOMAIN_ALIAS_RID_ADMINS, FILE_ALL_ACCESS, FALSE, TRUE );
  135. if( FAILED(hrAdmin) ) return hrAdmin;
  136. HRESULT hrServerOps = AddPermissionToPath( strMainInstallPath.c_str(), DOMAIN_ALIAS_RID_SYSTEM_OPS );
  137. if( FAILED(hrServerOps) ) return hrServerOps;
  138. strImagesInstallPath = strMainInstallPath;
  139. strImagesInstallPath += _T("\\images");
  140. if( !DirExists( strImagesInstallPath.c_str() ) && !CreateDirectory( strImagesInstallPath.c_str(), NULL ) )
  141. {
  142. return E_FAIL;
  143. }
  144. // Copy the main files and register any DLLs
  145. int nCurrentFile = 0;
  146. const TCHAR* szCurrentFile = NULL;
  147. for( szCurrentFile = pszaMainFilePath[nCurrentFile++]; _tcslen(szCurrentFile); szCurrentFile = pszaMainFilePath[nCurrentFile++] )
  148. {
  149. DWORD dwLen = MAX_PATH - 1;
  150. DWORD dwRealLen = 0;
  151. UINT nRes = DPROMPT_SUCCESS;
  152. TCHAR* pszPath = new TCHAR[MAX_PATH];
  153. if( !pszPath ) continue;
  154. nRes = SetupPromptForDisk( ::GetForegroundWindow(), NULL, bstrDiskName, strDirectory.c_str(), szCurrentFile, NULL, IDF_CHECKFIRST | IDF_NOBEEP | IDF_WARNIFSKIP, pszPath, dwLen, &dwRealLen );
  155. if( nRes == DPROMPT_BUFFERTOOSMALL )
  156. {
  157. delete [] pszPath;
  158. dwLen = dwRealLen;
  159. pszPath = new TCHAR[dwRealLen];
  160. if( !pszPath ) continue;
  161. nRes = SetupPromptForDisk( ::GetForegroundWindow(), NULL, bstrDiskName, strDirectory.c_str(), szCurrentFile, NULL, IDF_CHECKFIRST | IDF_NOBEEP | IDF_WARNIFSKIP, pszPath, dwLen, &dwRealLen );
  162. }
  163. if( nRes == DPROMPT_SUCCESS )
  164. {
  165. // Store away the new, real path
  166. strDirectory = pszPath;
  167. // Copy the file!
  168. tstring strSourceFile = pszPath;
  169. strSourceFile += _T("\\");
  170. strSourceFile += szCurrentFile;
  171. tstring strDestFile = strMainInstallPath;
  172. strDestFile += _T("\\");
  173. strDestFile += szCurrentFile;
  174. if( SetupDecompressOrCopyFile( strSourceFile.c_str(), strDestFile.c_str(), NULL ) != ERROR_SUCCESS )
  175. {
  176. DWORD dwError = GetLastError();
  177. if ( (dwError != ERROR_SHARING_VIOLATION) &&
  178. (dwError != ERROR_USER_MAPPED_FILE) ) // We don't want to fail if it already exists
  179. {
  180. return E_FAIL;
  181. }
  182. }
  183. TCHAR szExt[_MAX_EXT] = {0};
  184. _tsplitpath( strDestFile.c_str(), NULL, NULL, NULL, szExt );
  185. if ( _tcscmp( szExt, _T(".dll") ) == 0 )
  186. {
  187. RegisterFile( strDestFile );
  188. }
  189. }
  190. delete [] pszPath;
  191. if( nRes != DPROMPT_SUCCESS )
  192. {
  193. return E_FAIL;
  194. }
  195. }
  196. // Copy the image files
  197. nCurrentFile = 0;
  198. for( szCurrentFile = pszaImagesFilePath[nCurrentFile++]; _tcslen(szCurrentFile); szCurrentFile = pszaImagesFilePath[nCurrentFile++] )
  199. {
  200. DWORD dwLen = MAX_PATH-1;
  201. DWORD dwRealLen = 0;
  202. UINT nRes = DPROMPT_SUCCESS;
  203. TCHAR* pszPath = new TCHAR[MAX_PATH];
  204. if( !pszPath ) continue;
  205. nRes = SetupPromptForDisk( ::GetForegroundWindow(), NULL, bstrDiskName, strDirectory.c_str(), szCurrentFile, NULL, IDF_CHECKFIRST | IDF_NOBEEP | IDF_WARNIFSKIP, pszPath, dwLen, &dwRealLen );
  206. if( nRes == DPROMPT_BUFFERTOOSMALL )
  207. {
  208. delete [] pszPath;
  209. dwLen = dwRealLen;
  210. pszPath = new TCHAR[dwRealLen];
  211. if( !pszPath ) continue;
  212. nRes = SetupPromptForDisk( ::GetForegroundWindow(), NULL, bstrDiskName, strDirectory.c_str(), szCurrentFile, NULL, IDF_CHECKFIRST | IDF_NOBEEP | IDF_WARNIFSKIP, pszPath, dwLen, &dwRealLen );
  213. }
  214. if( nRes == DPROMPT_SUCCESS )
  215. {
  216. // Store away the new, real path
  217. strDirectory = pszPath;
  218. // Copy the file!
  219. tstring strSourceFile = pszPath;
  220. strSourceFile += _T("\\");
  221. strSourceFile += szCurrentFile;
  222. tstring strDestFile = strImagesInstallPath;
  223. strDestFile += _T("\\");
  224. strDestFile += szCurrentFile;
  225. if( SetupDecompressOrCopyFile( strSourceFile.c_str(), strDestFile.c_str(), NULL ) != ERROR_SUCCESS )
  226. {
  227. DWORD dwError = GetLastError();
  228. if ( (dwError != ERROR_SHARING_VIOLATION) &&
  229. (dwError != ERROR_USER_MAPPED_FILE) ) // We don't want to fail if it already exists
  230. {
  231. return E_FAIL;
  232. }
  233. }
  234. }
  235. delete [] pszPath;
  236. if( nRes != DPROMPT_SUCCESS )
  237. {
  238. return E_FAIL;
  239. }
  240. }
  241. return S_OK;
  242. }