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.

941 lines
24 KiB

  1. #include "headers.hxx"
  2. #include "..\CSVDSReader.hpp"
  3. #include "..\constants.hpp"
  4. #include "..\global.hpp"
  5. #include <winnls.h>
  6. String escape(const wchar_t *str)
  7. {
  8. LOG_FUNCTION(escape);
  9. String dest;
  10. wchar_t strNum[5];
  11. while(*str!=0)
  12. {
  13. wsprintf(strNum,L"\\x%x",*str);
  14. dest+=String(strNum);
  15. str++;
  16. }
  17. return dest;
  18. }
  19. String issues;
  20. bool
  21. isPropertyInChangeList
  22. (
  23. String, //property,
  24. const objectChanges &//changes
  25. )
  26. {
  27. /*objectChanges::const_iterator begin,end;
  28. begin=changes.begin();
  29. end=changes.end();
  30. while(begin!=end)
  31. {
  32. changeList::const_iterator beginChanges,endChanges;
  33. beginChanges=begin->second.begin();
  34. endChanges=begin->second.end();
  35. while(beginChanges!=endChanges)
  36. {
  37. if (property.icompare(beginChanges->property)==0) return true;
  38. beginChanges++;
  39. }
  40. begin++;
  41. }*/
  42. return false;
  43. }
  44. bool
  45. isObjectPropertyInChangeList
  46. (
  47. String object,
  48. String property,
  49. const objectChanges &changes
  50. )
  51. {
  52. objectChanges::const_iterator begin,end;
  53. begin=changes.begin();
  54. end=changes.end();
  55. while(begin!=end)
  56. {
  57. changeList::const_iterator beginChanges,endChanges;
  58. beginChanges=begin->second.begin();
  59. endChanges=begin->second.end();
  60. while(beginChanges!=endChanges)
  61. {
  62. if (
  63. property.icompare(beginChanges->property)==0 &&
  64. object.icompare(beginChanges->object)==0
  65. )
  66. {
  67. return true;
  68. }
  69. beginChanges++;
  70. }
  71. begin++;
  72. }
  73. return false;
  74. }
  75. HRESULT
  76. getCommonProperties
  77. (
  78. const mapOfPositions& pp1,
  79. const mapOfPositions& pp2,
  80. StringList &commonProperties
  81. )
  82. {
  83. LOG_FUNCTION(getCommonProperties);
  84. HRESULT hr=S_OK;
  85. do
  86. {
  87. if(pp1.size()!=0)
  88. {
  89. mapOfPositions::const_iterator begin=pp1.begin(),end=pp1.end();
  90. while(begin!=end)
  91. {
  92. if(pp2.find(begin->first)==pp2.end())
  93. {
  94. error=L"The property:" + begin->first +
  95. L" was found only in Old. \r\n" +
  96. L"This program does not take into account" +
  97. L" the removal of properties from Old to New.\r\n"
  98. L"You should pass the Old csv file as the"
  99. L" first command line argument.";
  100. hr=E_FAIL;
  101. break;
  102. }
  103. begin++;
  104. }
  105. BREAK_ON_FAILED_HRESULT(hr);
  106. }
  107. if(pp2.size()!=0)
  108. {
  109. mapOfPositions::const_iterator begin=pp2.begin(),end=pp2.end();
  110. while(begin!=end)
  111. {
  112. if(pp1.find(begin->first)==pp1.end())
  113. {
  114. //bugbug - No Longer possible
  115. /*if (!isPropertyInChangeList(begin->first,changes))
  116. {
  117. issues +=
  118. L"The property:" + begin->first +
  119. L" was found only in New but is not a global"
  120. L" change. \r\nThis program does not generate entries"
  121. L" for properties only in New.\r\n\r\n\r\n";
  122. }*/
  123. }
  124. else
  125. {
  126. commonProperties.push_back(begin->first);
  127. }
  128. begin++;
  129. }
  130. BREAK_ON_FAILED_HRESULT(hr);
  131. }
  132. } while (0);
  133. return hr;
  134. }
  135. HRESULT
  136. addReplace
  137. (
  138. const enum TYPE_OF_CHANGE type,
  139. const long locale,
  140. const String &object,
  141. const String &property,
  142. const String &valueOld,
  143. const String &valueNew,
  144. const HANDLE fileOut
  145. )
  146. {
  147. LOG_FUNCTION(addReplace);
  148. ASSERT(
  149. type==REPLACE_W2K_MULTIPLE_VALUE ||
  150. type==REPLACE_W2K_SINGLE_VALUE
  151. );
  152. HRESULT hr=S_OK;
  153. do
  154. {
  155. String entry;
  156. entry=String::format
  157. (
  158. L"\r\n"
  159. L"\r\n"
  160. L" addChange\r\n"
  161. L" (\r\n"
  162. L" 0x%1!x!,\r\n"
  163. L" L\"%2\",\r\n"
  164. L" L\"%3\",\r\n"
  165. L" //%4 \r\n"
  166. L" L\"%5\",\r\n"
  167. L" //%6 \r\n"
  168. L" L\"%7\",\r\n"
  169. L" %8\r\n"
  170. L" );",
  171. locale, //1
  172. object.c_str(), //2
  173. property.c_str(), //3
  174. valueOld.c_str(), //4
  175. escape(valueOld.c_str()).c_str(), //5
  176. valueNew.c_str(), //6
  177. escape(valueNew.c_str()).c_str(), //7
  178. (type==REPLACE_W2K_SINGLE_VALUE) ? //8
  179. L"REPLACE_Old_SINGLE_VALUE":
  180. L"REPLACE_Old_MULTIPLE_VALUE"
  181. );
  182. AnsiString ansiEntry;
  183. String::ConvertResult res=entry.convert(ansiEntry);
  184. if(res!=String::CONVERT_SUCCESSFUL)
  185. {
  186. error=L"Ansi conversion failure";
  187. hr=E_FAIL;
  188. break;
  189. }
  190. hr = FS::Write(fileOut,ansiEntry);
  191. } while(0);
  192. return hr;
  193. }
  194. bool
  195. findI
  196. (
  197. const StringList &list,
  198. const String &value
  199. )
  200. {
  201. LOG_FUNCTION(findI);
  202. for
  203. (
  204. StringList::const_iterator current=list.begin(),end=list.end();
  205. current!=end;
  206. current++
  207. )
  208. {
  209. //if(current->icompare(value)==0)
  210. if(*current==value)
  211. {
  212. return true;
  213. }
  214. }
  215. return false;
  216. }
  217. bool
  218. findIPartial
  219. (
  220. const StringList &list,
  221. const String &value,
  222. String &valueFound
  223. )
  224. {
  225. LOG_FUNCTION(findIPartial);
  226. for
  227. (
  228. StringList::const_iterator current=list.begin(),end=list.end();
  229. current!=end;
  230. current++
  231. )
  232. {
  233. if(value.size()<=current->size())
  234. {
  235. //if(value.icompare( current->substr(0,value.size()) )==0)
  236. if( value == current->substr(0,value.size()) )
  237. {
  238. valueFound=*current;
  239. return true;
  240. }
  241. }
  242. }
  243. return false;
  244. }
  245. HRESULT
  246. dealWithMultipleValues
  247. (
  248. const long locale,
  249. const String& object,
  250. const String& property,
  251. const StringList &valuesNew,
  252. const StringList &valuesOld,
  253. const HANDLE fileOut
  254. )
  255. {
  256. LOG_FUNCTION(dealWithMultipleValues);
  257. StringList::const_iterator bgOld=valuesOld.begin();
  258. StringList::const_iterator endOld=valuesOld.end();
  259. HRESULT hr=S_OK;
  260. do
  261. {
  262. while(bgOld!=endOld)
  263. {
  264. if (!findI(valuesNew,*bgOld))
  265. {
  266. // The value was not found in New
  267. // The beginning of the value should be found
  268. String beforeComma,valueFound;
  269. size_t pos=bgOld->find(L',');
  270. if(pos==String::npos || pos==0)
  271. {
  272. error=String::format
  273. (
  274. L"(%1!x!,%2,%3) should have comma after 1st position",
  275. locale,
  276. object.c_str(),
  277. property.c_str()
  278. );
  279. hr=E_FAIL;
  280. break;
  281. }
  282. // pos+1 will include the comma
  283. beforeComma=bgOld->substr(0,pos+1);
  284. if(
  285. beforeComma.icompare(L"cn,")==0 &&
  286. object.icompare(L"domainDNS-Display")==0 &&
  287. property.icompare(L"attributeDisplayNames")==0
  288. )
  289. {
  290. // We are opening this exception since
  291. // this is the only value that had its beforeComma
  292. // part changed.
  293. beforeComma=L"dc,";
  294. }
  295. if(!findIPartial(valuesNew,beforeComma,valueFound))
  296. {
  297. error=String::format
  298. (
  299. L"(%1!x!,%2,%3) Value %4 is not in New",
  300. locale,
  301. object.c_str(),
  302. property.c_str(),
  303. beforeComma.c_str()
  304. );
  305. hr=E_FAIL;
  306. break;
  307. }
  308. hr=addReplace
  309. (
  310. REPLACE_W2K_MULTIPLE_VALUE,
  311. locale,
  312. object.c_str(),
  313. property.c_str(),
  314. *bgOld,
  315. valueFound,
  316. fileOut
  317. );
  318. BREAK_ON_FAILED_HRESULT(hr);
  319. }
  320. bgOld++;
  321. }
  322. BREAK_ON_FAILED_HRESULT(hr);
  323. } while(0);
  324. return hr;
  325. }
  326. // the function bellow is auxiliary in testing
  327. // how well csvreader performs its tasks of
  328. // reading properties. It dumps csvName to fileOut
  329. HRESULT
  330. dumpCsv
  331. (
  332. const String &csvName,
  333. const long *locales,
  334. const HANDLE fileOut
  335. )
  336. {
  337. LOG_FUNCTION(dumpCsv);
  338. HRESULT hr=S_OK;
  339. do
  340. {
  341. CSVDSReader csv;
  342. hr=csv.read(csvName.c_str(),locales);
  343. BREAK_ON_FAILED_HRESULT(hr);
  344. const mapOfPositions& pp1=csv.getProperties();
  345. // First we dump all the properties
  346. mapOfPositions::iterator begin=pp1.begin();
  347. mapOfPositions::iterator end=pp1.end();
  348. mapOfProperties prop;
  349. StringList emptyList;
  350. while(begin!=end)
  351. {
  352. hr=FS::Write(fileOut,begin->first);
  353. BREAK_ON_FAILED_HRESULT(hr);
  354. hr=FS::Write(fileOut,L",");
  355. BREAK_ON_FAILED_HRESULT(hr);
  356. prop[begin->first]=emptyList;
  357. begin++;
  358. }
  359. BREAK_ON_FAILED_HRESULT(hr);
  360. hr=FS::Write(fileOut,L"\r\n");
  361. BREAK_ON_FAILED_HRESULT(hr);
  362. bool flagEOF=false;
  363. // Now we will enumerate all csv lines
  364. hr=csv.initializeGetNext();
  365. BREAK_ON_FAILED_HRESULT(hr);
  366. do
  367. {
  368. long loc;
  369. String obj;
  370. hr=csv.getNextObject(loc,obj,prop);
  371. BREAK_ON_FAILED_HRESULT(hr);
  372. if(hr==S_FALSE) flagEOF=true;
  373. if(loc==0) continue;
  374. // now we enumerate each Value set from a property
  375. mapOfProperties::iterator begin=prop.begin();
  376. mapOfProperties::iterator end=prop.end();
  377. mapOfProperties::iterator last=prop.end();
  378. last--;
  379. while(begin!=end)
  380. {
  381. if(begin->second.size()!=0)
  382. {
  383. StringList::iterator curValue=begin->second.begin();
  384. StringList::iterator endValue=begin->second.end();
  385. StringList::iterator lastValue=endValue;
  386. lastValue--;
  387. if(
  388. begin->second.size()>1 ||
  389. begin->second.begin()->find(L',')!=String::npos
  390. )
  391. {
  392. hr=FS::Write(fileOut,L"\"");
  393. BREAK_ON_FAILED_HRESULT(hr);
  394. }
  395. while(curValue!=endValue)
  396. {
  397. hr=FS::Write(fileOut,*curValue);
  398. BREAK_ON_FAILED_HRESULT(hr);
  399. if(curValue!=lastValue)
  400. {
  401. hr=FS::Write(fileOut,L";");
  402. BREAK_ON_FAILED_HRESULT(hr);
  403. }
  404. curValue++;
  405. }
  406. BREAK_ON_FAILED_HRESULT(hr);
  407. if(
  408. begin->second.size()>1 ||
  409. begin->second.begin()->find(L',')!=String::npos
  410. )
  411. {
  412. hr=FS::Write(fileOut,L"\"");
  413. BREAK_ON_FAILED_HRESULT(hr);
  414. }
  415. }
  416. if(begin!=last)
  417. {
  418. hr=FS::Write(fileOut,L",");
  419. BREAK_ON_FAILED_HRESULT(hr);
  420. }
  421. begin++;
  422. }
  423. BREAK_ON_FAILED_HRESULT(hr);
  424. hr=FS::Write(fileOut,L"\r\n");
  425. BREAK_ON_FAILED_HRESULT(hr);
  426. } while(!flagEOF);
  427. } while(0);
  428. return hr;
  429. }
  430. // Compare the Old and New csv files to check for
  431. // differences in their common properties that will generate
  432. // REPLACE_Old entries in fileOut. locales has the set of locales
  433. // expected to be present in both the csv files.
  434. HRESULT
  435. generateChanges
  436. (
  437. const String &csvOldName,
  438. const String &csvNewName,
  439. const long *locales,
  440. const HANDLE fileOut
  441. )
  442. {
  443. LOG_FUNCTION(generateChanges);
  444. HRESULT hr=S_OK;
  445. // bugbug No Longer Necessary
  446. // Let's add the new objects in a StringList
  447. // to later use findI to skip csv lines with
  448. // new objects
  449. StringList newNewObjects;
  450. for(long t=0;*NEW_WHISTLER_OBJECTS[t]!=0;t++)
  451. {
  452. newNewObjects.push_back(NEW_WHISTLER_OBJECTS[t]);
  453. }
  454. do
  455. {
  456. CSVDSReader csvOld;
  457. hr=csvOld.read(csvOldName.c_str(),locales);
  458. BREAK_ON_FAILED_HRESULT(hr);
  459. CSVDSReader csvNew;
  460. hr=csvNew.read(csvNewName.c_str(),locales);
  461. BREAK_ON_FAILED_HRESULT(hr);
  462. // Now we get the common properties as a StringList
  463. const mapOfPositions& pp1=csvOld.getProperties();
  464. const mapOfPositions& pp2=csvNew.getProperties();
  465. StringList commonProperties;
  466. // bugbug. Get uncommon too and write them as
  467. // global ADD_ALL_CSV_VALUES changes
  468. hr=getCommonProperties
  469. (
  470. pp1,
  471. pp2,
  472. commonProperties
  473. );
  474. BREAK_ON_FAILED_HRESULT(hr);
  475. // Here we start readding both csv files
  476. hr=csvOld.initializeGetNext();
  477. BREAK_ON_FAILED_HRESULT(hr);
  478. hr=csvNew.initializeGetNext();
  479. BREAK_ON_FAILED_HRESULT(hr);
  480. // The loop bellow will sequentially read objects
  481. // in both csv's making sure the same objects are read.
  482. bool flagEOF=false;
  483. do
  484. {
  485. mapOfProperties propOld,propNew;
  486. long locOld,locNew;
  487. String objOld,objNew;
  488. hr=csvOld.getNextObject(locOld,objOld,propOld);
  489. if(objOld==L"remoteStorageServicePoint-Display")
  490. {
  491. flagEOF=flagEOF;
  492. }
  493. LOG(locOld);
  494. LOG(objOld);
  495. BREAK_ON_FAILED_HRESULT(hr);
  496. if(hr==S_FALSE) flagEOF=true;
  497. // The loop bellow skips csv lines with new objects.
  498. do
  499. {
  500. //bugbug instead of skipping add locale dependent NEW_OBJECT
  501. //changes. It will require no parameters since it will use
  502. //the latest csv. The loop goes untill the objects are the same
  503. //or the new has ended. If the old has ended, clear its object
  504. // to go on with the new
  505. hr=csvNew.getNextObject(locNew,objNew,propNew);
  506. BREAK_ON_FAILED_HRESULT(hr);
  507. } while(hr!=S_FALSE && findI(newNewObjects,objNew));
  508. //bugbug if the new has ended
  509. BREAK_ON_FAILED_HRESULT(hr);
  510. if(hr==S_FALSE) flagEOF=true;
  511. if(locNew==0 && locOld==0) continue;
  512. // This means blank lines on both csvs.
  513. // Blank lines would be common only in the end of
  514. // the file, but I don't care for them in the middle as long as they are
  515. // in the same number in both the New and Old csvs.
  516. // If we have blank lines in only one of the files, the if
  517. // bellow will flag it as any other assynchronous result
  518. if( (objOld != objNew) || (locOld != locNew) )
  519. {
  520. error=String::format
  521. (
  522. "(%1,%2!x!) should be the same as (%3,%4!x!).",
  523. objOld.c_str(),
  524. locOld,
  525. objNew.c_str(),
  526. locNew
  527. );
  528. hr=E_FAIL;
  529. break;
  530. }
  531. // now let's check the differences in the common properties
  532. StringList::iterator curCommon=commonProperties.begin();
  533. StringList::iterator endCommon=commonProperties.end();
  534. for(;curCommon!=endCommon;curCommon++)
  535. {
  536. //bugbug no longer possible
  537. /*
  538. if (isObjectPropertyInChangeList(objOld,*curCommon,changes) )
  539. { // It is already taken care of by a global change
  540. continue;
  541. }*/
  542. const StringList &valuesOld=propOld[*curCommon];
  543. const StringList &valuesNew=propNew[*curCommon];
  544. long Oldlen=valuesOld.size();
  545. long Newlen=valuesNew.size();
  546. if (Oldlen!=Newlen)
  547. {
  548. error=String::format
  549. (
  550. L"(%1!x!,%2,%3) should have the same Old(%4!d!) "
  551. L"and New(%5!d!) number of values",
  552. locOld,
  553. objOld.c_str(),
  554. curCommon->c_str(),
  555. Oldlen,
  556. Newlen
  557. );
  558. hr=E_FAIL;
  559. break;
  560. }
  561. if(Oldlen==1) // and, therefore, Newlen==1
  562. {
  563. if( valuesNew.begin()->icompare(*valuesOld.begin()) != 0 )
  564. {
  565. hr=addReplace
  566. (
  567. REPLACE_W2K_SINGLE_VALUE,
  568. locOld,
  569. objOld.c_str(),
  570. curCommon->c_str(),
  571. *valuesOld.begin(),
  572. *valuesNew.begin(),
  573. fileOut
  574. );
  575. BREAK_ON_FAILED_HRESULT(hr);
  576. }
  577. }
  578. else if(Oldlen > 1)
  579. {
  580. hr=dealWithMultipleValues
  581. (
  582. locOld,
  583. objOld.c_str(),
  584. curCommon->c_str(),
  585. valuesNew,
  586. valuesOld,
  587. fileOut
  588. );
  589. BREAK_ON_FAILED_HRESULT(hr);
  590. } // else both are 0 and replacements are not needed
  591. }
  592. BREAK_ON_FAILED_HRESULT(hr);
  593. } while(!flagEOF);
  594. BREAK_ON_FAILED_HRESULT(hr);
  595. }
  596. while(0);
  597. return hr;
  598. }
  599. void chk()
  600. {
  601. HRESULT hr=S_OK;
  602. HANDLE file=NULL;
  603. String errors;
  604. do
  605. {
  606. hr=FS::CreateFile("c:\\public\\dcpromoOld.csv",
  607. file,
  608. GENERIC_READ);
  609. if(FAILED(hr)) break;
  610. int countLine=0;
  611. bool flagEof=false;
  612. while(!flagEof)
  613. {
  614. String line;
  615. hr=ReadLine(file,line);
  616. if(hr==EOF_HRESULT)
  617. {
  618. hr=S_OK;
  619. flagEof=true;
  620. }
  621. if(line.empty()) continue;
  622. if(IsNLSDefinedString(COMPARE_STRING,0,NULL,line.c_str(),line.length())==FALSE)
  623. {
  624. errors+=String::format(L"line:%1!d! ", countLine+1);
  625. wchar_t str[2];
  626. str[1]=0;
  627. for(int countColumn=0;countColumn<line.length();countColumn++)
  628. {
  629. str[0]=line[countColumn];
  630. if(IsNLSDefinedString(COMPARE_STRING,0,NULL,str,wcslen(str))==FALSE)
  631. {
  632. errors+=String::format(L"(0x%1!x! at %2!d!)",str[0],countColumn+1);
  633. }
  634. }
  635. errors+=L".\n";
  636. }
  637. countLine++;
  638. }
  639. }
  640. while(0);
  641. if(file!=NULL) CloseHandle(file);
  642. MessageBox(NULL,errors.c_str(),L"errors",MB_OK);
  643. }
  644. #include <rpcdce.h>
  645. void printGUID(const GUID& g)
  646. {
  647. printf("{%x,%x,%x,{%x,%x,%x,%x,%x,%x,%x,%x}}\n",g.Data1,g.Data2,g.Data3,
  648. g.Data4[0],g.Data4[1],g.Data4[2],g.Data4[3],g.Data4[4],g.Data4[5],
  649. g.Data4[6],g.Data4[7]);
  650. wchar_t *str;
  651. if(UuidToString((UUID*)&g,&str)==RPC_S_OK)
  652. {
  653. wprintf(L" %s\n\n",str);
  654. RpcStringFree(&str);
  655. }
  656. }
  657. void __cdecl main( void )
  658. {
  659. GUID g1={0,0,1,0,1,2,3,4,5,6,7};
  660. printGUID(g1);
  661. if(UuidFromString(L"baddb31b-b428-4103-ae78-3bba5541a20d",&g1)==RPC_S_OK)
  662. {
  663. printGUID(g1);
  664. }
  665. else
  666. {
  667. printf("UUID string is not valid");
  668. }
  669. }
  670. /*
  671. void __cdecl main(int argc,char *argv[])
  672. {
  673. if(argc!=7)
  674. {
  675. printf("\nThis program generates a new set of changes to be "
  676. "used in dcpromo.lib by comparing the new and previous"
  677. " csv files. Usage:\n\n\"preBuild.exe GUID oldDcpromo "
  678. "newDcpromo old409 new409 targetFolder\"\n\n"
  679. "GUID is the identifier for this set of changes, for example:\n"
  680. "{0x4444C516,0xF43A,0x4c12,0x9C,0x4B,0xB5,0xC0,0x64,0x94,"
  681. "0x1D,0x61}\n\n"
  682. "oldDcpromo is the previous dcpromo.csv\n"
  683. "newDcpromo is the new dcpromo.csv\n"
  684. "old409 is the previous 409.csv\n"
  685. "new409 is the new 409.csv\n\n"
  686. "targetFolder is the sources file for dcpromo.lib,"
  687. " where guids.cpp, and "
  688. "changes.NNN.cpp will be generated and where the sources "
  689. "file for the display specifier upgrade library is. "
  690. "An entry like: \"changes.NNN.cpp \\\" will be added "
  691. "at the end targetFolder\\sources.\n\n");
  692. }
  693. else printf(argv[1]);
  694. }
  695. */
  696. /*
  697. int WINAPI
  698. WinMain(
  699. HINSTANCE hInstance,
  700. HINSTANCE, //hPrevInstance
  701. LPSTR, //lpszCmdLine
  702. int //nCmdShow
  703. )
  704. {
  705. LOG_FUNCTION(WinMain);
  706. chk();
  707. return 0;
  708. hResourceModuleHandle=hInstance;
  709. int argv;
  710. LPWSTR *argc=CommandLineToArgvW(GetCommandLine(),&argv);
  711. String usage;
  712. usage = L"Usage: OldRepl folder outputFile\r\n"
  713. L"Example: obj\\i386\\OldRepl .\\ ..\\setReplacements.cpp\r\n"
  714. L"folder must have four files: \r\n"
  715. L" win2k.dcpromo.csv\r\n"
  716. L" whistler.dcpromo.csv\r\n"
  717. L" win2k.409.csv\r\n"
  718. L" whistler.409.csv\r\n"
  719. L" Don't forget to checkout the output file if\r\n"
  720. L" it is under source control.\r\n";
  721. if(argv!=3)
  722. {
  723. MessageBox(NULL,usage.c_str(),L"Two arguments required.",MB_OK);
  724. return 0;
  725. }
  726. String path = FS::NormalizePath(argc[1]);
  727. String outFileName = FS::NormalizePath(argc[2]);
  728. String dcpromoNew = path+L"whistler.dcpromo.csv";
  729. String dcpromoOld = path+L"win2k.dcpromo.csv";
  730. String csv409New = path+L"whistler.409.csv";
  731. String csv409Old = path+L"win2k.409.csv";
  732. if(
  733. !FS::FileExists(dcpromoNew) ||
  734. !FS::FileExists(dcpromoOld) ||
  735. !FS::FileExists(csv409New) ||
  736. !FS::FileExists(csv409Old)
  737. )
  738. {
  739. MessageBox(NULL,usage.c_str(),L"Some file doesn't exist",MB_OK);
  740. return 0;
  741. }
  742. HANDLE outFile=INVALID_HANDLE_VALUE;
  743. HRESULT hr=S_OK;
  744. hr=FS::CreateFile( outFileName,
  745. outFile,
  746. GENERIC_WRITE,
  747. FILE_SHARE_READ,
  748. CREATE_ALWAYS);
  749. if FAILED(hr)
  750. {
  751. MessageBox(NULL,L"Problems to create output file",L"Error",MB_OK);
  752. LOG_HRESULT(hr);
  753. return hr;
  754. }
  755. do
  756. {
  757. AnsiString header;
  758. header = "// This file is generated by OldRepl.exe\r\n"
  759. "// Copyright (c) 2001 Microsoft Corporation\r\n"
  760. "// Jun 2001 lucios\r\n"
  761. "\r\n"
  762. "#include \"headers.hxx\"\r\n"
  763. "#include \"constants.hpp\"\r\n"
  764. "\r\n"
  765. "void setReplacementChanges()\r\n"
  766. "{";
  767. hr = FS::Write(outFile,header);
  768. BREAK_ON_FAILED_HRESULT(hr);
  769. hr=generateChanges
  770. (
  771. dcpromoOld,
  772. dcpromoNew,
  773. LOCALEIDS,
  774. outFile
  775. );
  776. BREAK_ON_FAILED_HRESULT(hr);
  777. hr=generateChanges
  778. (
  779. csv409Old,
  780. csv409New,
  781. LOCALE409,
  782. outFile
  783. );
  784. BREAK_ON_FAILED_HRESULT(hr);
  785. AnsiString tail="\r\n}\r\n";
  786. hr = FS::Write(outFile,tail);
  787. BREAK_ON_FAILED_HRESULT(hr);
  788. //hr=dumpCsv(dcpromoOld,LOCALEIDS,outFile);
  789. //hr=dumpCsv(csv409Old,LOCALE409,outFile);
  790. //BREAK_ON_FAILED_HRESULT(hr);
  791. } while(0);
  792. CloseHandle(outFile);
  793. if(FAILED(hr))
  794. {
  795. MessageBox(NULL,error.c_str(),L"Error",MB_OK);
  796. }
  797. else
  798. {
  799. MessageBox(NULL,L"Generation Successful",L"Success",MB_OK);
  800. }
  801. return 1;
  802. }
  803. */