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.
 
 
 
 
 
 

380 lines
9.8 KiB

#define _WIN32_DCOM
#include <atlbase.h>
#include <atlconv.h>
#include <initguid.h>
#include <comdef.h>
#include <stdio.h>
#include <iadmw.h> // COM Interface header file.
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
#include "util.h"
#include "common.h"
#include "filecopy.h"
DWORD CannonicalizePath(WCHAR *pszPath)
{
ATLASSERT(pszPath);
DWORD dwLen = wcslen(pszPath);
if( pszPath[dwLen-1] == '\\' )
return ERROR_SUCCESS;
wcscat(pszPath,L"\\");
return ERROR_SUCCESS;
}
// Inputs: Metabase Key Path, Root Folder Path
// Outputs: Folder path appended with the key name from the metabase path
DWORD CreateVirtualRootPath(const WCHAR* pwszMDKeyPath, const WCHAR *pwszRootFolderPath,
WCHAR *pwszPath, DWORD dwSize)
{
ATLASSERT(pwszMDKeyPath);
ATLASSERT(pwszRootFolderPath);
ATLASSERT(pwszPath);
WCHAR *pRoot = wcsstr(_wcslwr((wchar_t*)pwszMDKeyPath),L"/root");
if(!pRoot)
return -1;
wcscpy(pwszPath, pwszRootFolderPath);
// if the metabase path is the root folder then return the root path passed in
if( _wcsicmp(pRoot,L"/root") == 0 )
{
return ERROR_SUCCESS;
}
if ( pwszPath[wcslen(pwszPath)-1] != '\\' )
wcscat(pwszPath,L"\\");
// tack on the remainder of the metabase key
wcscat(pwszPath, pRoot + wcslen(L"/root/"));
// fix the backslash
for( DWORD i = 0; i < wcslen(pwszPath); i++ )
{
if( pwszPath[i] == '/' )
pwszPath[i] = '\\';
}
return ERROR_SUCCESS;
}
DWORD AddListItem( PXCOPYTASKITEM *ppTaskItemList , const PXCOPYTASKITEM pTaskItem )
{
PXCOPYTASKITEM pHead;
ATLASSERT(ppTaskItemList);
ATLASSERT(pTaskItem);
pHead = *ppTaskItemList;
if( pHead == NULL )
{
*ppTaskItemList = pTaskItem;
return ERROR_SUCCESS;
}
while(pHead->pNextItem != NULL)
pHead = pHead->pNextItem;
pHead->pNextItem = pTaskItem;
return ERROR_SUCCESS;
}
DWORD BuildAdminSharePathName(const WCHAR* pwszPath, const WCHAR* pwszServer,
WCHAR* pwszAdminPath, DWORD dwPathBuffer )
{
WCHAR buffer[MAX_PATH];
ZeroMemory( buffer,sizeof(buffer) );
wcscpy(buffer,L"\\\\");
wcscat(buffer,pwszServer);
wcscat(buffer,L"\\");
wcsncat(buffer, pwszPath, 1);
wcscat(buffer,L"$");
wcscat(buffer,pwszPath+2);
DWORD wsz = wcslen(buffer);
if (wsz > dwPathBuffer)
return -1;
wcscpy(pwszAdminPath,buffer);
return ERROR_SUCCESS;
}
HRESULT BuildXCOPYTaskList(IMSAdminBase* pIMeta, METADATA_HANDLE hKey, WCHAR* pwszKeyPath, WCHAR* pwszRootFolderPath,
COSERVERINFO * pCoServerInfo, PXCOPYTASKITEM *ppTaskItemList )
{
HRESULT hRes = 0L;
DWORD indx = 0;
WCHAR SubKeyName[MAX_PATH*2];
PXCOPYTASKITEM pHead = NULL;
WCHAR SourcePath[MAX_PATH+2];
WCHAR PathDataBuf[MAX_PATH+2];
DWORD dwReqBufLen = MAX_PATH+2;
PXCOPYTASKITEM pNewItem;
WCHAR KeyName[MAX_PATH];
_bstr_t bstrKey;
while (SUCCEEDED(hRes))
{
hRes = pIMeta->EnumKeys(hKey, pwszKeyPath, SubKeyName, indx);
// RECURSIVELY SERARCH ALL SUB-FOLDERS
if(SUCCEEDED(hRes)) {
bstrKey = pwszKeyPath; bstrKey += L"/"; bstrKey += SubKeyName;
BuildXCOPYTaskList(pIMeta,hKey,bstrKey,pwszRootFolderPath,
pCoServerInfo,ppTaskItemList );
}
indx++;
} //while (SUCCEEDED(hRes))
// Read the PATH data
hRes = GetPropertyData(pIMeta,hKey,pwszKeyPath,MD_VR_PATH,METADATA_ISINHERITED,ALL_METADATA,ALL_METADATA,
PathDataBuf, &dwReqBufLen );
if( !SUCCEEDED(hRes) )
return hRes;
// Special case: if the virtual directory is a front page virtual directory,
// then don't add it to the list
GetKeyNameFromPath(pwszKeyPath,KeyName,MAX_PATH);
if( wcsstr(_wcslwr(KeyName),L"_vti") != NULL )
return S_OK;
if( !IsServerLocal((char*)_bstr_t(pCoServerInfo->pwszName) ) )
BuildAdminSharePathName(PathDataBuf,pCoServerInfo->pwszName,SourcePath, MAX_PATH);
pNewItem = new XCOPYTASKITEM;
ZeroMemory(pNewItem,sizeof(XCOPYTASKITEM));
pNewItem->pwszMBPath = new WCHAR[MAX_PATH];
wcscpy(pNewItem->pwszMBPath,pwszKeyPath);
pNewItem->pwszSourcePath = new WCHAR[MAX_PATH + 2];
wcscpy(pNewItem->pwszSourcePath, SourcePath );
pNewItem->pwszDestPath = new WCHAR[MAX_PATH + 2];
// If a target root directory is not specified, then we are using the path read from
// the source metabase
if( !pwszRootFolderPath )
wcscpy(pNewItem->pwszDestPath, PathDataBuf );
// a path is specified, we will need to create the sub folder structure for virtual dirs
// ex:
// if path = w3svc/1/root target = c:\inetpub\wwwroot result = c:\inetpub\wwwroot
// w3svc/1/root/app1 , target = c:\inetpub\wwwroot , result = c:\inetpub\wwwroot\app1
// w3svc/1/root/app1/app2 result = result = c:\inetpub\wwwroot\app1\app2
else
CreateVirtualRootPath(pwszKeyPath,pwszRootFolderPath,pNewItem->pwszDestPath,MAX_PATH+2);
// if ( !pxcopytaskitemlist )
// pxcopytaskitemlist = pNewItem;
//else
AddListItem(ppTaskItemList ,pNewItem);
return hRes;
}
HRESULT CopyContent(COSERVERINFO * pCoServerInfo, WCHAR* pwszSourceMBKeyPath,
WCHAR* pwszRootFolderPath,PXCOPYTASKITEM *ppTaskItemList, BOOL bEnumFoldersOnly )
{
HRESULT hRes = 0L;
METADATA_HANDLE hKey;
CComPtr <IMSAdminBase> pIMetaSource = 0L;
MULTI_QI rgmqi[1] = { &IID_IMSAdminBase,0,0 };
if( !pCoServerInfo || !pwszSourceMBKeyPath)
return E_UNEXPECTED;
hRes = CoCreateInstanceEx(CLSID_MSAdminBase,NULL, CLSCTX_ALL, pCoServerInfo,
1, rgmqi);
if(SUCCEEDED(hRes))
pIMetaSource = reinterpret_cast<IMSAdminBase*>(rgmqi[0].pItf);
else
return hRes;
if( pCoServerInfo->pAuthInfo->pAuthIdentityData->User != NULL )
{
hRes = SetBlanket(pIMetaSource,pCoServerInfo->pAuthInfo->pAuthIdentityData->User,
pCoServerInfo->pAuthInfo->pAuthIdentityData->Domain,pCoServerInfo->pAuthInfo->pAuthIdentityData->Password);
if( !SUCCEEDED(hRes) )
return hRes;
}
// Open the metabase path and loop through all the sub keys
hRes = pIMetaSource->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM",
METADATA_PERMISSION_READ, 10000, &hKey);
if( !SUCCEEDED(hRes) )
return hRes;
BuildXCOPYTaskList(pIMetaSource,hKey,pwszSourceMBKeyPath,pwszRootFolderPath,
pCoServerInfo, ppTaskItemList );
pIMetaSource->CloseKey(hKey);
// DEBUGPRINTLIST(ppTaskItemList);
// Call XCOPY on list items.
if( bEnumFoldersOnly )
XCOPY(ppTaskItemList);
return hRes;
}
VOID FreeXCOPYTaskList(PXCOPYTASKITEM pList)
{
if( !pList )
return;
PXCOPYTASKITEM pHead = pList;
PXCOPYTASKITEM pNext = pList->pNextItem;
while( pNext )
{
pHead = pNext;
pNext = pNext->pNextItem;
delete pHead->pwszDestPath;
delete pHead->pwszMBPath;
delete pHead->pwszSourcePath;
delete pHead;
}
}
DWORD XCOPY(PXCOPYTASKITEM *pTaskItemList, WCHAR* args )
{
PXCOPYTASKITEM pHead = *pTaskItemList;
if( !pHead)
return -1;
while (pHead->pNextItem)
{
XCOPY(pHead->pwszSourcePath,pHead->pwszDestPath,args);
pHead = pHead->pNextItem;
}
XCOPY(pHead->pwszSourcePath,pHead->pwszDestPath,args);
return ERROR_SUCCESS;
}
DWORD XCOPY(WCHAR* source, WCHAR* target, WCHAR* args )
{
STARTUPINFO si = {0};
si.cb = sizeof( si );
PROCESS_INFORMATION pi = {0};
_bstr_t bstrSourcePath(source);
_bstr_t bstrTargetPath(target);
TCHAR szSystemFolder[ MAX_PATH ];
if( 0 == GetSystemDirectory( szSystemFolder, MAX_PATH ) )
{
return GetLastError();
}
bstr_t cApplicationName( szSystemFolder );
cApplicationName += ( TEXT( "\\xcopy.exe" ) );
bstr_t cCommandLine( cApplicationName);
cCommandLine += ( TEXT(" ") );
cCommandLine += _bstr_t("\"") + bstrSourcePath + _bstr_t("\"") ;
cCommandLine += ( TEXT(" ") );
cCommandLine += _bstr_t("\"") + bstrTargetPath + _bstr_t("\"") ;
cCommandLine += ( TEXT(" /E /I /K /Y /H") );
Log( TEXT("executing: %s"), (char*)cCommandLine );
//cCommandLine.append( args );
// _tprintf( TEXT("executing: %s\n"), (char*)cCommandLine );
// return 0;
BOOL bOK = CreateProcess(
(char*)cApplicationName, // LPCTSTR lpApplicationName, // name of executable module
(char*) cCommandLine, // LPTSTR lpCommandLine, // command line string
NULL, // LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
NULL, // BOOL bInheritHandles, // handle inheritance option
CREATE_NEW_PROCESS_GROUP, // DWORD dwCreationFlags, // creation flags
NULL, // LPVOID lpEnvironment, // new environment block
NULL, // LPCTSTR lpCurrentDirectory, // current directory name
&si, // LPSTARTUPINFO lpStartupInfo, // startup information
&pi ); // LPPROCESS_INFORMATION lpProcessInformation // process information
if( !bOK )
{
Log( TEXT( "FAIL: CreateProcess() failed, error code=%d" ), GetLastError() );
return GetLastError();
}
DWORD dwRet = WaitForSingleObject( pi.hProcess, 360000 );
if( dwRet == WAIT_TIMEOUT )
{
Log( TEXT( "FAIL: CreateProcess() timed out" ) );
return ERROR_SEM_TIMEOUT;
}
else if( dwRet == WAIT_ABANDONED )
{
Log( TEXT( "FAIL: WaitForSingleObject() failed on WAIT_ABANDONED" ) );
return ERROR_SEM_TIMEOUT;
}
else if( dwRet == WAIT_FAILED )
{
LogError( TEXT( "FAIL: WaitForSingleObject() failed" ), GetLastError() );
return GetLastError();
}
DWORD dwExitCode = 0;
if( GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
{
if( dwExitCode )
{
Log( TEXT( "FAIL: xcopy() threw an error=%d" ), dwExitCode );
return dwExitCode;
}
else
{
Log( TEXT( "CreateProcess() succeeded" ) );
}
}
else
{
LogError( TEXT( "GetExitCodeProcess()" ), GetLastError() );
return GetLastError();
}
return ERROR_SUCCESS;
}