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.

379 lines
9.8 KiB

  1. #define _WIN32_DCOM
  2. #include <atlbase.h>
  3. #include <atlconv.h>
  4. #include <initguid.h>
  5. #include <comdef.h>
  6. #include <stdio.h>
  7. #include <iadmw.h> // COM Interface header file.
  8. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
  9. #include "util.h"
  10. #include "common.h"
  11. #include "filecopy.h"
  12. DWORD CannonicalizePath(WCHAR *pszPath)
  13. {
  14. ATLASSERT(pszPath);
  15. DWORD dwLen = wcslen(pszPath);
  16. if( pszPath[dwLen-1] == '\\' )
  17. return ERROR_SUCCESS;
  18. wcscat(pszPath,L"\\");
  19. return ERROR_SUCCESS;
  20. }
  21. // Inputs: Metabase Key Path, Root Folder Path
  22. // Outputs: Folder path appended with the key name from the metabase path
  23. DWORD CreateVirtualRootPath(const WCHAR* pwszMDKeyPath, const WCHAR *pwszRootFolderPath,
  24. WCHAR *pwszPath, DWORD dwSize)
  25. {
  26. ATLASSERT(pwszMDKeyPath);
  27. ATLASSERT(pwszRootFolderPath);
  28. ATLASSERT(pwszPath);
  29. WCHAR *pRoot = wcsstr(_wcslwr((wchar_t*)pwszMDKeyPath),L"/root");
  30. if(!pRoot)
  31. return -1;
  32. wcscpy(pwszPath, pwszRootFolderPath);
  33. // if the metabase path is the root folder then return the root path passed in
  34. if( _wcsicmp(pRoot,L"/root") == 0 )
  35. {
  36. return ERROR_SUCCESS;
  37. }
  38. if ( pwszPath[wcslen(pwszPath)-1] != '\\' )
  39. wcscat(pwszPath,L"\\");
  40. // tack on the remainder of the metabase key
  41. wcscat(pwszPath, pRoot + wcslen(L"/root/"));
  42. // fix the backslash
  43. for( DWORD i = 0; i < wcslen(pwszPath); i++ )
  44. {
  45. if( pwszPath[i] == '/' )
  46. pwszPath[i] = '\\';
  47. }
  48. return ERROR_SUCCESS;
  49. }
  50. DWORD AddListItem( PXCOPYTASKITEM *ppTaskItemList , const PXCOPYTASKITEM pTaskItem )
  51. {
  52. PXCOPYTASKITEM pHead;
  53. ATLASSERT(ppTaskItemList);
  54. ATLASSERT(pTaskItem);
  55. pHead = *ppTaskItemList;
  56. if( pHead == NULL )
  57. {
  58. *ppTaskItemList = pTaskItem;
  59. return ERROR_SUCCESS;
  60. }
  61. while(pHead->pNextItem != NULL)
  62. pHead = pHead->pNextItem;
  63. pHead->pNextItem = pTaskItem;
  64. return ERROR_SUCCESS;
  65. }
  66. DWORD BuildAdminSharePathName(const WCHAR* pwszPath, const WCHAR* pwszServer,
  67. WCHAR* pwszAdminPath, DWORD dwPathBuffer )
  68. {
  69. WCHAR buffer[MAX_PATH];
  70. ZeroMemory( buffer,sizeof(buffer) );
  71. wcscpy(buffer,L"\\\\");
  72. wcscat(buffer,pwszServer);
  73. wcscat(buffer,L"\\");
  74. wcsncat(buffer, pwszPath, 1);
  75. wcscat(buffer,L"$");
  76. wcscat(buffer,pwszPath+2);
  77. DWORD wsz = wcslen(buffer);
  78. if (wsz > dwPathBuffer)
  79. return -1;
  80. wcscpy(pwszAdminPath,buffer);
  81. return ERROR_SUCCESS;
  82. }
  83. HRESULT BuildXCOPYTaskList(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, WCHAR* pwszKeyPath, WCHAR* pwszRootFolderPath,
  84. COSERVERINFO * pCoServerInfo, PXCOPYTASKITEM *ppTaskItemList )
  85. {
  86. HRESULT hRes = 0L;
  87. DWORD indx = 0;
  88. WCHAR SubKeyName[MAX_PATH*2];
  89. PXCOPYTASKITEM pHead = NULL;
  90. WCHAR SourcePath[MAX_PATH+2];
  91. WCHAR PathDataBuf[MAX_PATH+2];
  92. DWORD dwReqBufLen = MAX_PATH+2;
  93. PXCOPYTASKITEM pNewItem;
  94. WCHAR KeyName[MAX_PATH];
  95. _bstr_t bstrKey;
  96. while (SUCCEEDED(hRes))
  97. {
  98. hRes = pIMeta->EnumKeys(hKey, pwszKeyPath, SubKeyName, indx);
  99. // RECURSIVELY SERARCH ALL SUB-FOLDERS
  100. if(SUCCEEDED(hRes)) {
  101. bstrKey = pwszKeyPath; bstrKey += L"/"; bstrKey += SubKeyName;
  102. BuildXCOPYTaskList(pIMeta,hKey,bstrKey,pwszRootFolderPath,
  103. pCoServerInfo,ppTaskItemList );
  104. }
  105. indx++;
  106. } //while (SUCCEEDED(hRes))
  107. // Read the PATH data
  108. hRes = GetPropertyData(pIMeta,hKey,pwszKeyPath,MD_VR_PATH,METADATA_ISINHERITED,ALL_METADATA,ALL_METADATA,
  109. PathDataBuf, &dwReqBufLen );
  110. if( !SUCCEEDED(hRes) )
  111. return hRes;
  112. // Special case: if the virtual directory is a front page virtual directory,
  113. // then don't add it to the list
  114. GetKeyNameFromPath(pwszKeyPath,KeyName,MAX_PATH);
  115. if( wcsstr(_wcslwr(KeyName),L"_vti") != NULL )
  116. return S_OK;
  117. if( !IsServerLocal((char*)_bstr_t(pCoServerInfo->pwszName) ) )
  118. BuildAdminSharePathName(PathDataBuf,pCoServerInfo->pwszName,SourcePath, MAX_PATH);
  119. pNewItem = new XCOPYTASKITEM;
  120. ZeroMemory(pNewItem,sizeof(XCOPYTASKITEM));
  121. pNewItem->pwszMBPath = new WCHAR[MAX_PATH];
  122. wcscpy(pNewItem->pwszMBPath,pwszKeyPath);
  123. pNewItem->pwszSourcePath = new WCHAR[MAX_PATH + 2];
  124. wcscpy(pNewItem->pwszSourcePath, SourcePath );
  125. pNewItem->pwszDestPath = new WCHAR[MAX_PATH + 2];
  126. // If a target root directory is not specified, then we are using the path read from
  127. // the source metabase
  128. if( !pwszRootFolderPath )
  129. wcscpy(pNewItem->pwszDestPath, PathDataBuf );
  130. // a path is specified, we will need to create the sub folder structure for virtual dirs
  131. // ex:
  132. // if path = w3svc/1/root target = c:\inetpub\wwwroot result = c:\inetpub\wwwroot
  133. // w3svc/1/root/app1 , target = c:\inetpub\wwwroot , result = c:\inetpub\wwwroot\app1
  134. // w3svc/1/root/app1/app2 result = result = c:\inetpub\wwwroot\app1\app2
  135. else
  136. CreateVirtualRootPath(pwszKeyPath,pwszRootFolderPath,pNewItem->pwszDestPath,MAX_PATH+2);
  137. // if ( !pxcopytaskitemlist )
  138. // pxcopytaskitemlist = pNewItem;
  139. //else
  140. AddListItem(ppTaskItemList ,pNewItem);
  141. return hRes;
  142. }
  143. HRESULT CopyContent(COSERVERINFO * pCoServerInfo, WCHAR* pwszSourceMBKeyPath,
  144. WCHAR* pwszRootFolderPath,PXCOPYTASKITEM *ppTaskItemList, BOOL bEnumFoldersOnly )
  145. {
  146. HRESULT hRes = 0L;
  147. METADATA_HANDLE hKey;
  148. CComPtr <IMSAdminBase> pIMetaSource = 0L;
  149. MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
  150. if( !pCoServerInfo || !pwszSourceMBKeyPath)
  151. return E_UNEXPECTED;
  152. hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfo,
  153. 1, rgmqi);
  154. if(SUCCEEDED(hRes))
  155. pIMetaSource = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
  156. else
  157. return hRes;
  158. if( pCoServerInfo->pAuthInfo->pAuthIdentityData->User != NULL )
  159. {
  160. hRes = SetBlanket(pIMetaSource,pCoServerInfo->pAuthInfo->pAuthIdentityData->User,
  161. pCoServerInfo->pAuthInfo->pAuthIdentityData->Domain,pCoServerInfo->pAuthInfo->pAuthIdentityData->Password);
  162. if( !SUCCEEDED(hRes) )
  163. return hRes;
  164. }
  165. // Open the metabase path and loop through all the sub keys
  166. hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM",
  167. METADATA_PERMISSION_READ, 10000, &hKey);
  168. if( !SUCCEEDED(hRes) )
  169. return hRes;
  170. BuildXCOPYTaskList(pIMetaSource,hKey,pwszSourceMBKeyPath,pwszRootFolderPath,
  171. pCoServerInfo, ppTaskItemList );
  172. pIMetaSource->CloseKey(hKey);
  173. // DEBUGPRINTLIST(ppTaskItemList);
  174. // Call XCOPY on list items.
  175. if( bEnumFoldersOnly )
  176. XCOPY(ppTaskItemList);
  177. return hRes;
  178. }
  179. VOID FreeXCOPYTaskList(PXCOPYTASKITEM pList)
  180. {
  181. if( !pList )
  182. return;
  183. PXCOPYTASKITEM pHead = pList;
  184. PXCOPYTASKITEM pNext = pList->pNextItem;
  185. while( pNext )
  186. {
  187. pHead = pNext;
  188. pNext = pNext->pNextItem;
  189. delete pHead->pwszDestPath;
  190. delete pHead->pwszMBPath;
  191. delete pHead->pwszSourcePath;
  192. delete pHead;
  193. }
  194. }
  195. DWORD XCOPY(PXCOPYTASKITEM *pTaskItemList, WCHAR* args )
  196. {
  197. PXCOPYTASKITEM pHead = *pTaskItemList;
  198. if( !pHead)
  199. return -1;
  200. while (pHead->pNextItem)
  201. {
  202. XCOPY(pHead->pwszSourcePath,pHead->pwszDestPath,args);
  203. pHead = pHead->pNextItem;
  204. }
  205. XCOPY(pHead->pwszSourcePath,pHead->pwszDestPath,args);
  206. return ERROR_SUCCESS;
  207. }
  208. DWORD XCOPY(WCHAR* source, WCHAR* target, WCHAR* args )
  209. {
  210. STARTUPINFO si = {0};
  211. si.cb = sizeof( si );
  212. PROCESS_INFORMATION pi = {0};
  213. _bstr_t bstrSourcePath(source);
  214. _bstr_t bstrTargetPath(target);
  215. TCHAR szSystemFolder[ MAX_PATH ];
  216. if( 0 == GetSystemDirectory( szSystemFolder, MAX_PATH ) )
  217. {
  218. return GetLastError();
  219. }
  220. bstr_t cApplicationName( szSystemFolder );
  221. cApplicationName += ( TEXT( "\\xcopy.exe" ) );
  222. bstr_t cCommandLine( cApplicationName);
  223. cCommandLine += ( TEXT(" ") );
  224. cCommandLine += _bstr_t("\"") + bstrSourcePath + _bstr_t("\"") ;
  225. cCommandLine += ( TEXT(" ") );
  226. cCommandLine += _bstr_t("\"") + bstrTargetPath + _bstr_t("\"") ;
  227. cCommandLine += ( TEXT(" /E /I /K /Y /H") );
  228. Log( TEXT("executing: %s"), (char*)cCommandLine );
  229. //cCommandLine.append( args );
  230. // _tprintf( TEXT("executing: %s\n"), (char*)cCommandLine );
  231. // return 0;
  232. BOOL bOK = CreateProcess(
  233. (char*)cApplicationName, // LPCTSTR lpApplicationName, // name of executable module
  234. (char*) cCommandLine, // LPTSTR lpCommandLine, // command line string
  235. NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
  236. NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  237. NULL, // BOOL bInheritHandles, // handle inheritance option
  238. CREATE_NEW_PROCESS_GROUP, // DWORD dwCreationFlags, // creation flags
  239. NULL, // LPVOID lpEnvironment, // new environment block
  240. NULL, // LPCTSTR lpCurrentDirectory, // current directory name
  241. &si, // LPSTARTUPINFO lpStartupInfo, // startup information
  242. &pi ); // LPPROCESS_INFORMATION lpProcessInformation // process information
  243. if( !bOK )
  244. {
  245. Log( TEXT( "FAIL: CreateProcess() failed, error code=%d" ), GetLastError() );
  246. return GetLastError();
  247. }
  248. DWORD dwRet = WaitForSingleObject( pi.hProcess, 360000 );
  249. if( dwRet == WAIT_TIMEOUT )
  250. {
  251. Log( TEXT( "FAIL: CreateProcess() timed out" ) );
  252. return ERROR_SEM_TIMEOUT;
  253. }
  254. else if( dwRet == WAIT_ABANDONED )
  255. {
  256. Log( TEXT( "FAIL: WaitForSingleObject() failed on WAIT_ABANDONED" ) );
  257. return ERROR_SEM_TIMEOUT;
  258. }
  259. else if( dwRet == WAIT_FAILED )
  260. {
  261. LogError( TEXT( "FAIL: WaitForSingleObject() failed" ), GetLastError() );
  262. return GetLastError();
  263. }
  264. DWORD dwExitCode = 0;
  265. if( GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
  266. {
  267. if( dwExitCode )
  268. {
  269. Log( TEXT( "FAIL: xcopy() threw an error=%d" ), dwExitCode );
  270. return dwExitCode;
  271. }
  272. else
  273. {
  274. Log( TEXT( "CreateProcess() succeeded" ) );
  275. }
  276. }
  277. else
  278. {
  279. LogError( TEXT( "GetExitCodeProcess()" ), GetLastError() );
  280. return GetLastError();
  281. }
  282. return ERROR_SUCCESS;
  283. }