836 lines
22 KiB
C++
836 lines
22 KiB
C++
|
#include "headers.hxx"
|
||
|
|
||
|
|
||
|
#include "repair.hpp"
|
||
|
#include "CSVDSReader.hpp"
|
||
|
#include "resource.h"
|
||
|
|
||
|
|
||
|
|
||
|
Repair::Repair
|
||
|
(
|
||
|
const CSVDSReader& csvReader409_,
|
||
|
const CSVDSReader& csvReaderIntl_,
|
||
|
const String& domain_,
|
||
|
const String& rootContainerDn_,
|
||
|
AnalisysResults& res,
|
||
|
const String& ldiffName_,
|
||
|
const String& csvName_,
|
||
|
const String& saveName_,
|
||
|
const String& logPath_,
|
||
|
void *caleeStruct_/*=NULL*/,
|
||
|
progressFunction stepIt_/*=NULL*/,
|
||
|
progressFunction totalSteps_/*=NULL*/
|
||
|
)
|
||
|
:
|
||
|
results(res),
|
||
|
domain(domain_),
|
||
|
rootContainerDn(rootContainerDn_),
|
||
|
csvReader409(csvReader409_),
|
||
|
csvReaderIntl(csvReaderIntl_),
|
||
|
ldiffName(ldiffName_),
|
||
|
csvName(csvName_),
|
||
|
saveName(saveName_),
|
||
|
logPath(logPath_),
|
||
|
caleeStruct(caleeStruct_),
|
||
|
stepIt(stepIt_),
|
||
|
totalSteps(totalSteps_)
|
||
|
{
|
||
|
LOG_CTOR(Repair);
|
||
|
ASSERT(!domain.empty());
|
||
|
ASSERT(!rootContainerDn.empty());
|
||
|
ASSERT(!ldiffName.empty());
|
||
|
ASSERT(!csvName.empty());
|
||
|
ASSERT(!saveName.empty());
|
||
|
ASSERT(!logPath.empty());
|
||
|
};
|
||
|
|
||
|
|
||
|
void Repair::setProgress()
|
||
|
{
|
||
|
// We know the numbers bellow will fit in a long
|
||
|
// and we want IA64 to build
|
||
|
csvActions = static_cast<long>
|
||
|
(
|
||
|
results.createContainers.size() +
|
||
|
results.createW2KObjects.size() +
|
||
|
results.createXPObjects.size()
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
ldiffActions = static_cast<long>
|
||
|
(
|
||
|
results.objectActions.size() +
|
||
|
results.extraneousValues.size()
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
// We have three main tasks:
|
||
|
// 1) building the csv and ldif files to make the changes
|
||
|
// (buildCsv, buildChangeLdif)
|
||
|
// 2) saving the ldif files with objects that will change
|
||
|
// (buildSaveLdif)
|
||
|
// 3) running the csv and ldif files that will actually make
|
||
|
// the changes
|
||
|
// (runCsvOrLdif for the buildCsv and buildChangeLdif files)
|
||
|
// For simplification, The two first tasks will be half of
|
||
|
// the total work and the the last will be the other half.
|
||
|
//
|
||
|
// For task 1, each csv action takes 10 times an ldiff action.
|
||
|
//
|
||
|
// Each task 2 action is an ldif export that will be supposed
|
||
|
// to take 5 times more than an ldif import, since it has to
|
||
|
// call ldiffde to get each object.
|
||
|
//
|
||
|
// The total progress for 1) is
|
||
|
// t1=csvActions*10 + ldiffActions
|
||
|
// The progress for 2) is t2=5*ldiffActions
|
||
|
// The progress for 3) is a proportional division of
|
||
|
// t1+t2 between csvActions and ldiffActions that will add
|
||
|
// up to t1
|
||
|
// t3 = (t1+t2)*csvActions/(csvactions+ldiffActions) +
|
||
|
// (t1+t2)*ldiffActions/(csvactions+ldiffActions)
|
||
|
|
||
|
if(csvActions + ldiffActions == 0)
|
||
|
{
|
||
|
// We don't want to update the page if there are no
|
||
|
// actions
|
||
|
totalSteps=NULL;
|
||
|
stepIt=NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
csvBuildStep=10;
|
||
|
ldiffBuildStep=1;
|
||
|
ldiffSaveStep=10;
|
||
|
|
||
|
long totalProgress = csvBuildStep * csvActions +
|
||
|
ldiffBuildStep * ldiffActions +
|
||
|
ldiffSaveStep * ldiffActions;
|
||
|
// totalProgress is accounting for task 1 and 2
|
||
|
|
||
|
csvRunStep = totalProgress * csvActions /
|
||
|
(csvActions+ldiffActions);
|
||
|
|
||
|
ldiffRunStep = totalProgress - csvRunStep;
|
||
|
|
||
|
// now we compute the total time
|
||
|
totalProgress*=2;
|
||
|
|
||
|
if(totalSteps!=NULL)
|
||
|
{
|
||
|
totalSteps(totalProgress,caleeStruct);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
Repair::run()
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::run);
|
||
|
|
||
|
|
||
|
setProgress();
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
// First we build the csv. If we can't build it
|
||
|
// we don't want to run the LDIF and delete
|
||
|
// the recereate objects
|
||
|
if (csvActions != 0)
|
||
|
{
|
||
|
hr=buildCsv();
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
// Now we save the current objects and then
|
||
|
// create and run the LDIF
|
||
|
if ( ldiffActions !=0 )
|
||
|
{
|
||
|
// If we can't save we definatelly don't
|
||
|
// want to change anything
|
||
|
hr=buildSaveLdif();
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// buildChangeLdif wil build the Ldif that
|
||
|
// will change the objects saved im
|
||
|
// buildSaveLdif
|
||
|
hr=buildChangeLdif();
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
|
||
|
GetWorkFileName(
|
||
|
String::load(IDS_FILE_NAME_LDIF_LOG),
|
||
|
L"txt",
|
||
|
ldifLog
|
||
|
);
|
||
|
// runs the Ldif built in buildChangeLdif
|
||
|
hr=runCsvOrLdif(LDIF,IMPORT,ldiffName,L"",ldifLog);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffRunStep,caleeStruct);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Finally, we run the csv
|
||
|
if (csvActions!=0)
|
||
|
{
|
||
|
String opt=L"-c DOMAINPLACEHOLDER \"" + domain + L"\"";
|
||
|
|
||
|
GetWorkFileName
|
||
|
(
|
||
|
String::load(IDS_FILE_NAME_CSV_LOG),
|
||
|
L"txt",
|
||
|
csvLog
|
||
|
);
|
||
|
hr=runCsvOrLdif(CSV,IMPORT,csvName,opt,csvLog);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(csvRunStep,caleeStruct);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
while (0);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// Get the export results of a single object
|
||
|
HRESULT
|
||
|
Repair::getLdifExportedObject(
|
||
|
const long locale,
|
||
|
const String &object,
|
||
|
String &objectLines
|
||
|
)
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::getLdifExportedObject);
|
||
|
|
||
|
ASSERT(!object.empty());
|
||
|
ASSERT(locale > 0);
|
||
|
objectLines.erase();
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
String dn= L"CN=" + object +
|
||
|
String::format(L",CN=%1!3x!,", locale) +
|
||
|
rootContainerDn;
|
||
|
|
||
|
String opt=L"-o ObjectGuid -d \"" + dn + L"\"";
|
||
|
|
||
|
String tempName;
|
||
|
hr=GetWorkTempFileName(L"TMP",tempName);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=runCsvOrLdif(LDIF,EXPORT,tempName,opt);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=ReadAllFile(tempName,objectLines);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=Win::DeleteFile(tempName);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
} while(0);
|
||
|
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// buildSaveLdif will save information on
|
||
|
// all objects that will be changed
|
||
|
// or deleted in runChangeLdif.
|
||
|
// This includes information on:
|
||
|
// results.objectActions
|
||
|
HRESULT
|
||
|
Repair::buildSaveLdif()
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::buildSaveLdif);
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
HANDLE file;
|
||
|
|
||
|
hr=FS::CreateFile(saveName,
|
||
|
file,
|
||
|
GENERIC_WRITE);
|
||
|
|
||
|
if FAILED(hr)
|
||
|
{
|
||
|
error=String::format(IDS_COULD_NOT_CREATE_FILE,saveName.c_str());
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
String objectLines;
|
||
|
|
||
|
ObjectActions::iterator beginObj=results.objectActions.begin();
|
||
|
ObjectActions::iterator endObj=results.objectActions.end();
|
||
|
|
||
|
while(beginObj!=endObj)
|
||
|
{
|
||
|
String dn= L"dn: CN=" + beginObj->first.object +
|
||
|
String::format(L",CN=%1!3x!,", beginObj->first.locale) +
|
||
|
rootContainerDn + L"\r\nchangetype: delete\r\n";
|
||
|
|
||
|
hr=FS::WriteLine(file,dn);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=getLdifExportedObject(
|
||
|
beginObj->first.locale,
|
||
|
beginObj->first.object,
|
||
|
objectLines
|
||
|
);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=FS::WriteLine(file,objectLines);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffSaveStep,caleeStruct);
|
||
|
}
|
||
|
beginObj++;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
beginObj=results.extraneousValues.begin();
|
||
|
endObj=results.extraneousValues.end();
|
||
|
while(beginObj!=endObj)
|
||
|
{
|
||
|
ObjectId tempObj(
|
||
|
beginObj->first.locale,
|
||
|
String(beginObj->first.object)
|
||
|
);
|
||
|
if(
|
||
|
results.objectActions.find(tempObj) ==
|
||
|
results.objectActions.end()
|
||
|
)
|
||
|
{
|
||
|
String dn= L"dn: CN=" + beginObj->first.object +
|
||
|
String::format(L",CN=%1!3x!,", beginObj->first.locale) +
|
||
|
rootContainerDn + L"\r\nchangetype: delete\r\n";
|
||
|
|
||
|
hr=FS::WriteLine(file,dn);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=getLdifExportedObject(
|
||
|
beginObj->first.locale,
|
||
|
beginObj->first.object,
|
||
|
objectLines
|
||
|
);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=FS::WriteLine(file,objectLines);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffSaveStep,caleeStruct);
|
||
|
}
|
||
|
beginObj++;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
} while(0);
|
||
|
|
||
|
CloseHandle(file);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
Repair::makeObjectsLdif(HANDLE file,ObjectIdList &objects)
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::makeObjectsLdif);
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
ObjectIdList::iterator begin,end;
|
||
|
|
||
|
String header;
|
||
|
|
||
|
begin=objects.begin();
|
||
|
end=objects.end();
|
||
|
while(begin!=end)
|
||
|
{
|
||
|
header= L"\r\ndn: CN=" + begin->object +
|
||
|
String::format(L",CN=%1!3x!,", begin->locale) +
|
||
|
rootContainerDn;
|
||
|
hr=FS::WriteLine(file,header);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=FS::WriteLine(file,L"changetype: delete");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
begin++;
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffBuildStep,caleeStruct);
|
||
|
}
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
} while(0);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
// buildChangeLdif wil build the Ldif that
|
||
|
// will change the objects saved im
|
||
|
// buildSaveLdif
|
||
|
HRESULT
|
||
|
Repair::buildChangeLdif()
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::buildChangeLdif);
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
HANDLE file;
|
||
|
|
||
|
hr=FS::CreateFile(ldiffName,
|
||
|
file,
|
||
|
GENERIC_WRITE);
|
||
|
|
||
|
if FAILED(hr)
|
||
|
{
|
||
|
error=String::format(IDS_COULD_NOT_CREATE_FILE,ldiffName.c_str());
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
String header;
|
||
|
String line;
|
||
|
|
||
|
ObjectActions::iterator beginObj=results.objectActions.begin();
|
||
|
ObjectActions::iterator endObj=results.objectActions.end();
|
||
|
|
||
|
while(beginObj!=endObj)
|
||
|
{
|
||
|
header= L"\r\ndn: CN=" + beginObj->first.object +
|
||
|
String::format(L",CN=%1!3x!,", beginObj->first.locale) +
|
||
|
rootContainerDn;
|
||
|
hr=FS::WriteLine(file,header);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=FS::WriteLine(file,L"changetype: ntdsSchemaModify");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
|
||
|
PropertyActions::iterator beginAct=beginObj->second.begin();
|
||
|
PropertyActions::iterator endAct=beginObj->second.end();
|
||
|
|
||
|
while(beginAct!=endAct)
|
||
|
{
|
||
|
|
||
|
if(!beginAct->second.addValues.empty())
|
||
|
{
|
||
|
line = L"add: " + beginAct->first;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
StringList::iterator
|
||
|
beginAdd = beginAct->second.addValues.begin();
|
||
|
StringList::iterator
|
||
|
endAdd = beginAct->second.addValues.end();
|
||
|
while(beginAdd!=endAdd)
|
||
|
{
|
||
|
line = beginAct->first + L": " + *beginAdd;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
beginAdd++;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr); // break on if internal while broke
|
||
|
|
||
|
hr=FS::WriteLine(file,L"-");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
if(!beginAct->second.delValues.empty())
|
||
|
{
|
||
|
line = L"delete: " + beginAct->first;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
StringList::iterator
|
||
|
beginDel = beginAct->second.delValues.begin();
|
||
|
StringList::iterator
|
||
|
endDel = beginAct->second.delValues.end();
|
||
|
while(beginDel!=endDel)
|
||
|
{
|
||
|
line = beginAct->first + L": " + *beginDel;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
beginDel++;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr); // break on if internal while broke
|
||
|
|
||
|
hr=FS::WriteLine(file,L"-");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
beginAct++;
|
||
|
} // while(beginAct!=endAct)
|
||
|
BREAK_ON_FAILED_HRESULT(hr); // break on if internal while broke
|
||
|
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffBuildStep,caleeStruct);
|
||
|
}
|
||
|
beginObj++;
|
||
|
} // while(beginObj!=endObj)
|
||
|
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
// Now we will add actions to remove the extraneous objects
|
||
|
beginObj=results.extraneousValues.begin();
|
||
|
endObj=results.extraneousValues.end();
|
||
|
while(beginObj!=endObj)
|
||
|
{
|
||
|
|
||
|
header= L"\r\ndn: CN=" + beginObj->first.object +
|
||
|
String::format(L",CN=%1!3x!,", beginObj->first.locale) +
|
||
|
rootContainerDn;
|
||
|
|
||
|
hr=FS::WriteLine(file,header);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=FS::WriteLine(file,L"changetype: ntdsSchemaModify");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
PropertyActions::iterator beginAct=beginObj->second.begin();
|
||
|
PropertyActions::iterator endAct=beginObj->second.end();
|
||
|
|
||
|
while(beginAct!=endAct)
|
||
|
{
|
||
|
if(!beginAct->second.delValues.empty())
|
||
|
{
|
||
|
line = L"delete: " + beginAct->first;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
StringList::iterator
|
||
|
beginDel = beginAct->second.delValues.begin();
|
||
|
StringList::iterator
|
||
|
endDel = beginAct->second.delValues.end();
|
||
|
while(beginDel!=endDel)
|
||
|
{
|
||
|
line = beginAct->first + L": " + *beginDel;
|
||
|
hr=FS::WriteLine(file,line);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
beginDel++;
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr); // break on if internal while broke
|
||
|
|
||
|
hr=FS::WriteLine(file,L"-");
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
} //if(!beginAct->second.delValues.empty())
|
||
|
beginAct++;
|
||
|
} // while(beginAct!=endAct)
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(ldiffBuildStep,caleeStruct);
|
||
|
}
|
||
|
beginObj++;
|
||
|
} // while(beginObj!=endObj)
|
||
|
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
} while(0);
|
||
|
|
||
|
CloseHandle(file);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
Repair::makeObjectsCsv(HANDLE file,ObjectIdList &objects)
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::makeObjectsCsv);
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
ObjectIdList::iterator begin,end;
|
||
|
|
||
|
begin=objects.begin();
|
||
|
end=objects.end();
|
||
|
while(begin!=end)
|
||
|
{
|
||
|
long locale=begin->locale;
|
||
|
const CSVDSReader &csvReader=(locale==0x409)?csvReader409:csvReaderIntl;
|
||
|
|
||
|
setOfObjects tempObjs;
|
||
|
pair<String,long> tempObj;
|
||
|
tempObj.first=begin->object;
|
||
|
tempObj.second=begin->locale;
|
||
|
tempObjs.insert(tempObj);
|
||
|
|
||
|
|
||
|
hr=csvReader.makeObjectsCsv(file,tempObjs);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
begin++;
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(csvBuildStep,caleeStruct);
|
||
|
}
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
} while(0);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
// buildCsv creates a CSV with:
|
||
|
// results.createContainers,
|
||
|
// results.createW2KObjects
|
||
|
// results.createXPObjects
|
||
|
HRESULT
|
||
|
Repair::buildCsv()
|
||
|
{
|
||
|
LOG_FUNCTION(Repair::buildCsv);
|
||
|
|
||
|
HANDLE file;
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
|
||
|
hr=FS::CreateFile(csvName,
|
||
|
file,
|
||
|
GENERIC_WRITE);
|
||
|
|
||
|
if FAILED(hr)
|
||
|
{
|
||
|
error=String::format(IDS_COULD_NOT_CREATE_FILE,csvName.c_str());
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
|
||
|
LongList::iterator bgCont,endCont;
|
||
|
bgCont=results.createContainers.begin();
|
||
|
endCont=results.createContainers.end();
|
||
|
|
||
|
while(bgCont!=endCont)
|
||
|
{
|
||
|
long locale=*bgCont;
|
||
|
const CSVDSReader &csvReader=(locale==0x409)?csvReader409:csvReaderIntl;
|
||
|
long locales[2]={locale,0L};
|
||
|
hr=csvReader.makeLocalesCsv(file,locales);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
bgCont++;
|
||
|
if(stepIt!=NULL)
|
||
|
{
|
||
|
stepIt(csvBuildStep,caleeStruct);
|
||
|
}
|
||
|
}
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=makeObjectsCsv(file,results.createW2KObjects);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
|
||
|
hr=makeObjectsCsv(file,results.createXPObjects);
|
||
|
BREAK_ON_FAILED_HRESULT(hr);
|
||
|
} while(0);
|
||
|
|
||
|
CloseHandle(file);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// This finction will run csvde or ldifde(whichExe)
|
||
|
// to import or export (inOut) file. The options specified
|
||
|
// are -u for unicode, -j for the log/err path -f for the file
|
||
|
// -i if import and the extraOptions.
|
||
|
// The log file will be renamed for logFileArg(if !empty)
|
||
|
// If an error file is generated it will be renamed.
|
||
|
HRESULT
|
||
|
Repair::runCsvOrLdif(
|
||
|
csvOrLdif whichExe,
|
||
|
importExport inOut,
|
||
|
const String& file,
|
||
|
const String& extraOptions,//=L""
|
||
|
const String& logFileArg//=L""
|
||
|
)
|
||
|
{
|
||
|
|
||
|
LOG_FUNCTION2(Repair::runCsvOrLdif,file.c_str());
|
||
|
|
||
|
String baseName = (whichExe==LDIF) ? L"LDIF" : L"CSV";
|
||
|
String exeName = baseName + L"de.exe";
|
||
|
String options = (inOut==IMPORT) ? L"-i " + extraOptions : extraOptions;
|
||
|
String operation = (inOut==IMPORT) ? L"importing" : L"exporting";
|
||
|
|
||
|
HRESULT hr=S_OK;
|
||
|
do
|
||
|
{
|
||
|
|
||
|
String sys32dir = Win::GetSystemDirectory();
|
||
|
String wholeName = sys32dir + L"\\" + exeName;
|
||
|
|
||
|
if (!FS::FileExists(wholeName))
|
||
|
{
|
||
|
error=String::format(IDS_EXE_NOT_FOUND,wholeName.c_str());
|
||
|
hr=E_FAIL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (inOut==IMPORT && !FS::FileExists(file))
|
||
|
{
|
||
|
hr=Win32ToHresult(ERROR_FILE_NOT_FOUND);
|
||
|
error=file;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
String commandLine = L"\"" + wholeName + L"\" " +
|
||
|
options +
|
||
|
L" -u -f \"" +
|
||
|
file +
|
||
|
L"\" -j \"" +
|
||
|
logPath + L"\"";
|
||
|
|
||
|
STARTUPINFO si;
|
||
|
PROCESS_INFORMATION pi;
|
||
|
GetStartupInfo(&si);
|
||
|
|
||
|
String curDir=L"";
|
||
|
|
||
|
String errFile=logPath + L"\\" + baseName + L".err";
|
||
|
String logFile=logPath + L"\\" + baseName + L".log";
|
||
|
|
||
|
if(FS::FileExists(errFile))
|
||
|
{
|
||
|
hr=Win::DeleteFile(errFile);
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,errFile);
|
||
|
}
|
||
|
|
||
|
if(FS::FileExists(logFile))
|
||
|
{
|
||
|
hr=Win::DeleteFile(logFile);
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,logFile);
|
||
|
}
|
||
|
|
||
|
hr=Win::CreateProcess
|
||
|
(
|
||
|
commandLine,
|
||
|
NULL, // lpProcessAttributes
|
||
|
NULL, // lpThreadAttributes
|
||
|
false, // dwCreationFlags
|
||
|
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,// fdwCreate
|
||
|
NULL, // lpEnvironment
|
||
|
curDir, // lpEnvironment
|
||
|
si, // [in] lpStartupInfo
|
||
|
pi // [out] pProcessInformation
|
||
|
);
|
||
|
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,
|
||
|
String::format(IDS_COULD_NOT_START_EXE,commandLine.c_str()));
|
||
|
|
||
|
|
||
|
|
||
|
String errorInfo=String::format
|
||
|
(
|
||
|
IDS_CSVDE_LDIFDE_ERROR_BASIC,
|
||
|
operation.c_str(),
|
||
|
exeName.c_str(),
|
||
|
commandLine.c_str()
|
||
|
);
|
||
|
|
||
|
do
|
||
|
{
|
||
|
|
||
|
DWORD resWait;
|
||
|
hr=Win::WaitForSingleObject(pi.hProcess,INFINITE,resWait);
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,errorInfo);
|
||
|
|
||
|
if(!logFileArg.empty())
|
||
|
{
|
||
|
hr=FS::MoveFile(logFile.c_str(), logFileArg.c_str());
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,logFile);
|
||
|
}
|
||
|
|
||
|
DWORD resExit;
|
||
|
hr=Win::GetExitCodeProcess(pi.hProcess,resExit);
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,errorInfo);
|
||
|
|
||
|
|
||
|
if(resExit!=0)
|
||
|
{
|
||
|
String betterErrFile;
|
||
|
GetWorkFileName
|
||
|
(
|
||
|
String::load(
|
||
|
(whichExe==LDIF) ?
|
||
|
IDS_FILE_NAME_LDIF_ERROR :
|
||
|
IDS_FILE_NAME_CSV_ERROR
|
||
|
),
|
||
|
L"txt",
|
||
|
betterErrFile
|
||
|
);
|
||
|
|
||
|
hr=FS::MoveFile(errFile.c_str(), betterErrFile.c_str());
|
||
|
BREAK_ON_FAILED_HRESULT_ERROR(hr,errFile);
|
||
|
|
||
|
error=String::format
|
||
|
(
|
||
|
IDS_CSVDE_LDIFDE_ERROR_COMPLETE,
|
||
|
operation.c_str(),
|
||
|
exeName.c_str(),
|
||
|
commandLine.c_str(),
|
||
|
betterErrFile.c_str()
|
||
|
);
|
||
|
hr=E_FAIL;
|
||
|
break;
|
||
|
}
|
||
|
} while(0);
|
||
|
|
||
|
|
||
|
CloseHandle(pi.hProcess);
|
||
|
CloseHandle(pi.hThread);
|
||
|
|
||
|
} while(0);
|
||
|
|
||
|
LOG_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|