Source code of Windows XP (NT5)
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.

2722 lines
95 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <private.h>
  5. #include <crt\io.h>
  6. #include <share.h>
  7. #include <time.h>
  8. #include <process.h>
  9. #include <setupapi.h>
  10. #include "rsa.h"
  11. #include "md5.h"
  12. #include "symutil.h"
  13. #include "dbgimage.h"
  14. #include "splitsymx.h"
  15. #include <string.h>
  16. #include "wppfmt.h"
  17. #define BINPLACE_LOG_SYNC_OBJECT "WRITE_BINPLACE_LOG"
  18. #ifndef MOVEFILE_CREATE_HARDLINK
  19. #define MOVEFILE_CREATE_HARDLINK 0x00000010
  20. #endif
  21. #define BINPLACE_ERR 77
  22. #define BINPLACE_OK 0
  23. BOOL fUpDriver;
  24. BOOL fUsage;
  25. BOOL fVerbose;
  26. BOOL fSymChecking;
  27. BOOL fTestMode;
  28. BOOL fSplitSymbols;
  29. BOOL fSetupMode;
  30. BOOL fSetupModeAllFiles;
  31. BOOL fSetupModeScriptFile;
  32. BOOL fPatheticOS;
  33. BOOL fLiveSystem;
  34. BOOL fKeepAttributes;
  35. BOOL fDigitalSign;
  36. BOOL fHardLinks;
  37. BOOL fIgnoreHardLinks;
  38. BOOL fDontLog;
  39. BOOL fPlaceWin95SymFile;
  40. BOOL fNoClassInSymbolsDir;
  41. BOOL fMakeErrorOnDumpCopy;
  42. BOOL fDontExit;
  43. BOOL fForcePlace;
  44. BOOL fSignCode;
  45. BOOL fVerifyLc;
  46. BOOL fWppFmt;
  47. BOOL fCheckDelayload;
  48. BOOL fChangeAsmsToRetailForSymbols;
  49. BOOL fSrcControl;
  50. BOOL fDbgControl;
  51. HINSTANCE hSetupApi;
  52. HINSTANCE hLcManager;
  53. HRESULT (WINAPI * pVerifyLocConstraintA) (IN PCSTR FileName, IN PCSTR LcFileName);
  54. BOOL (WINAPI * pSetupGetIntField) (IN PINFCONTEXT Context, IN DWORD FieldIndex, OUT PINT IntegerValue);
  55. BOOL (WINAPI * pSetupFindFirstLineA) (IN HINF InfHandle, IN PCSTR Section, IN PCSTR Key, OPTIONAL OUT PINFCONTEXT Context );
  56. BOOL (WINAPI * pSetupGetStringFieldA) (IN PINFCONTEXT Context, IN DWORD FieldIndex, OUT PSTR ReturnBuffer, OPTIONAL IN DWORD ReturnBufferSize, OUT PDWORD RequiredSize);
  57. HINF (WINAPI * pSetupOpenInfFileA) ( IN PCSTR FileName, IN PCSTR InfClass, OPTIONAL IN DWORD InfStyle, OUT PUINT ErrorLine OPTIONAL );
  58. HINF (WINAPI * pSetupOpenMasterInf) (VOID);
  59. ULONG SplitFlags = 0;
  60. LPSTR CurrentImageName;
  61. LPSTR PlaceFileName;
  62. LPSTR PlaceRootName;
  63. LPSTR ExcludeFileName;
  64. LPSTR DumpOverride;
  65. LPSTR LayoutInfName;
  66. LPSTR NormalPlaceSubdir;
  67. LPSTR CommandScriptName;
  68. LPSTR SymbolFilePath;
  69. LPSTR PrivateSymbolFilePath;
  70. LPSTR BinplaceLcDir;
  71. LPSTR LcFilePart;
  72. LPSTR szRSDSDllToLoad = NULL;
  73. HINF LayoutInf;
  74. FILE *PlaceFile;
  75. FILE *LogFile;
  76. FILE *CommandScriptFile;
  77. CHAR* gDelayLoadModule;
  78. CHAR* gDelayLoadHandler;
  79. CHAR gFullFileName[MAX_PATH+1];
  80. CHAR gFullDestName[MAX_PATH+1];
  81. CHAR gPublicSymbol[MAX_PATH+1];
  82. CHAR gPrivateSymbol[MAX_PATH+1];
  83. UCHAR SetupFilePath[ MAX_PATH+1 ];
  84. UCHAR DebugFilePath[ MAX_PATH+1 ];
  85. UCHAR PlaceFilePath[ MAX_PATH+1 ];
  86. UCHAR ExcludeFilePath[ MAX_PATH+1 ];
  87. UCHAR DefaultSymbolFilePath[ MAX_PATH+1 ];
  88. UCHAR szAltPlaceRoot[ MAX_PATH+1 ];
  89. UCHAR LcFullFileName[ MAX_PATH+1 ];
  90. UCHAR szExtraInfo[4096];
  91. UCHAR TraceFormatFilePath[ MAX_PATH+1 ] ;
  92. UCHAR LastPdbName[ MAX_PATH+1 ] ;
  93. UCHAR TraceDir[ MAX_PATH+1 ] ;
  94. PEXCLUDE_LIST ExcludeList;
  95. struct {
  96. WORD Machine;
  97. int RC;
  98. CHAR **Argv;
  99. int Argc;
  100. } ImageCheck;
  101. #define DEFAULT_PLACE_FILE "\\public\\sdk\\lib\\placefil.txt"
  102. #define DEFAULT_NTROOT "\\nt"
  103. #define DEFAULT_NTDRIVE "c:"
  104. #define DEFAULT_DUMP "dump"
  105. #define DEFAULT_LCDIR "LcINF"
  106. #define DEFAULT_EXCLUDE_FILE "\\public\\tools\\symbad.txt"
  107. #define DEFAULT_TRACEDIR "TraceFormat"
  108. #define DEFAULT_DELAYLOADDIR "delayload"
  109. typedef struct _CLASS_TABLE {
  110. LPSTR ClassName;
  111. LPSTR ClassLocation;
  112. } CLASS_TABLE, *PCLASS_TABLE;
  113. BOOL
  114. PlaceTheFile();
  115. BOOL
  116. StripCVSymbolPath (
  117. LPSTR DestinationFile
  118. );
  119. typedef
  120. BOOL
  121. (WINAPI *PCREATEHARDLINKA)(
  122. LPCSTR lpFileName,
  123. LPCSTR lpExistingFileName,
  124. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  125. );
  126. PCREATEHARDLINKA pCreateHardLinkA;
  127. BOOL
  128. CopyTheFile(
  129. LPSTR SourceFileName,
  130. LPSTR SourceFilePart,
  131. LPSTR DestinationSubdir,
  132. LPSTR DestinationFilePart
  133. );
  134. BOOL
  135. BinplaceCopyPdb (
  136. LPSTR DestinationFile,
  137. LPSTR SourceFileName, // Used for redist case
  138. BOOL CopyFromSourceOnly,
  139. BOOL StripPrivate,
  140. LPSTR DestinationSymbol,
  141. DWORD LenDestSymbolBuffer
  142. );
  143. BOOL
  144. VerifyFinalImage(
  145. IN PCHAR FileName,
  146. IN BOOL fRetail,
  147. OUT PBOOL BinplaceLc
  148. );
  149. BOOL
  150. SourceIsNewer(
  151. IN LPSTR SourceFile,
  152. IN LPSTR TargetFile
  153. );
  154. BOOL
  155. SetupModeRetailFile(
  156. IN LPSTR FullFileName,
  157. IN LPSTR FileNamePart,
  158. OUT PBOOL PutInDump
  159. );
  160. __inline BOOL
  161. SearchOneDirectory(
  162. IN LPSTR Directory,
  163. IN LPSTR FileToFind,
  164. IN LPSTR SourceFullName,
  165. IN LPSTR SourceFilePart,
  166. OUT PBOOL FoundInTree
  167. )
  168. {
  169. //
  170. // This was way too slow. Just say we didn't find the file.
  171. //
  172. *FoundInTree = FALSE;
  173. return(TRUE);
  174. }
  175. BOOL
  176. FileExists(
  177. IN LPCSTR FileName,
  178. OUT PWIN32_FIND_DATA FindData
  179. );
  180. BOOL
  181. SignWithIDWKey(
  182. IN LPCSTR FileName);
  183. CLASS_TABLE CommonClassTable[] = {
  184. {"retail", "."},
  185. {"system", "system32"},
  186. {"system16","system"},
  187. {"windows", "."},
  188. {"drivers", "system32\\drivers"},
  189. {"drvetc", "system32\\drivers\\etc"},
  190. {"config", "system32\\config"},
  191. {NULL,NULL}
  192. };
  193. CLASS_TABLE i386SpecificClassTable[] = {
  194. {"hal","system32"},
  195. {"printer","system32\\spool\\drivers\\w32x86"},
  196. {"prtprocs","system32\\spool\\prtprocs\\w32x86"},
  197. {NULL,NULL}
  198. };
  199. CLASS_TABLE Amd64SpecificClassTable[] = {
  200. {"hal",".."},
  201. {"printer","system32\\spool\\drivers\\w32amd64"},
  202. {"prtprocs","system32\\spool\\prtprocs\\w32amd64"},
  203. {NULL,NULL}
  204. };
  205. CLASS_TABLE ia64SpecificClassTable[] = {
  206. {"hal",".."},
  207. {"printer","system32\\spool\\drivers\\w32ia64"},
  208. {"prtprocs","system32\\spool\\prtprocs\\w32ia64"},
  209. {NULL,NULL}
  210. };
  211. //
  212. // Names of sections in layout.inx
  213. //
  214. LPCSTR szSourceDisksFiles = "SourceDisksFiles";
  215. LPCSTR szSourceDisksAMD64 = "SourceDisksFiles.amd64";
  216. LPCSTR szSourceDisksX86 = "SourceDisksFiles.x86";
  217. LPCSTR szSourceDisksIA64 = "SourceDisksFiles.ia64";
  218. typedef struct _PLACE_FILE_RECORD {
  219. LPSTR FileNameEntry;
  220. LPSTR FileClass;
  221. } PLACE_FILE_RECORD, *PPLACE_FILE_RECORD;
  222. int MaxNumberOfRecords;
  223. int NumberOfRecords;
  224. PPLACE_FILE_RECORD PlaceFileRecords;
  225. int __cdecl
  226. pfcomp(
  227. const void *e1,
  228. const void *e2
  229. )
  230. {
  231. PPLACE_FILE_RECORD p1;
  232. PPLACE_FILE_RECORD p2;
  233. p1 = (PPLACE_FILE_RECORD)e1;
  234. p2 = (PPLACE_FILE_RECORD)e2;
  235. return (strcmp(p1->FileNameEntry,p2->FileNameEntry));
  236. }
  237. CHAR PlaceFileDir[4096];
  238. CHAR PlaceFileClass[4096];
  239. CHAR PlaceFileEntry[4096];
  240. BOOL
  241. SortPlaceFileRecord()
  242. {
  243. int cfield;
  244. PPLACE_FILE_RECORD NewRecords;
  245. NumberOfRecords = 0;
  246. MaxNumberOfRecords = 0;
  247. //
  248. // get space for 6k records. Grow if need to.
  249. //
  250. MaxNumberOfRecords = 7000;
  251. PlaceFileRecords = (PPLACE_FILE_RECORD) malloc( sizeof(*PlaceFileRecords)*MaxNumberOfRecords );
  252. if ( !PlaceFileRecords ) {
  253. return FALSE;
  254. }
  255. if (fseek(PlaceFile,0,SEEK_SET)) {
  256. free(PlaceFileRecords);
  257. PlaceFileRecords = NULL;
  258. return FALSE;
  259. }
  260. while (fgets(PlaceFileDir,sizeof(PlaceFileDir),PlaceFile)) {
  261. PlaceFileEntry[0] = '\0';
  262. PlaceFileClass[0] = '\0';
  263. cfield = sscanf(
  264. PlaceFileDir,
  265. // "%s %[A-Za-z0-9.,_!@#\\$+=%^&()~ -]s",
  266. "%s %s",
  267. PlaceFileEntry,
  268. PlaceFileClass
  269. );
  270. if (cfield <= 0 || PlaceFileEntry[0] == ';') {
  271. continue;
  272. }
  273. PlaceFileRecords[NumberOfRecords].FileNameEntry = (LPSTR) malloc( strlen(PlaceFileEntry)+1 );
  274. PlaceFileRecords[NumberOfRecords].FileClass = (LPSTR) malloc( strlen(PlaceFileClass)+1 );
  275. if (!PlaceFileRecords[NumberOfRecords].FileClass || !PlaceFileRecords[NumberOfRecords].FileNameEntry) {
  276. if (PlaceFileRecords[NumberOfRecords].FileClass)
  277. free(PlaceFileRecords[NumberOfRecords].FileClass);
  278. if (PlaceFileRecords[NumberOfRecords].FileNameEntry)
  279. free(PlaceFileRecords[NumberOfRecords].FileNameEntry);
  280. free(PlaceFileRecords);
  281. PlaceFileRecords = NULL;
  282. return FALSE;
  283. }
  284. strcpy(PlaceFileRecords[NumberOfRecords].FileNameEntry,PlaceFileEntry);
  285. strcpy(PlaceFileRecords[NumberOfRecords].FileClass,PlaceFileClass);
  286. NumberOfRecords++;
  287. if ( NumberOfRecords >= MaxNumberOfRecords ) {
  288. MaxNumberOfRecords += 200;
  289. NewRecords = (PPLACE_FILE_RECORD) realloc(
  290. PlaceFileRecords,
  291. sizeof(*PlaceFileRecords)*MaxNumberOfRecords
  292. );
  293. if ( !NewRecords ) {
  294. PlaceFileRecords = NULL;
  295. return FALSE;
  296. }
  297. PlaceFileRecords = NewRecords;
  298. }
  299. }
  300. qsort((void *)PlaceFileRecords,(size_t)NumberOfRecords,(size_t)sizeof(*PlaceFileRecords),pfcomp);
  301. return TRUE;
  302. }
  303. PPLACE_FILE_RECORD
  304. LookupPlaceFileRecord(
  305. LPSTR FileName
  306. )
  307. {
  308. LONG High;
  309. LONG Low;
  310. LONG Middle;
  311. LONG Result;
  312. //
  313. // Lookup the name using a binary search.
  314. //
  315. if ( !PlaceFileRecords ) {
  316. return NULL;
  317. }
  318. Low = 0;
  319. High = NumberOfRecords - 1;
  320. while (High >= Low) {
  321. //
  322. // Compute the next probe index and compare the import name
  323. // with the export name entry.
  324. //
  325. Middle = (Low + High) >> 1;
  326. Result = _stricmp(FileName, PlaceFileRecords[Middle].FileNameEntry);
  327. if (Result < 0) {
  328. High = Middle - 1;
  329. } else if (Result > 0) {
  330. Low = Middle + 1;
  331. } else {
  332. break;
  333. }
  334. }
  335. if (High < Low) {
  336. return NULL;
  337. } else {
  338. return &PlaceFileRecords[Middle];
  339. }
  340. }
  341. int __cdecl
  342. main(
  343. int argc,
  344. char *argv[],
  345. char *envp[]
  346. )
  347. {
  348. char c, *p, *OverrideFlags, *s, **newargv;
  349. LPSTR LogFileName = NULL;
  350. LPSTR LcFileName = NULL;
  351. int len = 0;
  352. int i, n;
  353. BOOL NoPrivateSplit = FALSE;
  354. OSVERSIONINFO VersionInformation;
  355. LPTSTR platform;
  356. HANDLE hLogSync;
  357. // Grab the shared log event right away to increase the chances of collisions
  358. // (we would rather not have to create the event object every time)
  359. hLogSync = CreateMutex( NULL, FALSE, BINPLACE_LOG_SYNC_OBJECT );
  360. if (NULL == hLogSync) {
  361. fprintf(stderr, "BINPLACE : error BNP0000: unable to synchronize log access (%lu)\n", GetLastError() );
  362. }
  363. //
  364. // Win 95 can't compare file times very well, this hack neuters the SourceIsNewer function
  365. // on Win 95
  366. //
  367. VersionInformation.dwOSVersionInfoSize = sizeof( VersionInformation );
  368. if (GetVersionEx( &VersionInformation ) && VersionInformation.dwPlatformId != VER_PLATFORM_WIN32_NT) {
  369. fPatheticOS = TRUE;
  370. }
  371. envp;
  372. fUpDriver = FALSE;
  373. fUsage = FALSE;
  374. fVerbose = FALSE;
  375. fSymChecking = FALSE;
  376. fTestMode = FALSE;
  377. fSplitSymbols = FALSE;
  378. fSetupMode = FALSE;
  379. fSetupModeAllFiles = FALSE;
  380. fSetupModeScriptFile = FALSE;
  381. fLiveSystem = FALSE;
  382. fKeepAttributes = FALSE;
  383. fDigitalSign = FALSE;
  384. fHardLinks = FALSE;
  385. fIgnoreHardLinks = FALSE;
  386. fDontExit = FALSE;
  387. fForcePlace = FALSE;
  388. fSignCode = FALSE;
  389. fVerifyLc = FALSE;
  390. fWppFmt = FALSE ;
  391. fSrcControl = FALSE;
  392. fDbgControl = FALSE;
  393. NormalPlaceSubdir = NULL;
  394. pVerifyLocConstraintA = NULL;
  395. gPublicSymbol[0] = '\0';
  396. gPrivateSymbol[0] = '\0';
  397. if (argc < 2) {
  398. goto showUsage;
  399. }
  400. szRSDSDllToLoad = (LPSTR) malloc(MAX_PATH+1);
  401. strcpy( szRSDSDllToLoad, "mspdb70.dll");
  402. LayoutInfName = NULL;
  403. setvbuf(stderr, NULL, _IONBF, 0);
  404. setvbuf(stdout, NULL, _IONBF, 0);
  405. if (!(PlaceFileName = getenv( "BINPLACE_PLACEFILE" ))) {
  406. if ((PlaceFileName = getenv("_NTDRIVE")) == NULL) {
  407. PlaceFileName = DEFAULT_NTDRIVE;
  408. }
  409. strcpy((PCHAR) PlaceFilePath, PlaceFileName);
  410. if ((PlaceFileName = getenv("_NTROOT")) == NULL) {
  411. PlaceFileName = DEFAULT_NTROOT;
  412. }
  413. strcat((PCHAR) PlaceFilePath, PlaceFileName);
  414. strcat((PCHAR) PlaceFilePath, DEFAULT_PLACE_FILE);
  415. PlaceFileName = (PCHAR) PlaceFilePath;
  416. }
  417. if (!(ExcludeFileName = getenv( "BINPLACE_EXCLUDE_FILE" ))) {
  418. if ((ExcludeFileName = getenv("_NTDRIVE")) == NULL) {
  419. ExcludeFileName = DEFAULT_NTDRIVE;
  420. }
  421. strcpy((PCHAR) ExcludeFilePath, ExcludeFileName);
  422. if ((ExcludeFileName = getenv("_NTROOT")) == NULL) {
  423. ExcludeFileName = DEFAULT_NTROOT;
  424. }
  425. strcat((PCHAR) ExcludeFilePath, ExcludeFileName);
  426. strcat((PCHAR) ExcludeFilePath, DEFAULT_EXCLUDE_FILE);
  427. ExcludeFileName = (PCHAR) ExcludeFilePath;
  428. }
  429. if (!(BinplaceLcDir = getenv( "BINPLACE_LCDIR" ))) {
  430. BinplaceLcDir = DEFAULT_LCDIR;
  431. }
  432. if ( getenv("NT_SIGNCODE") != NULL ) {
  433. fSignCode=TRUE;
  434. }
  435. //
  436. // Support Cross compile as well
  437. //
  438. #if defined(_AMD64_)
  439. ImageCheck.Machine = IMAGE_FILE_MACHINE_AMD64;
  440. PlaceRootName = getenv( "_NTAMD64TREE" );
  441. #elif defined(_IA64_)
  442. ImageCheck.Machine = IMAGE_FILE_MACHINE_IA64;
  443. PlaceRootName = getenv( "_NTIA64TREE" );
  444. #else // defined(_X86_)
  445. if ((platform = getenv("AMD64")) != NULL) {
  446. ImageCheck.Machine = IMAGE_FILE_MACHINE_AMD64;
  447. PlaceRootName = getenv( "_NTAMD64TREE" );
  448. } else if ((platform = getenv("IA64")) != NULL) {
  449. ImageCheck.Machine = IMAGE_FILE_MACHINE_IA64;
  450. PlaceRootName = getenv( "_NTIA64TREE" );
  451. } else {
  452. ImageCheck.Machine = IMAGE_FILE_MACHINE_I386;
  453. PlaceRootName = getenv( "_NT386TREE" );
  454. if (!PlaceRootName)
  455. PlaceRootName = getenv( "_NTx86TREE" );
  456. }
  457. #endif
  458. CurrentImageName = NULL;
  459. OverrideFlags = getenv( "BINPLACE_OVERRIDE_FLAGS" );
  460. if (OverrideFlags != NULL) {
  461. s = OverrideFlags;
  462. n = 0;
  463. while (*s) {
  464. while (*s && *s <= ' ')
  465. s += 1;
  466. if (*s) {
  467. n += 1;
  468. while (*s > ' ')
  469. s += 1;
  470. if (*s)
  471. *s++ = '\0';
  472. }
  473. }
  474. if (n) {
  475. newargv = malloc( (argc + n + 1) * sizeof( char * ) );
  476. memcpy( &newargv[n], argv, argc * sizeof( char * ) );
  477. argv = newargv;
  478. argv[ 0 ] = argv[ n ];
  479. argc += n;
  480. s = OverrideFlags;
  481. for (i=1; i<=n; i++) {
  482. while (*s && *s <= ' ')
  483. s += 1;
  484. argv[ i ] = s;
  485. while (*s++)
  486. ;
  487. }
  488. }
  489. }
  490. while (--argc) {
  491. p = *++argv;
  492. if (*p == '/' || *p == '-') {
  493. if (_stricmp(p + 1, "ChangeAsmsToRetailForSymbols") == 0) {
  494. fChangeAsmsToRetailForSymbols = TRUE;
  495. } else {
  496. while (c = *++p)
  497. switch (toupper( c )) {
  498. case '?':
  499. fUsage = TRUE;
  500. break;
  501. case 'A':
  502. SplitFlags |= SPLITSYM_EXTRACT_ALL;
  503. break;
  504. case 'B':
  505. argc--, argv++;
  506. NormalPlaceSubdir = *argv;
  507. break;
  508. case 'C':
  509. if (*(p+1) == 'I' || *(p+1) == 'i') {
  510. char *q;
  511. argc--, argv++;
  512. p = *argv;
  513. ImageCheck.RC = atoi(p);
  514. if (!ImageCheck.RC) {
  515. fprintf( stderr, "BINPLACE : error BNP0000: Invalid return code for -CI option\n");
  516. fUsage = TRUE;
  517. }
  518. while (*p++ != ',');
  519. q = p;
  520. ImageCheck.Argc = 0;
  521. while (*p != '\0')
  522. if (*p++ == ',') ImageCheck.Argc++;
  523. // last option plus extra args for Image file and Argv NULL
  524. ImageCheck.Argc += 3;
  525. ImageCheck.Argv = malloc( ImageCheck.Argc * sizeof( void * ) );
  526. for ( i = 0; i <= ImageCheck.Argc - 3; i++) {
  527. ImageCheck.Argv[i] = q;
  528. while (*q != ',' && *q != '\0') q++;
  529. *q++ = '\0';
  530. }
  531. p--;
  532. ImageCheck.Argv[ImageCheck.Argc-1] = NULL;
  533. } else {
  534. fDigitalSign = TRUE;
  535. }
  536. break;
  537. case 'D':
  538. if (*(p+1) == 'L' || *(p+1) == 'l')
  539. {
  540. argc--, argv++;
  541. p = *argv;
  542. gDelayLoadModule = p;
  543. while (*p != ',')
  544. {
  545. p++;
  546. }
  547. *p = '\0';
  548. p++;
  549. gDelayLoadHandler = p;
  550. while (*p != '\0')
  551. {
  552. p++;
  553. }
  554. p--;
  555. if (gDelayLoadModule[0] == '\0' ||
  556. gDelayLoadHandler[0] == '\0')
  557. {
  558. fprintf(stderr, "BINPLACE : error BNP0000: Invalid switch for -dl option\n");
  559. fUsage = TRUE;
  560. }
  561. else
  562. {
  563. fCheckDelayload = TRUE;
  564. }
  565. }
  566. else
  567. {
  568. argc--, argv++;
  569. DumpOverride = *argv;
  570. }
  571. break;
  572. case 'E':
  573. fDontExit = TRUE;
  574. break;
  575. case 'F':
  576. fForcePlace = TRUE;
  577. break;
  578. case 'G':
  579. argc--, argv++;
  580. LcFileName = *argv;
  581. break;
  582. case 'H':
  583. if ((VersionInformation.dwPlatformId != VER_PLATFORM_WIN32_NT) ||
  584. (VersionInformation.dwMajorVersion < 5) ||
  585. (pCreateHardLinkA = (PCREATEHARDLINKA)GetProcAddress( GetModuleHandle( "KERNEL32" ),
  586. "CreateHardLinkA"
  587. )
  588. ) == NULL
  589. ) {
  590. fprintf( stderr, "BINPLACE: Hard links not supported. Defaulting to CopyFile\n" );
  591. fHardLinks = FALSE;
  592. } else {
  593. fHardLinks = TRUE;
  594. }
  595. break;
  596. case 'I':
  597. argc--, argv++;
  598. LayoutInfName = *argv;
  599. break;
  600. case 'J':
  601. fSymChecking = TRUE;
  602. break;
  603. case 'K':
  604. fKeepAttributes = TRUE;
  605. break;
  606. case 'L':
  607. fLiveSystem++;
  608. break;
  609. case 'M':
  610. fMakeErrorOnDumpCopy = TRUE;
  611. break;
  612. case 'N':
  613. argc--, argv++;
  614. PrivateSymbolFilePath = *argv;
  615. break;
  616. case 'O':
  617. argc--, argv++;
  618. if (PlaceRootName != NULL) {
  619. strcpy(szAltPlaceRoot,PlaceRootName);
  620. strcat(szAltPlaceRoot,"\\");
  621. strcat(szAltPlaceRoot,*argv);
  622. PlaceRootName = szAltPlaceRoot;
  623. }
  624. break;
  625. case 'P':
  626. argc--, argv++;
  627. PlaceFileName = *argv;
  628. break;
  629. case 'Q':
  630. fDontLog = TRUE;
  631. break;
  632. case 'R':
  633. argc--, argv++;
  634. PlaceRootName = *argv;
  635. break;
  636. case 'S':
  637. argc--, argv++;
  638. SymbolFilePath = *argv;
  639. fSplitSymbols = TRUE;
  640. fIgnoreHardLinks = TRUE;
  641. break;
  642. case 'T':
  643. fTestMode = TRUE;
  644. break;
  645. case 'U':
  646. fUpDriver = TRUE;
  647. break;
  648. case 'V':
  649. fVerbose = TRUE;
  650. break;
  651. case 'W':
  652. fPlaceWin95SymFile = TRUE;
  653. break;
  654. case 'X':
  655. SplitFlags |= SPLITSYM_REMOVE_PRIVATE;
  656. break;
  657. case 'Y':
  658. fNoClassInSymbolsDir = TRUE;
  659. break;
  660. case 'Z':
  661. NoPrivateSplit = TRUE;
  662. break;
  663. case '!':
  664. hSetupApi = LoadLibrary("setupapi.dll");
  665. if (hSetupApi) {
  666. (VOID *) pSetupGetIntField = GetProcAddress(hSetupApi, "SetupGetIntField");
  667. (VOID *) pSetupFindFirstLineA = GetProcAddress(hSetupApi, "SetupFindFirstLineA");
  668. (VOID *) pSetupGetStringFieldA = GetProcAddress(hSetupApi, "SetupGetStringFieldA");
  669. (VOID *) pSetupOpenInfFileA = GetProcAddress(hSetupApi, "SetupOpenInfFileA");
  670. (VOID *) pSetupOpenMasterInf = GetProcAddress(hSetupApi, "SetupOpenMasterInf");
  671. if (pSetupGetIntField &&
  672. pSetupFindFirstLineA &&
  673. pSetupGetStringFieldA &&
  674. pSetupOpenInfFileA &&
  675. pSetupOpenMasterInf) {
  676. fSetupMode = TRUE;
  677. } else {
  678. printf("Unable to bind to the necessary SETUPAPI.DLL functions... Ignoring setup mode switch\n");
  679. }
  680. }
  681. if (*(p+1) == '!') {
  682. p++;
  683. if (fSetupMode)
  684. fSetupModeAllFiles = TRUE;
  685. if (*(p+1) == '!') {
  686. p++;
  687. argc--, argv++;
  688. CommandScriptName = *argv;
  689. if (fSetupMode) {
  690. fSetupModeScriptFile = TRUE;
  691. CommandScriptFile = fopen(CommandScriptName, "a");
  692. if (!CommandScriptFile) {
  693. fprintf(stderr,"BINPLACE : fatal error BNP0000: fopen of script file %s failed %d\n",CommandScriptName,GetLastError());
  694. exit(BINPLACE_ERR);
  695. }
  696. }
  697. } else {
  698. fIgnoreHardLinks = TRUE;
  699. }
  700. } else {
  701. fIgnoreHardLinks = TRUE;
  702. }
  703. break;
  704. case ':': // Simple (== crude) escape mechanism as all the letters are used
  705. // -:XXX can add extra options if need be
  706. // For now just handle TMF, Trace Message Format processing of PDB's
  707. if ((strlen(p) >= 3) && ((toupper(*(p+1)) == 'T') && (toupper(*(p+2)) == 'M') && (toupper(*(p+3))) == 'F')) {
  708. LPSTR tfile ;
  709. // If the RUNWPP operation ran this option will be automatically added
  710. p += 3 ; // Gobble up the TMF
  711. fWppFmt = TRUE ; // Need to package up the Software Tracing Formats
  712. strncpy(TraceDir,DEFAULT_TRACEDIR,MAX_PATH) ; //Append to PrivateSymbolsPath
  713. //If no default override.
  714. tfile = getenv("TRACE_FORMAT_PATH"); //Has Path been overriden?
  715. if (tfile != NULL) {
  716. _snprintf(TraceFormatFilePath, MAX_PATH, "%s", tfile);
  717. if (fVerbose) {
  718. fprintf( stdout, "BINPLACE : warning BNP0000: Trace Formats file path set to %s\n", TraceFormatFilePath ) ;
  719. }
  720. } else {
  721. TraceFormatFilePath[0] = '\0' ;
  722. }
  723. } else if ((strlen(p) >= 3) && ((toupper(*(p+1)) == 'S') && (toupper(*(p+2)) == 'R') && (toupper(*(p+3))) == 'C')) {
  724. // This is the option for turning on creating a cvdump for the pdb for
  725. // source control.
  726. p += 3;
  727. fSrcControl=TRUE;
  728. } else if ((strlen(p) >= 3) && ((toupper(*(p+1)) == 'D') && (toupper(*(p+2)) == 'B') && (toupper(*(p+3))) == 'G')) {
  729. // This is the option for turning on creating a cvdump for the pdb for
  730. // source control.
  731. p += 3;
  732. fDbgControl=TRUE;
  733. }
  734. break;
  735. default:
  736. fprintf( stderr, "BINPLACE : error BNP0000: Invalid switch - /%c\n", c );
  737. fUsage = TRUE;
  738. break;
  739. }
  740. }
  741. if ( fUsage ) {
  742. showUsage:
  743. fputs(
  744. "usage: binplace [switches] image-names... \n"
  745. "where: [-?] display this message\n"
  746. " [-a] Used with -s, extract all symbols\n"
  747. " [-b subdir] put file in subdirectory of normal place\n"
  748. " [-c] digitally sign image with IDW key\n"
  749. " [-d dump-override]\n"
  750. " [-:DBG] Don't binplace DBG files. If -j is present, don't binplace \n"
  751. " binaries that point to DBG files.\n"
  752. " [-e] don't exit if a file in list could not be binplaced\n"
  753. " [-f] force placement by disregarding file timestamps\n"
  754. " [-g lc-file] verify image with localization constraint file\n"
  755. " [-h] modifies behavior to use hard links instead of CopyFile.\n"
  756. " (ignored if -s, -! or -!! is present)\n"
  757. " [-i layout-inf] Used with -!, -!! or -!!!, override master inf location\n"
  758. " [-j] verify proper symbols exist before copying\n"
  759. " [-k] keep attributes (don't turn off archive)\n"
  760. " [-l] operate over a live system\n"
  761. " [-n <Path>] Used with -x - Private pdb symbol path\n"
  762. " [-o place-root-subdir] alternate project subdirectory\n"
  763. " [-p place-file]\n"
  764. " [-q] suppress writing to log file %BINPLACE_LOG%\n"
  765. " [-r place-root]\n"
  766. " [-s Symbol file path] split symbols from image files\n"
  767. " [-:SRC] Process the PDB for source indexing\n"
  768. " [-t] test mode\n"
  769. " [-:TMF] Process the PDB for Trace Format files\n"
  770. " [-u] UP driver\n"
  771. " [-v] verbose output\n"
  772. " [-w] copy the Win95 Sym file to the symbols tree\n"
  773. " [-x] Used with -s, delete private symbolic when splitting\n"
  774. " [-y] Used with -s, don't create class subdirs in the symbols tree\n"
  775. " [-z] ignore -x if present\n"
  776. " [-!] setup mode (ignore optional files)\n"
  777. " [-!!] setup mode (copy optional files)\n"
  778. " [-!!! script-file] setup mode with command script\n"
  779. " [-ci <rc,app,-arg0,-argv1,-argn>]\n"
  780. " rc=application error return code,\n"
  781. " app=application used to check images,\n"
  782. " -arg0..-argn=application options\n"
  783. " [-dl <modulename,delay-load handler>] (run dlcheck on this file)\n"
  784. "\n"
  785. "BINPLACE looks for the following environment variable names:\n"
  786. " BINPLACE_EXCLUDE_FILE - full path name to symbad.txt\n"
  787. " BINPLACE_OVERRIDE_FLAGS - may contain additional switches\n"
  788. " BINPLACE_PLACEFILE - default value for -p flag\n"
  789. " _NT386TREE - default value for -r flag on x86 platform\n"
  790. " _NTAMD64TREE - default value for -r flag on AMD64 platform\n"
  791. " _NTIA64TREE - default value for -r flag on IA64 platform\n"
  792. " TRACE_FORMAT_PATH - set the path for Trace Format Files\n"
  793. "\n"
  794. ,stderr
  795. );
  796. exit(BINPLACE_ERR);
  797. }
  798. } else {
  799. WIN32_FIND_DATA FindData;
  800. HANDLE h;
  801. if (!PlaceRootName) {
  802. // If there's no root, just exit.
  803. exit(BINPLACE_OK);
  804. }
  805. //
  806. // Workaround for bogus setargv: ignore directories
  807. //
  808. if (NoPrivateSplit) {
  809. SplitFlags &= ~SPLITSYM_REMOVE_PRIVATE;
  810. }
  811. h = FindFirstFile(p,&FindData);
  812. if (h != INVALID_HANDLE_VALUE) {
  813. FindClose(h);
  814. if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  815. if ( fVerbose ) {
  816. fprintf(stdout,"BINPLACE : warning BNP0000: ignoring directory %s\n",p);
  817. }
  818. continue;
  819. }
  820. }
  821. CurrentImageName = p;
  822. // If this is a dbg, don't binplace it
  823. if ( fDbgControl && (strlen(p) > 4) &&
  824. (strcmp(p+strlen(p)-4, ".dbg")== 0 ) ) {
  825. fprintf(stderr, "BINPLACE : warning BNP0000: Dbg files not allowed. Use dbgtopdb.exe to remove %s.\n",p);
  826. fprintf(stderr, "BINPLACE : warning BNP0000: This will be an error after May 18, 2001 - problems, contact BarbKess.\n");
  827. // exit(BINPLACE_ERR);
  828. }
  829. //
  830. // If the master place file has not been opened, open
  831. // it up.
  832. //
  833. if ( !PlaceFile ) {
  834. PlaceFile = fopen(PlaceFileName, "rt");
  835. if (!PlaceFile) {
  836. fprintf(stderr,"BINPLACE : fatal error BNP0000: fopen of placefile %s failed %d\n",PlaceFileName,GetLastError());
  837. exit(BINPLACE_ERR);
  838. }
  839. if (fSetupMode && !fSetupModeScriptFile) {
  840. SortPlaceFileRecord();
  841. }
  842. }
  843. //
  844. // Check for bogus -g lc-file switch
  845. //
  846. if ( LcFileName != NULL ) {
  847. h = FindFirstFile(LcFileName, &FindData);
  848. if (h == INVALID_HANDLE_VALUE ||
  849. (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  850. if (fVerbose ) {
  851. fprintf(stdout,"BINPLACE : warning BNP0000: invalid file %s. Ignoring -G switch.\n", LcFileName);
  852. }
  853. LcFileName = NULL;
  854. }
  855. if (h != INVALID_HANDLE_VALUE) {
  856. FindClose(h);
  857. }
  858. }
  859. if ( LcFileName != NULL ) {
  860. DWORD cb = GetFullPathName(LcFileName,MAX_PATH+1,LcFullFileName,&LcFilePart);
  861. if (!cb || cb > MAX_PATH+1) {
  862. fprintf(stderr,"BINPLACE : fatal error BNP0000: GetFullPathName %s failed %d\n",LcFileName, GetLastError());
  863. exit(BINPLACE_ERR);
  864. }
  865. hLcManager = LoadLibraryA("lcman.DLL");
  866. if (hLcManager != NULL) {
  867. (VOID *) pVerifyLocConstraintA = GetProcAddress(hLcManager, "VerifyLocConstraintA");
  868. }
  869. if (pVerifyLocConstraintA != NULL) {
  870. fVerifyLc = TRUE;
  871. } else {
  872. fprintf(stdout,"BINPLACE : warning BNP0000: Unable to bind to the necessary LCMAN.DLL functions... Ignoring -G switch\n");
  873. }
  874. }
  875. // Get the Exclude List
  876. ExcludeList = GetExcludeList( ExcludeFileName );
  877. if (PlaceRootName == NULL) {
  878. fprintf(stderr,"BINPLACE : fatal error BNP0000: Place Root not defined - exiting.\n");
  879. exit(BINPLACE_ERR);
  880. }
  881. // If the SymbolFilePath has not been set, make a default value.
  882. if (!SymbolFilePath) {
  883. strcpy(DefaultSymbolFilePath, PlaceRootName);
  884. strcat(DefaultSymbolFilePath, "\\symbols");
  885. SymbolFilePath = DefaultSymbolFilePath;
  886. }
  887. if ( !PlaceTheFile() ) {
  888. if (fDontExit) {
  889. fprintf(stderr,"BINPLACE : error BNP0000: Unable to place file %s.\n",CurrentImageName);
  890. } else {
  891. fprintf(stderr,"BINPLACE : fatal error BNP0000: Unable to place file %s - exiting.\n",CurrentImageName);
  892. exit(BINPLACE_ERR);
  893. }
  894. }
  895. if ( !fDontLog) {
  896. if (hLogSync) {
  897. WaitForSingleObject(hLogSync, INFINITE);
  898. }
  899. if ((LogFileName = getenv("BINPLACE_LOG")) != NULL) {
  900. UINT cRetries = 25;
  901. if (!MakeSureDirectoryPathExists(LogFileName)) {
  902. fprintf(stderr,"BINPLACE : error BNP0000: Unable to make directory to \"%s\"\n", LogFileName);
  903. }
  904. do
  905. {
  906. LogFile = _fsopen(LogFileName, "a", _SH_DENYWR);
  907. Sleep(0L); // give up time-slice
  908. } while (!LogFile && --cRetries > 0);
  909. if ( !LogFile ) {
  910. fprintf(stderr,"BINPLACE : error BNP0000: fopen of log file %s failed %d\n", LogFileName,GetLastError());
  911. } else {
  912. time_t Time;
  913. FILE *fSlmIni;
  914. UCHAR szProject[MAX_PATH];
  915. UCHAR szSlmServer[MAX_PATH];
  916. UCHAR szEnlistment[MAX_PATH];
  917. UCHAR szSlmDir[MAX_PATH];
  918. UCHAR *szTime="";
  919. char szPublicSymbol[MAX_PATH+1],
  920. szPrivateSymbol[MAX_PATH+1],
  921. *pFile;
  922. // Get some other interesting info.
  923. fSlmIni = fopen("slm.ini", "r");
  924. if (fSlmIni) {
  925. fgets(szProject, sizeof(szProject), fSlmIni);
  926. fgets(szSlmServer, sizeof(szSlmServer), fSlmIni);
  927. fgets(szEnlistment, sizeof(szEnlistment), fSlmIni);
  928. fgets(szSlmDir, sizeof(szSlmDir), fSlmIni);
  929. // Get rid of the trailing newlines
  930. szProject[strlen(szProject)-1] = '\0';
  931. szSlmServer[strlen(szSlmServer)-1] = '\0';
  932. szSlmDir[strlen(szSlmDir)-1] = '\0';
  933. fclose(fSlmIni);
  934. } else {
  935. szSlmServer[0] = '\0';
  936. szProject[0] = '\0';
  937. szSlmDir[0] = '\0';
  938. }
  939. Time = time(NULL);
  940. szTime = ctime(&Time);
  941. if ( *szTime ) szTime[ strlen(szTime) - 1] = '\0'; // strip off newline
  942. sprintf(szExtraInfo,
  943. "%s\t%s\t%s\t%s",
  944. szSlmServer,
  945. szProject,
  946. szSlmDir,
  947. szTime);
  948. if ('\0' != *gPublicSymbol)
  949. {
  950. GetFullPathName( gPublicSymbol,
  951. MAX_PATH + 1,
  952. szPublicSymbol,
  953. &pFile );
  954. }
  955. else
  956. {
  957. szPublicSymbol[0] = '\0';
  958. }
  959. if ('\0' != *gPrivateSymbol)
  960. {
  961. GetFullPathName( gPrivateSymbol,
  962. MAX_PATH + 1,
  963. szPrivateSymbol,
  964. &pFile );
  965. }
  966. else
  967. {
  968. szPrivateSymbol[0] = '\0';
  969. }
  970. len = fprintf(LogFile,"%s\t%s\t%s\t%s\t%s\n",
  971. gFullFileName,
  972. szExtraInfo,
  973. gFullDestName,
  974. szPublicSymbol,
  975. szPrivateSymbol);
  976. if ( len < 0 ) {
  977. fprintf(stderr,"BINPLACE : error BNP0000: write to log file %s failed %d\n", LogFileName, GetLastError());
  978. }
  979. fclose(LogFile);
  980. }
  981. }
  982. if (hLogSync) {
  983. ReleaseMutex(hLogSync);
  984. }
  985. }
  986. }
  987. }
  988. exit(BINPLACE_OK);
  989. return BINPLACE_OK;
  990. }
  991. BOOL
  992. PlaceTheFile()
  993. {
  994. CHAR FullFileName[MAX_PATH+1];
  995. LPSTR PlaceFileNewName;
  996. LPSTR FilePart;
  997. LPSTR Separator;
  998. LPSTR PlaceFileClassPart;
  999. DWORD cb;
  1000. int cfield;
  1001. PCLASS_TABLE ClassTablePointer;
  1002. BOOLEAN ClassMatch;
  1003. BOOL fCopyResult;
  1004. LPSTR Extension;
  1005. BOOL PutInDump;
  1006. BOOL PutInDebug = FALSE;
  1007. BOOL PutInLcDir = FALSE;
  1008. cb = GetFullPathName(CurrentImageName,MAX_PATH+1,FullFileName,&FilePart);
  1009. if (!cb || cb > MAX_PATH+1) {
  1010. fprintf(stderr,"BINPLACE : fatal error BNP0000: GetFullPathName failed %d\n",GetLastError());
  1011. return FALSE;
  1012. }
  1013. strcpy(gFullFileName,FullFileName);
  1014. if (fVerbose) {
  1015. fprintf(stdout,"BINPLACE : warning BNP0000: Looking at file %s\n",FilePart);
  1016. }
  1017. Extension = strrchr(FilePart,'.');
  1018. if (Extension) {
  1019. if (!_stricmp(Extension,".DBG")) {
  1020. PutInDebug = TRUE;
  1021. }
  1022. else if (!_stricmp(Extension,".LC")) {
  1023. PutInLcDir = TRUE;
  1024. }
  1025. }
  1026. if (!DumpOverride) {
  1027. if (fSetupMode && !fSetupModeScriptFile) {
  1028. PPLACE_FILE_RECORD PfRec;
  1029. PfRec = LookupPlaceFileRecord(FilePart);
  1030. if ( PfRec ) {
  1031. strncpy(PlaceFileEntry,PfRec->FileNameEntry, sizeof(PlaceFileEntry));
  1032. strncpy(PlaceFileClass,PfRec->FileClass, sizeof(PlaceFileClass));
  1033. PlaceFileNewName = NULL;
  1034. goto fastfound;
  1035. }
  1036. }
  1037. if (fseek(PlaceFile,0,SEEK_SET)) {
  1038. fprintf(stderr,"BINPLACE : fatal error BNP0000: fseek(PlaceFile,0,SEEK_SET) failed %d\n",GetLastError());
  1039. return FALSE;
  1040. }
  1041. while (fgets(PlaceFileDir,sizeof(PlaceFileDir),PlaceFile)) {
  1042. PlaceFileEntry[0] = '\0';
  1043. PlaceFileClass[0] = '\0';
  1044. cfield = sscanf(
  1045. PlaceFileDir,
  1046. // "%s %[A-Za-z0-9.,_!@#\\$+=%^&()~ -]s",
  1047. "%s %s",
  1048. PlaceFileEntry,
  1049. PlaceFileClass
  1050. );
  1051. if (cfield <= 0 || PlaceFileEntry[0] == ';') {
  1052. continue;
  1053. }
  1054. if (PlaceFileNewName = strchr(PlaceFileEntry,'!')) {
  1055. *PlaceFileNewName++ = '\0';
  1056. }
  1057. if (!_stricmp(FilePart,PlaceFileEntry)) {
  1058. fastfound:
  1059. //
  1060. // now that we have the file and class, search the
  1061. // class tables for the directory.
  1062. //
  1063. Separator = PlaceFileClass - 1;
  1064. while (Separator) {
  1065. PlaceFileClassPart = Separator+1;
  1066. Separator = strchr(PlaceFileClassPart,':');
  1067. if (Separator) {
  1068. *Separator = '\0';
  1069. }
  1070. //
  1071. // If the class is "retail" and we're in Setup mode,
  1072. // handle this file specially. Setup mode is used to
  1073. // incrementally binplace files into an existing installation.
  1074. //
  1075. SetupFilePath[0] = '\0';
  1076. if (fSetupMode && !_stricmp(PlaceFileClassPart,"retail")) {
  1077. if (SetupModeRetailFile(FullFileName,FilePart,&PutInDump)) {
  1078. //
  1079. // No error. Either the file was handled or we need to
  1080. // put it in the dump directory.
  1081. //
  1082. if (PutInDump) {
  1083. fCopyResult = CopyTheFile(
  1084. FullFileName,
  1085. FilePart,
  1086. (DumpOverride ? DumpOverride : DEFAULT_DUMP),
  1087. NULL
  1088. );
  1089. } else {
  1090. fCopyResult = TRUE;
  1091. }
  1092. } else {
  1093. //
  1094. // Got an error, return error status.
  1095. //
  1096. fCopyResult = FALSE;
  1097. }
  1098. if (!fSetupModeScriptFile) {
  1099. return(fCopyResult);
  1100. }
  1101. }
  1102. PlaceFileDir[0]='\0';
  1103. ClassMatch = FALSE;
  1104. ClassTablePointer = &CommonClassTable[0];
  1105. while (ClassTablePointer->ClassName) {
  1106. if (!_stricmp(ClassTablePointer->ClassName,PlaceFileClassPart)) {
  1107. strcpy(PlaceFileDir,ClassTablePointer->ClassLocation);
  1108. ClassMatch = TRUE;
  1109. //
  1110. // If the class is a driver and a UP driver is
  1111. // specified, then put the driver in the UP
  1112. // subdirectory.
  1113. //
  1114. // Do the same for retail. We assume the -u switch is passed
  1115. // only when actually needed.
  1116. //
  1117. if (fUpDriver
  1118. && ( !_stricmp(PlaceFileClass,"drivers")
  1119. || !_stricmp(PlaceFileClass,"retail"))) {
  1120. strcat(PlaceFileDir,"\\up");
  1121. }
  1122. break;
  1123. }
  1124. ClassTablePointer++;
  1125. }
  1126. if (!ClassMatch) {
  1127. //
  1128. // Search Specific classes
  1129. //
  1130. // We need to support cross compiling here.
  1131. LPTSTR platform;
  1132. #if defined(_AMD64_)
  1133. ClassTablePointer = &Amd64SpecificClassTable[0];
  1134. #elif defined(_IA64_)
  1135. ClassTablePointer = &ia64SpecificClassTable[0];
  1136. #else // defined(_X86_)
  1137. ClassTablePointer = &i386SpecificClassTable[0];
  1138. if ((platform = getenv("AMD64")) != NULL) {
  1139. ClassTablePointer = &Amd64SpecificClassTable[0];
  1140. } else if ((platform = getenv("IA64")) != NULL) {
  1141. ClassTablePointer = &ia64SpecificClassTable[0];
  1142. }
  1143. #endif
  1144. while (ClassTablePointer->ClassName) {
  1145. if (!_stricmp(ClassTablePointer->ClassName,PlaceFileClassPart)) {
  1146. strcpy(PlaceFileDir,ClassTablePointer->ClassLocation);
  1147. ClassMatch = TRUE;
  1148. break;
  1149. }
  1150. ClassTablePointer++;
  1151. }
  1152. }
  1153. if (!ClassMatch) {
  1154. char * asterisk;
  1155. //
  1156. // Still not found in class table. Use the class as the
  1157. // directory
  1158. //
  1159. if ( fVerbose ) {
  1160. fprintf(stderr,"BINPLACE : warning BNP0000: Class %s Not found in Class Tables\n",PlaceFileClassPart);
  1161. }
  1162. if ( asterisk = strchr( PlaceFileClassPart, '*')) {
  1163. //
  1164. // Expand * to platform
  1165. //
  1166. LPTSTR platform;
  1167. ULONG PlatformSize;
  1168. LPTSTR PlatformPath;
  1169. #if defined(_AMD64_)
  1170. PlatformSize = 5;
  1171. PlatformPath = TEXT("amd64");
  1172. #elif defined(_IA64_)
  1173. PlatformSize = 4;
  1174. PlatformPath = TEXT("ia64");
  1175. #else // defined(_X86_)
  1176. PlatformSize = 4;
  1177. PlatformPath = TEXT("i386");
  1178. if ((platform = getenv("IA64")) != NULL) {
  1179. PlatformPath = TEXT("ia64");
  1180. } else if ((platform = getenv("AMD64")) != NULL) {
  1181. PlatformSize = 5;
  1182. PlatformPath = TEXT("amd64");
  1183. }
  1184. #endif
  1185. strncpy(PlaceFileDir,PlaceFileClassPart, (int)(asterisk - PlaceFileClassPart));
  1186. strcpy(PlaceFileDir + (asterisk - PlaceFileClassPart), PlatformPath);
  1187. strcpy(PlaceFileDir + (asterisk - PlaceFileClassPart) + PlatformSize, asterisk + 1);
  1188. } else {
  1189. strcpy(PlaceFileDir,PlaceFileClassPart);
  1190. }
  1191. }
  1192. if (SetupFilePath[0] == '\0') {
  1193. lstrcpy(SetupFilePath, PlaceFileDir);
  1194. lstrcat(SetupFilePath, "\\");
  1195. lstrcat(SetupFilePath, FilePart);
  1196. }
  1197. if (NormalPlaceSubdir) {
  1198. strcat(PlaceFileDir,"\\");
  1199. strcat(PlaceFileDir,NormalPlaceSubdir);
  1200. }
  1201. fCopyResult = CopyTheFile(FullFileName,FilePart,PlaceFileDir,PlaceFileNewName);
  1202. if (!fCopyResult) {
  1203. break;
  1204. }
  1205. }
  1206. return(fCopyResult);
  1207. }
  1208. }
  1209. }
  1210. if (fMakeErrorOnDumpCopy) {
  1211. fprintf(stderr, "BINPLACE : error BNP0000: File '%s' is not listed in '%s'. Copying to dump.\n", FullFileName, PlaceFileName);
  1212. }
  1213. return CopyTheFile(
  1214. FullFileName,
  1215. FilePart,
  1216. PutInDebug ? "Symbols" : (PutInLcDir ? BinplaceLcDir : (DumpOverride ? DumpOverride : DEFAULT_DUMP)),
  1217. NULL
  1218. );
  1219. }
  1220. BOOL
  1221. CopyTheFile(
  1222. LPSTR SourceFileName,
  1223. LPSTR SourceFilePart,
  1224. LPSTR DestinationSubdir,
  1225. LPSTR DestinationFilePart
  1226. )
  1227. {
  1228. CHAR DestinationFile[MAX_PATH+1];
  1229. CHAR TmpDestinationFile[MAX_PATH];
  1230. CHAR TmpDestinationDir[MAX_PATH];
  1231. CHAR DestinationLcFile[MAX_PATH+1];
  1232. char Drive[_MAX_DRIVE];
  1233. char Dir[_MAX_DIR];
  1234. char Ext[_MAX_EXT];
  1235. char Name[_MAX_FNAME];
  1236. char TmpName[_MAX_FNAME];
  1237. char TmpPath[_MAX_PATH];
  1238. char FileSystemType[8];
  1239. char DriveRoot[4];
  1240. CHAR *TmpSymbolFilePath;
  1241. CHAR *pFile;
  1242. DWORD dwFileSystemFlags;
  1243. DWORD dwMaxCompLength;
  1244. CHAR ErrMsg[MAX_SYM_ERR];
  1245. BOOL fBinplaceLc;
  1246. if ( !PlaceRootName ) {
  1247. fprintf(stderr,"BINPLACE : warning BNP0000: PlaceRoot is not specified\n");
  1248. return FALSE;
  1249. }
  1250. if (fCheckDelayload && !_stricmp(SourceFilePart, gDelayLoadModule))
  1251. {
  1252. strcpy(TmpDestinationFile, PlaceRootName);
  1253. strcat(TmpDestinationFile, "\\");
  1254. strcat(TmpDestinationFile, DEFAULT_DELAYLOADDIR);
  1255. strcat(TmpDestinationFile, "\\");
  1256. strcat(TmpDestinationFile, SourceFilePart);
  1257. strcat(TmpDestinationFile, ".ini");
  1258. if (!MakeSureDirectoryPathExists(TmpDestinationFile))
  1259. {
  1260. fprintf(stderr, "BINPLACE : error BNP0000: Unable to create directory path '%s' (%u)\n", TmpDestinationFile, GetLastError());
  1261. }
  1262. else
  1263. {
  1264. WritePrivateProfileString("Default", "DelayLoadHandler", gDelayLoadHandler, TmpDestinationFile);
  1265. strcpy(TmpDestinationDir,".\\"); //default to "retail"
  1266. if ((*DestinationSubdir != '.') && (*(DestinationSubdir+1) != '\0'))
  1267. {
  1268. strcpy(TmpDestinationDir,DestinationSubdir);
  1269. strcat(TmpDestinationDir,"\\");
  1270. }
  1271. WritePrivateProfileString("Default", "DestinationDir", TmpDestinationDir, TmpDestinationFile);
  1272. }
  1273. }
  1274. //
  1275. // We also neuter SourceIsNewer on FAT partitions since they have a 2 second
  1276. // file time granularity
  1277. //
  1278. _splitpath(SourceFileName, DriveRoot, Dir, NULL, NULL);
  1279. lstrcat(DriveRoot, "\\");
  1280. GetVolumeInformation(DriveRoot, NULL, 0, NULL, &dwMaxCompLength, &dwFileSystemFlags, FileSystemType, 7);
  1281. if (lstrcmpi(FileSystemType, "FAT") == 0 || lstrcmpi(FileSystemType, "FAT32") == 0)
  1282. fPatheticOS = TRUE;
  1283. strcpy(DestinationFile,PlaceRootName);
  1284. strcat(DestinationFile,"\\");
  1285. strcat(DestinationFile,DestinationSubdir);
  1286. strcat(DestinationFile,"\\");
  1287. strcpy (TmpDestinationDir, DestinationFile);
  1288. if (!MakeSureDirectoryPathExists(DestinationFile)) {
  1289. fprintf(stderr, "BINPLACE : error BNP0000: Unable to create directory path '%s' (%u)\n",
  1290. DestinationFile, GetLastError()
  1291. );
  1292. }
  1293. if (DestinationFilePart) {
  1294. strcat(DestinationFile,DestinationFilePart);
  1295. } else {
  1296. strcat(DestinationFile,SourceFilePart);
  1297. }
  1298. GetFullPathName(DestinationFile, MAX_PATH+1, gFullDestName, &pFile);
  1299. if (!fSetupMode && (fVerbose || fTestMode)) {
  1300. fprintf(stdout,"BINPLACE : warning BNP0000: place %s in %s\n",SourceFileName,DestinationFile);
  1301. }
  1302. if (!fSetupMode) {
  1303. ULONG SymbolFlag = IGNORE_IF_SPLIT;
  1304. BOOL fRetail = (*DestinationSubdir == '.') && (*(DestinationSubdir+1) == '\0');
  1305. if (SourceIsNewer(SourceFileName,DestinationFile)) {
  1306. fprintf(stdout, "binplace %s\n", SourceFileName);
  1307. if (!VerifyFinalImage(SourceFileName, fRetail, &fBinplaceLc))
  1308. return FALSE;
  1309. // Verify Symbols
  1310. if (fRetail && fSymChecking && !fSignCode) {
  1311. _splitpath(SourceFileName,Drive, Dir, Name, Ext );
  1312. strcpy(TmpName,Name);
  1313. strcat(TmpName,Ext);
  1314. strcpy(TmpPath,Drive);
  1315. strcat(TmpPath,Dir);
  1316. if ( fDbgControl ) {
  1317. SymbolFlag=ERROR_IF_SPLIT | ERROR_IF_NOT_SPLIT;
  1318. }
  1319. if (!CheckSymbols(ErrMsg, TmpPath,SourceFileName, NULL,
  1320. SymbolFlag,FALSE,
  1321. (LPTSTR) szRSDSDllToLoad ) ) {
  1322. if ( !InExcludeList(TmpName,ExcludeList) ) {
  1323. fprintf(stderr,"BINPLACE : error BNP0000: %s",ErrMsg);
  1324. return FALSE;
  1325. }
  1326. }
  1327. }
  1328. }
  1329. }
  1330. if (!fTestMode) {
  1331. //
  1332. // In Setup mode, copy the file only if it's newer than
  1333. // the one that's already there.
  1334. //
  1335. if (!fSetupModeScriptFile) {
  1336. if (SourceIsNewer(SourceFileName,DestinationFile)) {
  1337. if (fVerbose) {
  1338. fprintf(stdout,"BINPLACE : warning BNP0000: copy %s to %s\n",SourceFileName,DestinationFile);
  1339. }
  1340. } else {
  1341. return(TRUE);
  1342. }
  1343. }
  1344. SetFileAttributes(DestinationFile,FILE_ATTRIBUTE_NORMAL);
  1345. if (fSetupModeScriptFile) {
  1346. fprintf( CommandScriptFile, "%s %s\n", DestinationFile, SetupFilePath );
  1347. }
  1348. if (!fIgnoreHardLinks && fHardLinks) {
  1349. if ((*pCreateHardLinkA)(SourceFileName, DestinationFile, NULL)) {
  1350. if (!fKeepAttributes)
  1351. SetFileAttributes(DestinationFile,FILE_ATTRIBUTE_NORMAL);
  1352. return(TRUE);
  1353. }
  1354. }
  1355. if ( !CopyFile(SourceFileName,DestinationFile, FALSE)) {
  1356. fprintf(stderr,"BINPLACE : warning BNP0000: CopyFile(%s,%s) failed %d\n",SourceFileName,DestinationFile,GetLastError());
  1357. if (!fLiveSystem) {
  1358. return FALSE;
  1359. }
  1360. // If CopyFile failed and we are instructed to do this over a live
  1361. // system, attempt to do a safe copy
  1362. if (GetTempFileName (TmpDestinationDir, "bin", 0, TmpDestinationFile) == 0) {
  1363. fprintf (stderr, "BINPLACE : error BNP0000: GetTempFileName (%s, %s) failed - %d\n",
  1364. DestinationSubdir, TmpDestinationFile, GetLastError ());
  1365. return FALSE;
  1366. }
  1367. if (fVerbose) {
  1368. fprintf (stdout, "BINPLACE : warning BNP0000: temp file name is %s\n", TmpDestinationFile);
  1369. }
  1370. // rename target file to temp file
  1371. if (!MoveFileEx (DestinationFile, TmpDestinationFile, MOVEFILE_REPLACE_EXISTING)) {
  1372. // Move failed, get rid of temp file
  1373. ULONG error = GetLastError ();
  1374. if (fVerbose) {
  1375. fprintf (stdout, "BINPLACE : error BNP0000: MoveFileEx (%s, %s) failed %d",
  1376. DestinationFile, TmpDestinationFile, error);
  1377. }
  1378. DeleteFile (TmpDestinationFile);
  1379. SetLastError (error);
  1380. return FALSE;
  1381. }
  1382. // copy again
  1383. if (!CopyFile (SourceFileName, DestinationFile, TRUE)) {
  1384. // Copy failed. Delete the destination (perhaps due to out of space
  1385. // and replace original destination)
  1386. ULONG error = GetLastError ();
  1387. if (fVerbose) {
  1388. fprintf (stdout, "BINPLACE : error BNP0000: CopyFile (%s, %s) failed %d",
  1389. SourceFileName, DestinationFile, error);
  1390. }
  1391. DeleteFile (DestinationFile);
  1392. MoveFile (TmpDestinationFile, DestinationFile);
  1393. SetLastError (error);
  1394. return FALSE;
  1395. }
  1396. // mark temp for delete
  1397. if (!MoveFileEx (TmpDestinationFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
  1398. // Could not make old file for deletion. Delete destination
  1399. // and replace original destination)
  1400. ULONG error = GetLastError ();
  1401. if (fVerbose) {
  1402. fprintf (stdout, "BINPLACE : error BNP0000: MoveFileEx (%s, NULL) failed %d",
  1403. TmpDestinationFile, error);
  1404. }
  1405. DeleteFile (DestinationFile);
  1406. MoveFile (TmpDestinationFile, DestinationFile);
  1407. return FALSE;
  1408. }
  1409. }
  1410. if (fSetupMode && !fSetupModeScriptFile) {
  1411. fprintf(stdout,"%s ==> %s\n",SourceFileName,DestinationFile);
  1412. }
  1413. if (!fKeepAttributes)
  1414. SetFileAttributes(DestinationFile,FILE_ATTRIBUTE_NORMAL);
  1415. if (!fNoClassInSymbolsDir) {
  1416. strcpy(TmpDestinationDir, SymbolFilePath);
  1417. if ((DestinationSubdir[0] == '.') && (DestinationSubdir[1] == '\0')) {
  1418. strcat(TmpDestinationDir, "\\retail");
  1419. } else {
  1420. char * pSubdir;
  1421. char * pTmp;
  1422. strcat(TmpDestinationDir, "\\");
  1423. pSubdir = DestinationSubdir;
  1424. if (pSubdir[0] == '.' && pSubdir[1] == '\\')
  1425. {
  1426. pSubdir += 2;
  1427. }
  1428. //
  1429. // Put the root dir only on the path
  1430. // Optionally change asms to retail.
  1431. //
  1432. pTmp = strchr(pSubdir, '\\');
  1433. if (pTmp) {
  1434. const static char asms[] = "asms\\";
  1435. if (fChangeAsmsToRetailForSymbols
  1436. && _strnicmp(pSubdir, asms, sizeof(asms) - 1) ==0) {
  1437. //
  1438. strcpy(TmpDestinationFile, "retail");
  1439. strcat(TmpDestinationDir, TmpDestinationFile);
  1440. } else {
  1441. strcpy(TmpDestinationFile, pSubdir);
  1442. TmpDestinationFile[pTmp - pSubdir] = '\0';
  1443. strcat(TmpDestinationDir, TmpDestinationFile);
  1444. }
  1445. } else {
  1446. strcat(TmpDestinationDir, pSubdir);
  1447. }
  1448. }
  1449. TmpSymbolFilePath = TmpDestinationDir;
  1450. } else {
  1451. TmpSymbolFilePath = SymbolFilePath;
  1452. }
  1453. if (fSplitSymbols && !fUpDriver) {
  1454. _splitpath(SourceFileName, Drive, Dir, NULL, Ext);
  1455. _makepath(DebugFilePath, Drive, Dir, NULL, NULL);
  1456. SplitFlags |= SPLITSYM_SYMBOLPATH_IS_SRC;
  1457. if (SplitSymbolsX( DestinationFile, TmpSymbolFilePath, (PCHAR) DebugFilePath,
  1458. SplitFlags, szRSDSDllToLoad, gPublicSymbol, MAX_PATH )) {
  1459. if (fVerbose)
  1460. fprintf( stdout, "BINPLACE : warning BNP0000: Symbols stripped from %s into %s\n", DestinationFile, DebugFilePath );
  1461. } else {
  1462. if (fVerbose)
  1463. fprintf( stdout, "BINPLACE : warning BNP0000: No symbols to strip from %s\n", DestinationFile );
  1464. strcpy(DebugFilePath, TmpSymbolFilePath);
  1465. strcat(DebugFilePath, "\\");
  1466. strcat(DebugFilePath, &Ext[1]);
  1467. strcat(DebugFilePath, "\\");
  1468. BinplaceCopyPdb(DebugFilePath, SourceFileName, TRUE, SplitFlags & SPLITSYM_REMOVE_PRIVATE, gPublicSymbol, MAX_PATH);
  1469. }
  1470. if ((SplitFlags & SPLITSYM_REMOVE_PRIVATE) && (PrivateSymbolFilePath != NULL)) {
  1471. CHAR Dir1[_MAX_PATH];
  1472. CHAR Dir2[_MAX_PATH];
  1473. _splitpath(DebugFilePath, Drive, Dir, NULL, NULL);
  1474. _makepath(Dir1, Drive, Dir, NULL, NULL);
  1475. strcpy(Dir2, PrivateSymbolFilePath);
  1476. strcat(Dir2, Dir1+strlen(SymbolFilePath));
  1477. MakeSureDirectoryPathExists(Dir2);
  1478. BinplaceCopyPdb(Dir2, SourceFileName, TRUE, FALSE, gPrivateSymbol, MAX_PATH);
  1479. }
  1480. } else {
  1481. BinplaceCopyPdb(DestinationFile, SourceFileName, FALSE, (fSplitSymbols ? (SplitFlags & SPLITSYM_REMOVE_PRIVATE) : FALSE), gPublicSymbol, MAX_PATH);
  1482. }
  1483. StripCVSymbolPath(DestinationFile);
  1484. if (fPlaceWin95SymFile) {
  1485. char DestSymPath[_MAX_PATH];
  1486. char DestSymDir[_MAX_PATH];
  1487. char SrcSymPath[_MAX_PATH];
  1488. _splitpath(CurrentImageName, Drive, Dir, Name, Ext);
  1489. _makepath(SrcSymPath, Drive, Dir, Name, ".sym");
  1490. if (!_access(SrcSymPath, 0)) {
  1491. if (fSplitSymbols) {
  1492. strcpy(DestSymPath, TmpSymbolFilePath);
  1493. strcat(DestSymPath, "\\");
  1494. strcat(DestSymPath, Ext[0] == '.' ? &Ext[1] : Ext);
  1495. strcat(DestSymPath, "\\");
  1496. strcat(DestSymPath, Name);
  1497. strcat(DestSymPath, ".sym");
  1498. } else {
  1499. _splitpath(DestinationFile, Drive, Dir, NULL, NULL);
  1500. _makepath(DestSymPath, Drive, Dir, Name, ".sym");
  1501. }
  1502. SetFileAttributes(DestSymPath, FILE_ATTRIBUTE_NORMAL);
  1503. if (SourceIsNewer(SrcSymPath, SourceFileName)) {
  1504. // Only binplace the .sym file if it was built AFTER the image itself.
  1505. // Make sure to create the destination path in case it is not there already.
  1506. strcpy(DestSymDir, TmpSymbolFilePath);
  1507. strcat(DestSymDir, "\\");
  1508. strcat(DestSymDir, Ext[0] == '.' ? &Ext[1] : Ext);
  1509. strcat(DestSymDir, "\\");
  1510. MakeSureDirectoryPathExists(DestSymDir);
  1511. if (!CopyFile(SrcSymPath, DestSymPath, FALSE)) {
  1512. fprintf(stderr,"BINPLACE : warning BNP0000: CopyFile(%s,%s) failed %d\n", SrcSymPath, DestSymPath ,GetLastError());
  1513. }
  1514. }
  1515. if (!fKeepAttributes)
  1516. SetFileAttributes(DestinationFile,FILE_ATTRIBUTE_NORMAL);
  1517. } else {
  1518. if (fVerbose) {
  1519. fprintf( stdout, "BINPLACE : warning BNP0000: Unable to locate \"%s\" for \"%s\"\n", SrcSymPath, CurrentImageName );
  1520. }
  1521. }
  1522. }
  1523. if (fDigitalSign) {
  1524. SignWithIDWKey( DestinationFile );
  1525. }
  1526. if (!fSetupMode && fBinplaceLc) {
  1527. strcpy(DestinationLcFile,PlaceRootName);
  1528. strcat(DestinationLcFile,"\\");
  1529. strcat(DestinationLcFile,BinplaceLcDir);
  1530. strcat(DestinationLcFile,"\\");
  1531. strcat(DestinationLcFile,DestinationSubdir);
  1532. strcat(DestinationLcFile,"\\");
  1533. if (!MakeSureDirectoryPathExists(DestinationLcFile)) {
  1534. fprintf(stderr, "BINPLACE : error BNP0000: Unable to create directory path '%s' (%u)\n",
  1535. DestinationLcFile, GetLastError()
  1536. );
  1537. }
  1538. strcat(DestinationLcFile, LcFilePart);
  1539. if (!CopyFile(LcFullFileName, DestinationLcFile, FALSE)) {
  1540. fprintf(stderr,"BINPLACE : warning BNP0000: CopyFile(%s,%s) failed %d\n",
  1541. LcFullFileName,DestinationLcFile,GetLastError());
  1542. }
  1543. }
  1544. } else {
  1545. if (fSetupMode) {
  1546. if (SourceIsNewer(SourceFileName,DestinationFile)) {
  1547. if (fVerbose) {
  1548. fprintf(stdout,"BINPLACE : warning BNP0000: copy %s to %s\n",SourceFileName,DestinationFile);
  1549. }
  1550. } else {
  1551. return(TRUE);
  1552. }
  1553. }
  1554. if ( fSetupMode ) {
  1555. fprintf(stdout,"%s ==> %s\n",SourceFileName,DestinationFile);
  1556. }
  1557. }
  1558. return TRUE;
  1559. }
  1560. BOOL VerifyLc(
  1561. PCHAR FileName,
  1562. BOOL fRetail
  1563. )
  1564. {
  1565. HRESULT hr = (*pVerifyLocConstraintA)(FileName, LcFullFileName);
  1566. if (FAILED(hr)) {
  1567. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MATCH)) {
  1568. fprintf(stderr,
  1569. "BINPLACE : %s BNP0000: resource conflicts with localization constraint \"%s\"\n",
  1570. fRetail ? "error" : "warning",
  1571. FileName);
  1572. }
  1573. else {
  1574. fprintf(stderr,
  1575. "BINPLACE : %s BNP0000: VerifyLc %s failed 0x%lX\n",
  1576. fRetail ? "error" : "warning", FileName, hr);
  1577. }
  1578. return FALSE;
  1579. }
  1580. return TRUE;
  1581. }
  1582. typedef DWORD (WINAPI *PFNGVS)(LPSTR, LPDWORD);
  1583. BOOL
  1584. VerifyFinalImage(
  1585. IN PCHAR FileName,
  1586. IN BOOL fRetail,
  1587. OUT PBOOL BinplaceLc
  1588. )
  1589. {
  1590. HINSTANCE hVersion;
  1591. PFNGVS pfnGetFileVersionInfoSize;
  1592. DWORD dwSize;
  1593. DWORD dwReturn;
  1594. BOOL fRC = TRUE, rc=TRUE, tlb=FALSE;
  1595. LOADED_IMAGE LoadedImage;
  1596. OSVERSIONINFO VersionInfo;
  1597. LoadedImage.hFile = INVALID_HANDLE_VALUE;
  1598. *BinplaceLc = FALSE;
  1599. if (fVerifyLc) {
  1600. if (!VerifyLc(FileName, fRetail)) {
  1601. fRC = fRetail ? FALSE : TRUE;
  1602. goto End1;
  1603. }
  1604. *BinplaceLc = TRUE;
  1605. }
  1606. VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1607. GetVersionEx ( &VersionInfo );
  1608. if ( VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
  1609. return( TRUE ); // Not NT - can't load Win64 binaries
  1610. if ( VersionInfo.dwMajorVersion < 5 )
  1611. return ( TRUE ); // Prior to Win2K - can't load Win64 binaries
  1612. rc = MapAndLoad(FileName, NULL, &LoadedImage, FALSE, TRUE);
  1613. if (!rc) {
  1614. // Not a binary. See if it's one of the other types we care about (like typelibs)
  1615. CHAR szExt[_MAX_EXT];
  1616. _splitpath(FileName, NULL, NULL, NULL, szExt);
  1617. // The only non-binary images that need version resources are .tlb's
  1618. if (_stricmp(szExt, ".tlb")) {
  1619. return(TRUE);
  1620. }
  1621. tlb=TRUE;
  1622. }
  1623. hVersion = LoadLibraryA("VERSION.DLL");
  1624. if (hVersion == NULL) {
  1625. goto End1;
  1626. }
  1627. pfnGetFileVersionInfoSize = (PFNGVS) GetProcAddress(hVersion, "GetFileVersionInfoSizeA");
  1628. if (pfnGetFileVersionInfoSize == NULL) {
  1629. goto End2;
  1630. }
  1631. if ((dwReturn = pfnGetFileVersionInfoSize(FileName, &dwSize)) == 0) {
  1632. if ( !tlb && (LoadedImage.FileHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) &&
  1633. (LoadedImage.FileHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) &&
  1634. (LoadedImage.FileHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64) ) {
  1635. goto End2;
  1636. }
  1637. if (fRetail) {
  1638. fprintf(stderr,
  1639. "BINPLACE : %s BNP0000: no version resource detected for \"%s\"\n",
  1640. "error",
  1641. FileName);
  1642. fRC = FALSE;
  1643. } else {
  1644. fRC = TRUE;
  1645. }
  1646. }
  1647. End2:
  1648. FreeLibrary(hVersion);
  1649. End1:
  1650. if (ImageCheck.Argv != NULL &&
  1651. (LoadedImage.hFile != INVALID_HANDLE_VALUE ||
  1652. MapAndLoad(FileName, NULL, &LoadedImage, FALSE, TRUE) == TRUE)) {
  1653. if ((LoadedImage.FileHeader->FileHeader.Machine == ImageCheck.Machine)) {
  1654. int RC;
  1655. ImageCheck.Argv[ImageCheck.Argc-2] = FileName;
  1656. RC = (int)_spawnvp(P_WAIT, ImageCheck.Argv[0], (const char * const *) ImageCheck.Argv);
  1657. if (RC == -1 || RC == 128) {
  1658. fprintf(stderr,
  1659. "BINPLACE : error BNP0000: Cannot execute (%s). Make sure it (or it's DLL's) exists or verify binplace /CI option.\n", ImageCheck.Argv[0]);
  1660. fRC = FALSE;
  1661. } else if (RC == 1) {
  1662. fprintf(stderr,
  1663. "BINPLACE : error BNP0000: ImageCheck (%s) failed.\n", ImageCheck.Argv[0]);
  1664. fRC = FALSE;
  1665. } else if (RC == ImageCheck.RC) {
  1666. fprintf(stderr,
  1667. "BINPLACE : error BNP0000: Image checker (%s) detected errors in %s.\n", ImageCheck.Argv[0], FileName);
  1668. fRC = FALSE;
  1669. }
  1670. }
  1671. }
  1672. if (LoadedImage.hFile != INVALID_HANDLE_VALUE)
  1673. UnMapAndLoad(&LoadedImage);
  1674. return fRC;
  1675. }
  1676. BOOL
  1677. SourceIsNewer(
  1678. IN LPSTR SourceFile,
  1679. IN LPSTR TargetFile
  1680. )
  1681. {
  1682. BOOL Newer;
  1683. WIN32_FIND_DATA TargetInfo;
  1684. WIN32_FIND_DATA SourceInfo;
  1685. //
  1686. // If force placement (-f option) was specified, just return TRUE
  1687. // If the target file doesn't exist, then the source is newer.
  1688. // If the source file doesn't exist, just return TRUE and hope
  1689. // the caller will catch it.
  1690. if ((fForcePlace == FALSE) && (FileExists(TargetFile,&TargetInfo) && FileExists(SourceFile,&SourceInfo))) {
  1691. Newer = (fLiveSystem || !fPatheticOS)
  1692. ? (CompareFileTime(&SourceInfo.ftLastWriteTime,&TargetInfo.ftLastWriteTime) > 0)
  1693. : (CompareFileTime(&SourceInfo.ftLastWriteTime,&TargetInfo.ftLastWriteTime) >= 0);
  1694. } else {
  1695. Newer = TRUE;
  1696. }
  1697. return(Newer);
  1698. }
  1699. BOOL
  1700. SetupModeRetailFile(
  1701. IN LPSTR FullFileName,
  1702. IN LPSTR FileNamePart,
  1703. OUT PBOOL PutInDump
  1704. )
  1705. {
  1706. BOOL FoundInTree;
  1707. INFCONTEXT InfContext;
  1708. DWORD DontCare;
  1709. INT IntVal;
  1710. CHAR DirSpec[24];
  1711. CHAR Directory[MAX_PATH];
  1712. CHAR Rename[MAX_PATH];
  1713. LPSTR p;
  1714. //
  1715. // Find and update all instances of the file in the target tree.
  1716. //
  1717. *PutInDump = FALSE;
  1718. FoundInTree = FALSE;
  1719. if (!SearchOneDirectory(PlaceRootName,FileNamePart,FullFileName,FileNamePart,&FoundInTree)) {
  1720. return(FALSE);
  1721. }
  1722. if (!FoundInTree) {
  1723. //
  1724. // OK, now things get tricky. Load master layout inf if
  1725. // not already loaded.
  1726. //
  1727. if (!LayoutInf) {
  1728. if (LayoutInfName) {
  1729. //
  1730. // Use GetFullPathName(). Otherwise a name without a dir spec
  1731. // will be assumed to be in %sysroot%\inf, which is probably not
  1732. // what people would expect.
  1733. //
  1734. GetFullPathName(LayoutInfName,MAX_PATH,Directory,&p);
  1735. LayoutInf = (*pSetupOpenInfFileA)(Directory,NULL,INF_STYLE_WIN4,NULL);
  1736. } else {
  1737. LayoutInf = (*pSetupOpenMasterInf)();
  1738. }
  1739. if (LayoutInf == INVALID_HANDLE_VALUE) {
  1740. LayoutInf = NULL;
  1741. fprintf(
  1742. stderr,
  1743. "BINPLACE : error BNP0000: Unable to load %s\n",
  1744. LayoutInfName ? LayoutInfName : "%%sysroot%%\\inf\\layout.inf"
  1745. );
  1746. return(FALSE);
  1747. }
  1748. }
  1749. //
  1750. // Look up the file in the master inf.
  1751. //
  1752. if (!(*pSetupFindFirstLineA)(LayoutInf,szSourceDisksFiles,FileNamePart,&InfContext)) {
  1753. LPTSTR platform;
  1754. LPCTSTR szSourceDisksFPlat;
  1755. #if defined(_AMD64_)
  1756. szSourceDisksFPlat = &szSourceDisksAMD64[0];
  1757. #elif defined(_IA64_)
  1758. szSourceDisksFPlat = &szSourceDisksIA64[0];
  1759. #else // defined(_X86_)
  1760. szSourceDisksFPlat = &szSourceDisksX86[0];
  1761. if ((platform = getenv("AMD64")) != NULL) {
  1762. szSourceDisksFPlat = &szSourceDisksAMD64[0];
  1763. } else if ((platform = getenv("IA64")) != NULL) {
  1764. szSourceDisksFPlat = &szSourceDisksIA64[0];
  1765. }
  1766. #endif
  1767. if (!(*pSetupFindFirstLineA)(LayoutInf,szSourceDisksFPlat,FileNamePart,&InfContext)) {
  1768. if ( fVerbose ) {
  1769. fprintf(stderr,"BINPLACE : warning BNP0000: warning: unknown retail file %s\n",FileNamePart);
  1770. }
  1771. *PutInDump = TRUE;
  1772. return(TRUE);
  1773. }
  1774. }
  1775. //
  1776. // See if the file gets renamed in the target tree.
  1777. // If so, try to find the renamed version in the target.
  1778. //
  1779. if ((*pSetupGetStringFieldA)(&InfContext,11,Rename,MAX_PATH,&DontCare)
  1780. && lstrcmpi(Rename,FileNamePart)) {
  1781. FoundInTree = FALSE;
  1782. if (!SearchOneDirectory(PlaceRootName,Rename,FullFileName,FileNamePart,&FoundInTree)) {
  1783. return(FALSE);
  1784. }
  1785. //
  1786. // If we found the renamed file in the target tree, we're done.
  1787. //
  1788. if (FoundInTree) {
  1789. return(TRUE);
  1790. }
  1791. } else {
  1792. //
  1793. // Assume name in target is same as name in source.
  1794. //
  1795. strcpy(Rename,FileNamePart);
  1796. }
  1797. //
  1798. // We couldn't find the file in the target tree.
  1799. // The file might be new. Check the copy disposition for
  1800. // non-upgrades -- if the file is marked "copy always" then we want
  1801. // to copy it. Otherwise ignore the file. This way someone who
  1802. // uses this tool to 'upgrade' a build doesn't get a pile of files
  1803. // they don't need placed into their nt tree.
  1804. //
  1805. // This behavior is overrideable by using -!! instead of -!.
  1806. //
  1807. if (!fSetupModeAllFiles && (!(*pSetupGetIntField)(&InfContext,10,&IntVal) || IntVal)) {
  1808. //
  1809. // File is not marked "copy always" so ignore it, assuming it's
  1810. // configuration-specific and the user doesn't need it.
  1811. //
  1812. return(TRUE);
  1813. }
  1814. //
  1815. // File needs to be copied into the target tree.
  1816. // Get the directory spec.
  1817. //
  1818. DirSpec[0] = 0;
  1819. (*pSetupGetStringFieldA)(&InfContext,8,DirSpec,sizeof(DirSpec),&DontCare);
  1820. if (!(*pSetupFindFirstLineA)(LayoutInf,"WinntDirectories",DirSpec,&InfContext)
  1821. || !(*pSetupGetStringFieldA)(&InfContext,1,Directory,MAX_PATH,&DontCare)) {
  1822. if (strlen(DirSpec)) {
  1823. fprintf(stderr,"BINPLACE : error BNP0000: unknown directory spec %s in layout.inf for file %s\n",DirSpec,FileNamePart);
  1824. return(FALSE);
  1825. } else {
  1826. return(TRUE);
  1827. }
  1828. }
  1829. //
  1830. // If the spec begins with a slash, then for root dir, replace with .
  1831. // otherwise, skip over leading slash in the non-root case.
  1832. //
  1833. if ((Directory[0] == '\\')) {
  1834. if (!Directory[1]) {
  1835. Directory[0] = '.';
  1836. } else {
  1837. lstrcpy(Directory, Directory+1);
  1838. }
  1839. }
  1840. if (fSetupModeScriptFile) {
  1841. lstrcpy(SetupFilePath, Directory);
  1842. lstrcat(SetupFilePath, "\\");
  1843. lstrcat(SetupFilePath, Rename);
  1844. return FALSE;
  1845. }
  1846. //
  1847. // Got what we need -- copy the file.
  1848. //
  1849. return CopyTheFile(
  1850. FullFileName,
  1851. FileNamePart,
  1852. Directory,
  1853. Rename
  1854. );
  1855. }
  1856. return(TRUE);
  1857. }
  1858. BOOL
  1859. BinplaceCopyPdb (
  1860. LPSTR DestinationFile,
  1861. LPSTR SourceFileName,
  1862. BOOL CopyFromSourceOnly,
  1863. BOOL StripPrivate,
  1864. LPSTR DestinationSymbol,
  1865. DWORD LenDestSymbolBuffer
  1866. )
  1867. {
  1868. LOADED_IMAGE LoadedImage;
  1869. DWORD DirCnt;
  1870. IMAGE_DEBUG_DIRECTORY UNALIGNED *DebugDirs, *CvDebugDir;
  1871. if (MapAndLoad(
  1872. CopyFromSourceOnly ? SourceFileName : DestinationFile,
  1873. NULL,
  1874. &LoadedImage,
  1875. FALSE,
  1876. CopyFromSourceOnly ? TRUE : FALSE) == FALSE) {
  1877. return (FALSE);
  1878. }
  1879. DebugDirs = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryEntryToData(
  1880. LoadedImage.MappedAddress,
  1881. FALSE,
  1882. IMAGE_DIRECTORY_ENTRY_DEBUG,
  1883. &DirCnt
  1884. );
  1885. if (!DebugDirectoryIsUseful(DebugDirs, DirCnt)) {
  1886. UnMapAndLoad(&LoadedImage);
  1887. return(FALSE);
  1888. }
  1889. DirCnt /= sizeof(IMAGE_DEBUG_DIRECTORY);
  1890. CvDebugDir = NULL;
  1891. while (DirCnt) {
  1892. DirCnt--;
  1893. if (DebugDirs[DirCnt].Type == IMAGE_DEBUG_TYPE_CODEVIEW) {
  1894. CvDebugDir = &DebugDirs[DirCnt];
  1895. break;
  1896. }
  1897. }
  1898. if (!CvDebugDir) {
  1899. // Didn't find any CV debug dir. Bail.
  1900. UnMapAndLoad(&LoadedImage);
  1901. return(FALSE);
  1902. }
  1903. if (CvDebugDir->PointerToRawData != 0) {
  1904. PCVDD pDebugDir;
  1905. ULONG mysize;
  1906. pDebugDir = (PCVDD) (CvDebugDir->PointerToRawData + (PCHAR)LoadedImage.MappedAddress);
  1907. if (pDebugDir->dwSig == '01BN' ) {
  1908. mysize=sizeof(NB10IH);
  1909. } else {
  1910. mysize=sizeof(RSDSIH);
  1911. }
  1912. if (pDebugDir->dwSig == '01BN' || pDebugDir->dwSig == 'SDSR' ) {
  1913. // Got a PDB. The name immediately follows the signature.
  1914. LPSTR szMyDllToLoad;
  1915. CHAR PdbName[sizeof(((PRSDSI)(0))->szPdb)];
  1916. CHAR NewPdbName[sizeof(((PRSDSI)(0))->szPdb)];
  1917. CHAR Drive[_MAX_DRIVE];
  1918. CHAR Dir[_MAX_DIR];
  1919. CHAR Filename[_MAX_FNAME];
  1920. CHAR FileExt[_MAX_EXT];
  1921. if (pDebugDir->dwSig == '01BN') {
  1922. szMyDllToLoad=NULL;
  1923. } else {
  1924. szMyDllToLoad=szRSDSDllToLoad;
  1925. }
  1926. ZeroMemory(PdbName, sizeof(PdbName));
  1927. memcpy(PdbName, ((PCHAR)pDebugDir) + mysize, __min(CvDebugDir->SizeOfData - mysize, sizeof(PdbName)));
  1928. _splitpath(PdbName, NULL, NULL, Filename, FileExt);
  1929. _splitpath(DestinationFile, Drive, Dir, NULL, NULL);
  1930. _makepath(NewPdbName, Drive, Dir, Filename, FileExt);
  1931. if (!fSetupMode && (fVerbose || fTestMode)) {
  1932. fprintf(stdout,"BINPLACE : warning BNP0000: place %s in %s\n", PdbName, NewPdbName);
  1933. }
  1934. if (!MakeSureDirectoryPathExists(NewPdbName)) {
  1935. fprintf(stderr, "BINPLACE : error BNP0000: Unable to create directory path '%s' (%u)\n",
  1936. NewPdbName, GetLastError());
  1937. }
  1938. SetFileAttributes(NewPdbName,FILE_ATTRIBUTE_NORMAL);
  1939. if (DestinationSymbol)
  1940. {
  1941. strncpy(DestinationSymbol, NewPdbName, LenDestSymbolBuffer);
  1942. DestinationSymbol[LenDestSymbolBuffer-1] = '\0'; // ensure termination
  1943. }
  1944. if ( !CopyPdbX(PdbName, NewPdbName, StripPrivate, szMyDllToLoad)) {
  1945. if (!fSetupMode && (fVerbose || fTestMode)) {
  1946. fprintf(stderr,"BINPLACE : warning BNP0000: Unable to copy (%s,%s) %d\n", PdbName, NewPdbName, GetLastError());
  1947. }
  1948. // It's possible the name in the pdb isn't in the same location as it was when built. See if we can
  1949. // find it in the same dir as the image...
  1950. _splitpath(SourceFileName, Drive, Dir, NULL, NULL);
  1951. _makepath(PdbName, Drive, Dir, Filename, FileExt);
  1952. if (!fSetupMode && (fVerbose || fTestMode)) {
  1953. fprintf(stdout,"BINPLACE : warning BNP0000: place %s in %s\n", PdbName, NewPdbName);
  1954. }
  1955. if ( !CopyPdbX(PdbName, NewPdbName, StripPrivate, szMyDllToLoad)) {
  1956. // fprintf(stderr,"BINPLACE : warning BNP0000: CopyPdb(%s,%s) failed %d\n", PdbName, NewPdbName, GetLastError());
  1957. }
  1958. }
  1959. if (!fKeepAttributes)
  1960. SetFileAttributes(NewPdbName, FILE_ATTRIBUTE_NORMAL);
  1961. if (fWppFmt && !StripPrivate) {
  1962. // We want to do the trace format pass on the target PDB, but there is no point in doing
  1963. // that if it is stripped.
  1964. if (strcmp(PdbName,LastPdbName) != 0) { // Have we just processed this PDB?
  1965. if (fVerbose) {
  1966. fprintf( stdout, "BINPLACE : warning BNP0000: Trace Formats being built from %s\n", NewPdbName );
  1967. }
  1968. if (TraceFormatFilePath[0] == '\0') {
  1969. if (PrivateSymbolFilePath != NULL) {
  1970. _snprintf(TraceFormatFilePath,MAX_PATH,"%s\\%s",PrivateSymbolFilePath,TraceDir);
  1971. } else {
  1972. strncpy(TraceFormatFilePath, TraceDir, MAX_PATH) ;
  1973. }
  1974. if (fVerbose) {
  1975. fprintf( stdout, "BINPLACE : warning BNP0000: Trace Formats file path set to %s\n", TraceFormatFilePath );
  1976. }
  1977. }
  1978. BinplaceWppFmt(NewPdbName,TraceFormatFilePath,szRSDSDllToLoad,fVerbose);
  1979. // because files are frequently copied to multiple places, the PDB is also placed
  1980. // several times, there is no point in us processing it more than once.
  1981. strncpy(LastPdbName,PdbName,MAX_PATH);
  1982. } else {
  1983. if (fVerbose) {
  1984. fprintf( stdout, "BINPLACE : warning BNP0000: Trace Formats skipping %s (same as last)\n", NewPdbName );
  1985. }
  1986. }
  1987. }
  1988. if (fSrcControl && !StripPrivate) {
  1989. CHAR CvdumpName[_MAX_PATH + _MAX_FNAME];
  1990. UINT i;
  1991. LONG pos;
  1992. CHAR buf[_MAX_PATH*3];
  1993. // Find the start of "symbols.pri" in NewPdbName
  1994. pos=-1;
  1995. i=0;
  1996. while ( (i < strlen(NewPdbName) - strlen("symbols.pri")) && pos== -1) {
  1997. if (_strnicmp( NewPdbName+i, "symbols.pri", strlen("symbols.pri") ) == 0 ) {
  1998. pos=i;
  1999. } else {
  2000. i++;
  2001. }
  2002. }
  2003. if ( pos >= 0 ) {
  2004. strcpy(CvdumpName, NewPdbName);
  2005. CvdumpName[i]='\0';
  2006. strcat(CvdumpName, "cvdump.pri" );
  2007. strcat(CvdumpName, NewPdbName + pos + strlen("symbols.pri") );
  2008. strcat(CvdumpName, ".dmp");
  2009. // Get the Directory name and create it
  2010. if ( MakeSureDirectoryPathExists(CvdumpName) ) {
  2011. sprintf(buf, "cvdump -l %s > %s", NewPdbName, CvdumpName);
  2012. system(buf);
  2013. } else {
  2014. fprintf( stdout, "BINPLACE : error BNP0000: Cannot create directory for the file %s\n", CvdumpName);
  2015. }
  2016. }
  2017. }
  2018. if (!CopyFromSourceOnly) {
  2019. PVOID pCertificates = ImageDirectoryEntryToData(LoadedImage.MappedAddress,
  2020. FALSE,
  2021. IMAGE_DIRECTORY_ENTRY_SECURITY,
  2022. &DirCnt
  2023. );
  2024. if (!pCertificates && !DirCnt) {
  2025. // Only change the data in the image if it hasn't been signed (otherwise the sig is invalidated).
  2026. strcpy(((char *)pDebugDir) + mysize, Filename);
  2027. strcat(((char *)pDebugDir) + mysize, FileExt);
  2028. CvDebugDir->SizeOfData = mysize + strlen(Filename) + strlen(FileExt) + 1;
  2029. }
  2030. }
  2031. }
  2032. UnMapAndLoad(&LoadedImage);
  2033. return(TRUE);
  2034. }
  2035. UnMapAndLoad(&LoadedImage);
  2036. return(FALSE);
  2037. }
  2038. BOOL
  2039. FileExists(
  2040. IN LPCSTR FileName,
  2041. OUT PWIN32_FIND_DATA FindData
  2042. )
  2043. {
  2044. UINT OldMode;
  2045. BOOL Found;
  2046. HANDLE FindHandle;
  2047. OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  2048. FindHandle = FindFirstFile(FileName,FindData);
  2049. if (FindHandle == INVALID_HANDLE_VALUE) {
  2050. Found = FALSE;
  2051. } else {
  2052. FindClose(FindHandle);
  2053. Found = TRUE;
  2054. }
  2055. SetErrorMode(OldMode);
  2056. return(Found);
  2057. }
  2058. //////////////////////////////////////////////////////////////////////
  2059. // //
  2060. // Digital Signature Stuff //
  2061. // //
  2062. //////////////////////////////////////////////////////////////////////
  2063. LPBSAFE_PUB_KEY PUB;
  2064. LPBSAFE_PRV_KEY PRV;
  2065. unsigned char pubmodulus[] =
  2066. {
  2067. 0x00, 0x00, 0x00, 0x00,
  2068. 0x00, 0x00, 0x00, 0x00,
  2069. 0x00, 0x00, 0x00, 0x00,
  2070. 0x00, 0x00, 0x00, 0x00,
  2071. 0x00, 0x00, 0x00, 0x00,
  2072. 0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9,
  2073. 0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb,
  2074. 0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2,
  2075. 0xd7, 0xb7, 0x6b, 0x9a, 0xf2, 0x52, 0x45, 0x95,
  2076. 0xce, 0x63, 0x65, 0x6b, 0x58, 0x3a, 0xfe, 0xef,
  2077. 0x7c, 0xe7, 0xbf, 0xfe, 0x3d, 0xf6, 0x5c, 0x7d,
  2078. 0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb,
  2079. 0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87,
  2080. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  2081. };
  2082. unsigned char prvmodulus[] =
  2083. {
  2084. 0x00, 0x00, 0x00, 0x00,
  2085. 0x00, 0x00, 0x00, 0x00,
  2086. 0x00, 0x00, 0x00, 0x00,
  2087. 0x00, 0x00, 0x00, 0x00,
  2088. 0x00, 0x00, 0x00, 0x00,
  2089. 0x3d, 0x3a, 0x5e, 0xbd,
  2090. 0x72, 0x43, 0x3e, 0xc9, 0x4d, 0xbb, 0xc1, 0x1e,
  2091. 0x4a, 0xba, 0x5f, 0xcb, 0x3e, 0x88, 0x20, 0x87,
  2092. 0xef, 0xf5, 0xc1, 0xe2, 0xd7, 0xb7, 0x6b, 0x9a,
  2093. 0xf2, 0x52, 0x45, 0x95, 0xce, 0x63, 0x65, 0x6b,
  2094. 0x58, 0x3a, 0xfe, 0xef, 0x7c, 0xe7, 0xbf, 0xfe,
  2095. 0x3d, 0xf6, 0x5c, 0x7d, 0x6c, 0x5e, 0x06, 0x09,
  2096. 0x1a, 0xf5, 0x61, 0xbb, 0x20, 0x93, 0x09, 0x5f,
  2097. 0x05, 0x6d, 0xea, 0x87, 0x00, 0x00, 0x00, 0x00,
  2098. 0x00, 0x00, 0x00, 0x00, 0x3f, 0xbd, 0x29, 0x20,
  2099. 0x57, 0xd2, 0x3b, 0xf1, 0x07, 0xfa, 0xdf, 0xc1,
  2100. 0x16, 0x31, 0xe4, 0x95, 0xea, 0xc1, 0x2a, 0x46,
  2101. 0x2b, 0xad, 0x88, 0x57, 0x55, 0xf0, 0x57, 0x58,
  2102. 0xc6, 0x6f, 0x95, 0xeb, 0x00, 0x00, 0x00, 0x00,
  2103. 0x83, 0xdd, 0x9d, 0xd0, 0x03, 0xb1, 0x5a, 0x9b,
  2104. 0x9e, 0xb4, 0x63, 0x02, 0x43, 0x3e, 0xdf, 0xb0,
  2105. 0x52, 0x83, 0x5f, 0x6a, 0x03, 0xe7, 0xd6, 0x78,
  2106. 0x45, 0x83, 0x6a, 0x5b, 0xc4, 0xcb, 0xb1, 0x93,
  2107. 0x00, 0x00, 0x00, 0x00, 0x65, 0x9d, 0x43, 0xe8,
  2108. 0x48, 0x17, 0xcd, 0x29, 0x7e, 0xb9, 0x26, 0x5c,
  2109. 0x79, 0x66, 0x58, 0x61, 0x72, 0x86, 0x6a, 0xa3,
  2110. 0x63, 0xad, 0x63, 0xb8, 0xe1, 0x80, 0x4c, 0x0f,
  2111. 0x36, 0x7d, 0xd9, 0xa6, 0x00, 0x00, 0x00, 0x00,
  2112. 0x75, 0x3f, 0xef, 0x5a, 0x01, 0x5f, 0xf6, 0x0e,
  2113. 0xd7, 0xcd, 0x59, 0x1c, 0xc6, 0xec, 0xde, 0xf3,
  2114. 0x5a, 0x03, 0x09, 0xff, 0xf5, 0x23, 0xcc, 0x90,
  2115. 0x27, 0x1d, 0xaa, 0x29, 0x60, 0xde, 0x05, 0x6e,
  2116. 0x00, 0x00, 0x00, 0x00, 0xc0, 0x17, 0x0e, 0x57,
  2117. 0xf8, 0x9e, 0xd9, 0x5c, 0xf5, 0xb9, 0x3a, 0xfc,
  2118. 0x0e, 0xe2, 0x33, 0x27, 0x59, 0x1d, 0xd0, 0x97,
  2119. 0x4a, 0xb1, 0xb1, 0x1f, 0xc3, 0x37, 0xd1, 0xd6,
  2120. 0xe6, 0x9b, 0x35, 0xab, 0x00, 0x00, 0x00, 0x00,
  2121. 0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
  2122. 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
  2123. 0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
  2124. 0xcf, 0x92, 0xcc, 0x33, 0x99, 0xe8, 0x08, 0x60,
  2125. 0x17, 0x9a, 0x12, 0x9f, 0x24, 0xdd, 0xb1, 0x24,
  2126. 0x99, 0xc7, 0x3a, 0xb8, 0x0a, 0x7b, 0x0d, 0xdd,
  2127. 0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
  2128. 0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f,
  2129. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2130. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2131. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2132. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2133. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2134. 0x00, 0x00, 0x00, 0x00
  2135. };
  2136. BOOL initkey(void)
  2137. {
  2138. DWORD bits;
  2139. PUB = (LPBSAFE_PUB_KEY)pubmodulus;
  2140. PUB->magic = RSA1;
  2141. PUB->keylen = 0x48;
  2142. PUB->bitlen = 0x0200;
  2143. PUB->datalen = 0x3f;
  2144. PUB->pubexp = 0xc0887b5b;
  2145. PRV = (LPBSAFE_PRV_KEY)prvmodulus;
  2146. PRV->magic = RSA2;
  2147. PRV->keylen = 0x48;
  2148. PRV->bitlen = 0x0200;
  2149. PRV->datalen = 0x3f;
  2150. PRV->pubexp = 0xc0887b5b;
  2151. bits = PRV->bitlen;
  2152. return TRUE;
  2153. }
  2154. BOOL
  2155. SignWithIDWKey(
  2156. IN LPCSTR FileName)
  2157. {
  2158. HANDLE hFile;
  2159. HANDLE hMapping;
  2160. PUCHAR pMap;
  2161. HANDLE hSigFile;
  2162. DWORD Size;
  2163. MD5_CTX HashState;
  2164. BYTE SigHash[ 0x48 ];
  2165. BYTE Signature[ 0x48 ];
  2166. CHAR SigFilePath[ MAX_PATH ];
  2167. PSTR pszDot;
  2168. BOOL Return = FALSE;
  2169. if (!initkey()) {
  2170. return( FALSE );
  2171. }
  2172. hFile = CreateFile( FileName, GENERIC_READ,
  2173. FILE_SHARE_READ, NULL,
  2174. OPEN_EXISTING, 0, NULL );
  2175. if (hFile != INVALID_HANDLE_VALUE) {
  2176. hMapping = CreateFileMapping( hFile,
  2177. NULL,
  2178. PAGE_READONLY,
  2179. 0, 0, NULL );
  2180. if (hMapping) {
  2181. pMap = MapViewOfFileEx( hMapping,
  2182. FILE_MAP_READ,
  2183. 0, 0, 0, NULL );
  2184. if (pMap) {
  2185. Size = GetFileSize( hFile, NULL );
  2186. MD5Init( &HashState );
  2187. MD5Update( &HashState, pMap, Size );
  2188. MD5Final( &HashState );
  2189. memset(SigHash, 0xff, 0x40);
  2190. SigHash[0x40-1] = 0;
  2191. SigHash[0x40-2] = 1;
  2192. SigHash[16] = 0;
  2193. memcpy(SigHash, HashState.digest, 16);
  2194. //
  2195. // Encrypt the signature data
  2196. //
  2197. BSafeDecPrivate(PRV, SigHash, Signature );;
  2198. //
  2199. // Create and store it in a .sig file
  2200. //
  2201. strcpy( SigFilePath, FileName );
  2202. pszDot = strrchr( SigFilePath, '.' );
  2203. if (!pszDot) {
  2204. pszDot = SigFilePath + strlen( SigFilePath );
  2205. }
  2206. strcpy( pszDot, ".sig");
  2207. hSigFile = CreateFile( SigFilePath, GENERIC_WRITE,
  2208. 0, NULL,
  2209. CREATE_ALWAYS, 0, NULL );
  2210. if (hSigFile != INVALID_HANDLE_VALUE) {
  2211. WriteFile( hSigFile,
  2212. Signature,
  2213. sizeof( Signature ),
  2214. &Size, NULL );
  2215. CloseHandle( hSigFile );
  2216. Return = TRUE ;
  2217. if (fVerbose)
  2218. fprintf( stdout, "BINPLACE : warning BNP0000: Signature file generated in %s\n", SigFilePath);
  2219. } else {
  2220. fprintf( stderr, "BINPLACE : error BNP0000: Unable to create file %s, %d\n",
  2221. SigFilePath, GetLastError() );
  2222. }
  2223. UnmapViewOfFile( pMap );
  2224. } else {
  2225. fprintf(stderr, "BINPLACE : error BNP0000: unable to map view, %d\n", GetLastError());
  2226. }
  2227. CloseHandle( hMapping );
  2228. } else {
  2229. fprintf(stderr, "BINPLACE : error BNP0000: CreateFileMapping of %s failed, %d\n",
  2230. FileName, GetLastError() );
  2231. }
  2232. CloseHandle( hFile );
  2233. } else {
  2234. fprintf( stderr, "BINPLACE : error BNP0000: could not open %s, %d\n",
  2235. FileName, GetLastError() );
  2236. }
  2237. return( Return );
  2238. }
  2239. BOOL // Keep as BOOL for the future (used by rsa code)
  2240. GenRandom (ULONG huid, BYTE *pbBuffer, size_t dwLength)
  2241. {
  2242. return( FALSE );
  2243. }
  2244. BOOL
  2245. StripCVSymbolPath (
  2246. LPSTR DestinationFile
  2247. )
  2248. {
  2249. LOADED_IMAGE LoadedImage;
  2250. DWORD DirCnt;
  2251. IMAGE_DEBUG_DIRECTORY UNALIGNED *DebugDirs, *CvDebugDir;
  2252. PVOID pCertificates;
  2253. if (MapAndLoad(
  2254. DestinationFile,
  2255. NULL,
  2256. &LoadedImage,
  2257. FALSE,
  2258. FALSE) == FALSE) {
  2259. return (FALSE);
  2260. }
  2261. DebugDirs = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryEntryToData(
  2262. LoadedImage.MappedAddress,
  2263. FALSE,
  2264. IMAGE_DIRECTORY_ENTRY_DEBUG,
  2265. &DirCnt
  2266. );
  2267. if (!DebugDirectoryIsUseful(DebugDirs, DirCnt)) {
  2268. UnMapAndLoad(&LoadedImage);
  2269. return(FALSE);
  2270. }
  2271. DirCnt /= sizeof(IMAGE_DEBUG_DIRECTORY);
  2272. CvDebugDir = NULL;
  2273. while (DirCnt) {
  2274. DirCnt--;
  2275. if (DebugDirs[DirCnt].Type == IMAGE_DEBUG_TYPE_CODEVIEW) {
  2276. CvDebugDir = &DebugDirs[DirCnt];
  2277. break;
  2278. }
  2279. }
  2280. if (!CvDebugDir) {
  2281. // Didn't find any CV debug dir. Bail.
  2282. UnMapAndLoad(&LoadedImage);
  2283. return(FALSE);
  2284. }
  2285. if (CvDebugDir->PointerToRawData != 0) {
  2286. PCVDD pDebugDir;
  2287. ULONG mysize;
  2288. pDebugDir = (PCVDD) (CvDebugDir->PointerToRawData + (PCHAR)LoadedImage.MappedAddress);
  2289. if (pDebugDir->dwSig == '01BN' ) {
  2290. mysize=sizeof(NB10IH);
  2291. } else {
  2292. mysize=sizeof(RSDSIH);
  2293. }
  2294. if (pDebugDir->dwSig == '01BN' || pDebugDir->dwSig == 'SDSR' ) {
  2295. // Got a PDB. The name immediately follows the signature.
  2296. LPSTR szMyDllToLoad;
  2297. CHAR PdbName[sizeof(((PRSDSI)(0))->szPdb)];
  2298. CHAR Filename[_MAX_FNAME];
  2299. CHAR FileExt[_MAX_EXT];
  2300. if (pDebugDir->dwSig == '01BN') {
  2301. szMyDllToLoad=NULL;
  2302. } else {
  2303. szMyDllToLoad=szRSDSDllToLoad;
  2304. }
  2305. ZeroMemory(PdbName, sizeof(PdbName));
  2306. memcpy(PdbName, ((PCHAR)pDebugDir) + mysize, __min(CvDebugDir->SizeOfData - mysize, sizeof(PdbName)));
  2307. _splitpath(PdbName, NULL, NULL, Filename, FileExt);
  2308. pCertificates=NULL;
  2309. pCertificates = ImageDirectoryEntryToData(LoadedImage.MappedAddress,
  2310. FALSE,
  2311. IMAGE_DIRECTORY_ENTRY_SECURITY,
  2312. &DirCnt
  2313. );
  2314. if (!pCertificates && !DirCnt) {
  2315. // Only change the data in the image if it hasn't been signed (otherwise the sig is invalidated).
  2316. strcpy(((char *)pDebugDir) + mysize, Filename);
  2317. strcat(((char *)pDebugDir) + mysize, FileExt);
  2318. CvDebugDir->SizeOfData = mysize + strlen(Filename) + strlen(FileExt) + 1;
  2319. }
  2320. }
  2321. UnMapAndLoad(&LoadedImage);
  2322. return(TRUE);
  2323. }
  2324. UnMapAndLoad(&LoadedImage);
  2325. return(FALSE);
  2326. }
  2327. //#include <wppfmt.c> // just include this source for now (like copypdb)