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.

1269 lines
55 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. imagecfg.c
  5. Abstract:
  6. This function change the image loader configuration information in an image file.
  7. Author:
  8. Steve Wood (stevewo) 8-Nov-1994
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <private.h>
  15. struct {
  16. DWORD Flag;
  17. LPSTR ClearPrefix;
  18. LPSTR SetPrefix;
  19. LPSTR Description;
  20. } NtGlobalFlagNames[] = {
  21. {FLG_STOP_ON_EXCEPTION, "Don't ", "", "Stop on exception"},
  22. {FLG_SHOW_LDR_SNAPS, "Don't ", "", "Show Loader Debugging Information"},
  23. {FLG_DEBUG_INITIAL_COMMAND, "Don't ", "", "Debug Initial Command (WINLOGON)"},
  24. {FLG_STOP_ON_HUNG_GUI, "Don't ", "", "Stop on Hung GUI"},
  25. {FLG_HEAP_ENABLE_TAIL_CHECK, "Disable", "Enable", " Heap Tail Checking"},
  26. {FLG_HEAP_ENABLE_FREE_CHECK, "Disable", "Enable", " Heap Free Checking"},
  27. {FLG_HEAP_VALIDATE_PARAMETERS, "Disable", "Enable", " Heap Parameter Validation"},
  28. {FLG_HEAP_VALIDATE_ALL, "Disable", "Enable", " Heap Validate on Call"},
  29. {FLG_POOL_ENABLE_TAGGING, "Disable", "Enable", " Pool Tagging"},
  30. {FLG_HEAP_ENABLE_TAGGING, "Disable", "Enable", " Heap Tagging"},
  31. {FLG_USER_STACK_TRACE_DB, "Disable", "Enable", " User Mode Stack Backtrace DB (x86 checked only)"},
  32. {FLG_KERNEL_STACK_TRACE_DB, "Disable", "Enable", " Kernel Mode Stack Backtrace DB (x86 checked only)"},
  33. {FLG_MAINTAIN_OBJECT_TYPELIST, "Don't ", "", "Maintain list of kernel mode objects by type"},
  34. {FLG_HEAP_ENABLE_TAG_BY_DLL, "Disable", "Enable", " Heap DLL Tagging"},
  35. {FLG_ENABLE_CSRDEBUG, "Disable", "Enable", " Debugging of CSRSS"},
  36. {FLG_ENABLE_KDEBUG_SYMBOL_LOAD, "Disable", "Enable", " Kernel Debugger Symbol load"},
  37. {FLG_DISABLE_PAGE_KERNEL_STACKS, "Enable", "Disable", " Paging of Kernel Stacks"},
  38. {FLG_HEAP_DISABLE_COALESCING, "Enable", "Disable", " Heap Coalescing on Free"},
  39. {FLG_ENABLE_CLOSE_EXCEPTIONS, "Disable", "Enable", " Close Exceptions"},
  40. {FLG_ENABLE_EXCEPTION_LOGGING, "Disable", "Enable", " Exception Logging"},
  41. {FLG_ENABLE_HANDLE_TYPE_TAGGING, "Disable", "Enable", " Handle type tagging"},
  42. {FLG_HEAP_PAGE_ALLOCS, "Disable", "Enable", " Heap page allocs"},
  43. {FLG_DEBUG_INITIAL_COMMAND_EX, "Disable", "Enable", " Extended debug initial command"},
  44. {FLG_DISABLE_DBGPRINT, "Enable", "Disable"," DbgPrint to debugger"},
  45. {0, NULL}
  46. };
  47. void
  48. DisplayGlobalFlags(
  49. LPSTR IndentString,
  50. DWORD NtGlobalFlags,
  51. BOOLEAN Set
  52. )
  53. {
  54. ULONG i;
  55. for (i=0; NtGlobalFlagNames[i].Description; i++) {
  56. if (NtGlobalFlagNames[i].Flag & NtGlobalFlags) {
  57. printf( "%s%s%s\n",
  58. IndentString,
  59. Set ? NtGlobalFlagNames[i].SetPrefix :
  60. NtGlobalFlagNames[i].ClearPrefix,
  61. NtGlobalFlagNames[i].Description
  62. );
  63. }
  64. }
  65. return;
  66. }
  67. BOOL fVerbose;
  68. BOOL fUsage;
  69. BOOL fConfigInfoChanged;
  70. BOOL fImageHasConfigInfo;
  71. BOOL fImageHeaderChanged;
  72. LPSTR CurrentImageName;
  73. BOOL f64bitImage;
  74. LOADED_IMAGE CurrentImage;
  75. PIMAGE_LOAD_CONFIG_DIRECTORY pConfigInfo;
  76. CHAR DebugFilePath[_MAX_PATH];
  77. LPSTR SymbolPath;
  78. ULONG GlobalFlagsClear;
  79. ULONG GlobalFlagsSet;
  80. ULONG CriticalSectionDefaultTimeout;
  81. ULONG ProcessHeapFlags;
  82. ULONG MajorSubsystemVersion;
  83. ULONG MinorSubsystemVersion;
  84. ULONG Win32VersionValue;
  85. ULONG Win32CSDVerValue;
  86. BOOLEAN fUniprocessorOnly;
  87. BOOLEAN fRestrictedWorkingSet;
  88. BOOLEAN fEnableLargeAddresses;
  89. BOOLEAN fNoBind;
  90. BOOLEAN fEnableTerminalServerAware;
  91. BOOLEAN fDisableTerminalServerAware;
  92. BOOLEAN fSwapRunNet;
  93. BOOLEAN fSwapRunCD;
  94. BOOLEAN fQuiet;
  95. ULONGLONG DeCommitFreeBlockThreshold;
  96. ULONGLONG DeCommitTotalFreeThreshold;
  97. ULONGLONG MaximumAllocationSize;
  98. ULONGLONG VirtualMemoryThreshold;
  99. ULONGLONG ImageProcessAffinityMask;
  100. ULONGLONG SizeOfStackReserve;
  101. ULONGLONG SizeOfStackCommit;
  102. VOID
  103. DisplayImageInfo(
  104. BOOL HasConfigInfo
  105. );
  106. PVOID
  107. GetAddressOfExportedData(
  108. PLOADED_IMAGE Dll,
  109. LPSTR ExportedName
  110. );
  111. ULONGLONG
  112. ConvertNum(
  113. char *s
  114. )
  115. {
  116. ULONGLONG result;
  117. int n;
  118. if (!_strnicmp( s, "0x", 2 )) {
  119. s += 2;
  120. n = sscanf( s, "%I64x", &result );
  121. }
  122. else {
  123. n = sscanf( s, "%I64d", &result );
  124. }
  125. return( ( n != 1 ) ? 0 : result );
  126. } // ConvertNum()
  127. __inline PVOID
  128. GetVaForRva(
  129. PLOADED_IMAGE Image,
  130. ULONG Rva
  131. )
  132. {
  133. PVOID Va;
  134. Va = ImageRvaToVa( Image->FileHeader,
  135. Image->MappedAddress,
  136. Rva,
  137. &Image->LastRvaSection
  138. );
  139. return Va;
  140. }
  141. PVOID
  142. GetAddressOfExportedData(
  143. PLOADED_IMAGE Dll,
  144. LPSTR ExportedName
  145. )
  146. {
  147. PIMAGE_EXPORT_DIRECTORY Exports;
  148. ULONG ExportSize;
  149. USHORT HintIndex;
  150. USHORT OrdinalNumber;
  151. PULONG NameTableBase;
  152. PUSHORT NameOrdinalTableBase;
  153. PULONG FunctionTableBase;
  154. LPSTR NameTableName;
  155. Exports = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData( (PVOID)Dll->MappedAddress,
  156. FALSE,
  157. IMAGE_DIRECTORY_ENTRY_EXPORT,
  158. &ExportSize
  159. );
  160. if (Exports) {
  161. NameTableBase = (PULONG)GetVaForRva( Dll, Exports->AddressOfNames );
  162. NameOrdinalTableBase = (PUSHORT)GetVaForRva( Dll, Exports->AddressOfNameOrdinals );
  163. FunctionTableBase = (PULONG)GetVaForRva( Dll, Exports->AddressOfFunctions );
  164. if (NameTableBase != NULL &&
  165. NameOrdinalTableBase != NULL &&
  166. FunctionTableBase != NULL
  167. ) {
  168. for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
  169. NameTableName = (LPSTR)GetVaForRva( Dll, NameTableBase[ HintIndex ] );
  170. if (NameTableName) {
  171. if (!strcmp( ExportedName, NameTableName )) {
  172. OrdinalNumber = NameOrdinalTableBase[ HintIndex ];
  173. return FunctionTableBase[ OrdinalNumber ] + Dll->MappedAddress;
  174. }
  175. }
  176. }
  177. }
  178. }
  179. return NULL;
  180. }
  181. VOID
  182. DisplayConfigInfo32(PIMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig)
  183. {
  184. if (LoadConfig->GlobalFlagsClear) {
  185. printf( " NtGlobalFlags to clear: %08x\n", LoadConfig->GlobalFlagsClear);
  186. DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsClear, FALSE );
  187. }
  188. if (LoadConfig->GlobalFlagsSet) {
  189. printf( " NtGlobalFlags to set: %08x\n", LoadConfig->GlobalFlagsSet);
  190. DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsSet, TRUE );
  191. }
  192. if (LoadConfig->CriticalSectionDefaultTimeout) {
  193. printf( " Default Critical Section Timeout: %u milliseconds\n", LoadConfig->CriticalSectionDefaultTimeout);
  194. }
  195. if (LoadConfig->DeCommitFreeBlockThreshold) {
  196. printf( " Process Heap DeCommit Free Block threshold: %08x\n", (DWORD)LoadConfig->DeCommitFreeBlockThreshold);
  197. }
  198. if (LoadConfig->DeCommitTotalFreeThreshold) {
  199. printf( " Process Heap DeCommit Total Free threshold: %08x\n", (DWORD)LoadConfig->DeCommitTotalFreeThreshold);
  200. }
  201. if (LoadConfig->LockPrefixTable) {
  202. printf( " Lock Prefix Table: %x\n", LoadConfig->LockPrefixTable);
  203. }
  204. if (LoadConfig->MaximumAllocationSize) {
  205. printf( " Process Heap Maximum Allocation Size: %08x\n", LoadConfig->MaximumAllocationSize);
  206. }
  207. if (LoadConfig->VirtualMemoryThreshold) {
  208. printf( " Process Heap VirtualAlloc Threshold: %08x\n", LoadConfig->VirtualMemoryThreshold);
  209. }
  210. if (LoadConfig->ProcessHeapFlags) {
  211. printf( " Process Heap Flags: %08x\n", LoadConfig->ProcessHeapFlags);
  212. }
  213. if (LoadConfig->ProcessAffinityMask) {
  214. printf( " Process Affinity Mask: %08x\n", LoadConfig->ProcessAffinityMask);
  215. }
  216. if (LoadConfig->CSDVersion) {
  217. printf( " CSD version: %d\n", LoadConfig->CSDVersion);
  218. }
  219. if (LoadConfig->Size >= FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount)) {
  220. if (LoadConfig->SecurityCookie) {
  221. printf( " Security Cookie offset: %x\n", LoadConfig->SecurityCookie);
  222. }
  223. if (LoadConfig->SEHandlerTable) {
  224. printf( " SEH handler table: %x\n", LoadConfig->SEHandlerTable);
  225. }
  226. if (LoadConfig->SEHandlerCount) {
  227. printf( " SEH Handler count: %d\n", LoadConfig->SEHandlerCount);
  228. }
  229. }
  230. }
  231. VOID
  232. DisplayConfigInfo64(PIMAGE_LOAD_CONFIG_DIRECTORY64 LoadConfig)
  233. {
  234. if (LoadConfig->GlobalFlagsClear) {
  235. printf( " NtGlobalFlags to clear: %08x\n", LoadConfig->GlobalFlagsClear);
  236. DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsClear, FALSE );
  237. }
  238. if (LoadConfig->GlobalFlagsSet) {
  239. printf( " NtGlobalFlags to set: %08x\n", LoadConfig->GlobalFlagsSet);
  240. DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsSet, TRUE );
  241. }
  242. if (LoadConfig->CriticalSectionDefaultTimeout) {
  243. printf( " Default Critical Section Timeout: %u milliseconds\n", LoadConfig->CriticalSectionDefaultTimeout);
  244. }
  245. if (LoadConfig->DeCommitFreeBlockThreshold) {
  246. printf( " Process Heap DeCommit Free Block threshold: %I64x\n", LoadConfig->DeCommitFreeBlockThreshold);
  247. }
  248. if (LoadConfig->DeCommitTotalFreeThreshold) {
  249. printf( " Process Heap DeCommit Total Free threshold: %I64x\n", LoadConfig->DeCommitTotalFreeThreshold);
  250. }
  251. if (LoadConfig->LockPrefixTable) {
  252. printf( " Lock Prefix Table: %I64x\n", LoadConfig->LockPrefixTable);
  253. }
  254. if (LoadConfig->MaximumAllocationSize) {
  255. printf( " Process Heap Maximum Allocation Size: %I64x\n", LoadConfig->MaximumAllocationSize);
  256. }
  257. if (LoadConfig->VirtualMemoryThreshold) {
  258. printf( " Process Heap VirtualAlloc Threshold: %I64x\n", LoadConfig->VirtualMemoryThreshold);
  259. }
  260. if (LoadConfig->ProcessHeapFlags) {
  261. printf( " Process Heap Flags: %08x\n", LoadConfig->ProcessHeapFlags);
  262. }
  263. if (LoadConfig->ProcessAffinityMask) {
  264. printf( " Process Affinity Mask: %I64x\n", LoadConfig->ProcessAffinityMask);
  265. }
  266. if (LoadConfig->CSDVersion) {
  267. printf( " CSD version: %d\n", LoadConfig->CSDVersion);
  268. }
  269. if (LoadConfig->Size >= FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount)) {
  270. if (LoadConfig->SecurityCookie) {
  271. printf( " Security Cookie offset: %I64x\n", LoadConfig->SecurityCookie);
  272. }
  273. if (LoadConfig->SEHandlerTable) {
  274. printf( " SEH handler table: %I64x\n", LoadConfig->SEHandlerTable);
  275. }
  276. if (LoadConfig->SEHandlerCount) {
  277. printf( " SEH Handler count: %d\n", LoadConfig->SEHandlerCount);
  278. }
  279. }
  280. }
  281. VOID
  282. DisplayHeaderInfo32(PIMAGE_NT_HEADERS32 NtHeader)
  283. {
  284. printf( " Subsystem Version of %u.%u\n", NtHeader->OptionalHeader.MajorSubsystemVersion, NtHeader->OptionalHeader.MinorSubsystemVersion);
  285. if (NtHeader->OptionalHeader.Win32VersionValue) {
  286. printf( " Win32 GetVersion return value: %08x\n", NtHeader->OptionalHeader.Win32VersionValue);
  287. }
  288. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) {
  289. printf( " Image can handle large (>2GB) addresses\n" );
  290. }
  291. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP) {
  292. printf( " Image will run from swapfile if located on net\n" );
  293. }
  294. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) {
  295. printf( " Image will run from swapfile if located on removable media\n" );
  296. }
  297. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) {
  298. printf( " Image can only run in uni-processor mode on multi-processor systems\n" );
  299. }
  300. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM) {
  301. printf( " Image working set trimmed aggressively on small memory systems\n" );
  302. }
  303. if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) {
  304. printf( " Image is Terminal Server aware\n" );
  305. }
  306. if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND) {
  307. printf( " Image does not support binding\n" );
  308. }
  309. if (NtHeader->OptionalHeader.SizeOfStackReserve) {
  310. printf( " Stack Reserve Size: 0x%x\n", NtHeader->OptionalHeader.SizeOfStackReserve );
  311. }
  312. if (NtHeader->OptionalHeader.SizeOfStackCommit) {
  313. printf( " Stack Commit Size: 0x%x\n", NtHeader->OptionalHeader.SizeOfStackCommit );
  314. }
  315. }
  316. VOID
  317. DisplayHeaderInfo64(PIMAGE_NT_HEADERS64 NtHeader)
  318. {
  319. printf( " Subsystem Version of %u.%u\n", NtHeader->OptionalHeader.MajorSubsystemVersion, NtHeader->OptionalHeader.MinorSubsystemVersion);
  320. if (NtHeader->OptionalHeader.Win32VersionValue) {
  321. printf( " Win32 GetVersion return value: %08x\n", NtHeader->OptionalHeader.Win32VersionValue);
  322. }
  323. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) {
  324. printf( " Image can handle large (>2GB) addresses\n" );
  325. }
  326. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP) {
  327. printf( " Image will run from swapfile if located on net\n" );
  328. }
  329. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) {
  330. printf( " Image will run from swapfile if located on removable media\n" );
  331. }
  332. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) {
  333. printf( " Image can only run in uni-processor mode on multi-processor systems\n" );
  334. }
  335. if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM) {
  336. printf( " Image working set trimmed aggressively on small memory systems\n" );
  337. }
  338. if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) {
  339. printf( " Image is Terminal Server aware\n" );
  340. }
  341. if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND) {
  342. printf( " Image does not support binding\n" );
  343. }
  344. if (NtHeader->OptionalHeader.SizeOfStackReserve) {
  345. printf( " Stack Reserve Size: 0x%I64x\n", NtHeader->OptionalHeader.SizeOfStackReserve );
  346. }
  347. if (NtHeader->OptionalHeader.SizeOfStackCommit) {
  348. printf( " Stack Commit Size: 0x%I64x\n", NtHeader->OptionalHeader.SizeOfStackCommit );
  349. }
  350. }
  351. BOOL
  352. CheckIfConfigInfoChanged64(PIMAGE_LOAD_CONFIG_DIRECTORY64 LoadConfig)
  353. {
  354. if ((GlobalFlagsClear && (LoadConfig->GlobalFlagsClear != GlobalFlagsClear)) ||
  355. (GlobalFlagsSet && (LoadConfig->GlobalFlagsSet != GlobalFlagsSet)) ||
  356. (CriticalSectionDefaultTimeout && (LoadConfig->CriticalSectionDefaultTimeout != CriticalSectionDefaultTimeout)) ||
  357. (ProcessHeapFlags && (LoadConfig->ProcessHeapFlags != ProcessHeapFlags)) ||
  358. (DeCommitFreeBlockThreshold && (LoadConfig->DeCommitFreeBlockThreshold != DeCommitFreeBlockThreshold)) ||
  359. (DeCommitTotalFreeThreshold && (LoadConfig->DeCommitTotalFreeThreshold != DeCommitTotalFreeThreshold)) ||
  360. (MaximumAllocationSize && (LoadConfig->MaximumAllocationSize != MaximumAllocationSize)) ||
  361. (VirtualMemoryThreshold && (LoadConfig->VirtualMemoryThreshold != VirtualMemoryThreshold)) ||
  362. (ImageProcessAffinityMask && (LoadConfig->ProcessAffinityMask != ImageProcessAffinityMask)))
  363. {
  364. return TRUE;
  365. } else {
  366. return FALSE;
  367. }
  368. }
  369. BOOL
  370. CheckIfConfigInfoChanged32(PIMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig)
  371. {
  372. if ((GlobalFlagsClear && (LoadConfig->GlobalFlagsClear != GlobalFlagsClear)) ||
  373. (GlobalFlagsSet && (LoadConfig->GlobalFlagsSet != GlobalFlagsSet)) ||
  374. (CriticalSectionDefaultTimeout && (LoadConfig->CriticalSectionDefaultTimeout != CriticalSectionDefaultTimeout)) ||
  375. (ProcessHeapFlags && (LoadConfig->ProcessHeapFlags != ProcessHeapFlags)) ||
  376. (DeCommitFreeBlockThreshold && (LoadConfig->DeCommitFreeBlockThreshold != (DWORD)DeCommitFreeBlockThreshold)) ||
  377. (DeCommitTotalFreeThreshold && (LoadConfig->DeCommitTotalFreeThreshold != (DWORD)DeCommitTotalFreeThreshold)) ||
  378. (MaximumAllocationSize && (LoadConfig->MaximumAllocationSize != (DWORD)MaximumAllocationSize)) ||
  379. (VirtualMemoryThreshold && (LoadConfig->VirtualMemoryThreshold != (DWORD)VirtualMemoryThreshold)) ||
  380. (ImageProcessAffinityMask && (LoadConfig->ProcessAffinityMask != (DWORD)ImageProcessAffinityMask)))
  381. {
  382. return TRUE;
  383. } else {
  384. return FALSE;
  385. }
  386. }
  387. BOOL
  388. CheckIfImageHeaderChanged32(PIMAGE_NT_HEADERS32 NtHeader)
  389. {
  390. if ((MajorSubsystemVersion &&
  391. NtHeader->OptionalHeader.MajorSubsystemVersion != (USHORT)MajorSubsystemVersion ||
  392. NtHeader->OptionalHeader.MinorSubsystemVersion != (USHORT)MinorSubsystemVersion)
  393. ||
  394. (Win32VersionValue && (NtHeader->OptionalHeader.Win32VersionValue != Win32VersionValue))
  395. ||
  396. (fEnableLargeAddresses && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
  397. ||
  398. (fNoBind && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND))
  399. ||
  400. (fEnableTerminalServerAware && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
  401. ||
  402. (fDisableTerminalServerAware && (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
  403. ||
  404. (fSwapRunNet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP))
  405. ||
  406. (fSwapRunCD && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP))
  407. ||
  408. (fUniprocessorOnly && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
  409. ||
  410. (fRestrictedWorkingSet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM))
  411. ||
  412. (SizeOfStackReserve && (NtHeader->OptionalHeader.SizeOfStackReserve != (DWORD)SizeOfStackReserve))
  413. ||
  414. (SizeOfStackCommit && (NtHeader->OptionalHeader.SizeOfStackCommit != (DWORD)SizeOfStackCommit)) )
  415. {
  416. return TRUE;
  417. } else {
  418. return FALSE;
  419. }
  420. }
  421. BOOL
  422. CheckIfImageHeaderChanged64(PIMAGE_NT_HEADERS64 NtHeader)
  423. {
  424. if ((MajorSubsystemVersion &&
  425. NtHeader->OptionalHeader.MajorSubsystemVersion != (USHORT)MajorSubsystemVersion ||
  426. NtHeader->OptionalHeader.MinorSubsystemVersion != (USHORT)MinorSubsystemVersion)
  427. ||
  428. (Win32VersionValue && (NtHeader->OptionalHeader.Win32VersionValue != Win32VersionValue))
  429. ||
  430. (fEnableLargeAddresses && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
  431. ||
  432. (fNoBind && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND))
  433. ||
  434. (fEnableTerminalServerAware && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
  435. ||
  436. (fDisableTerminalServerAware && (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
  437. ||
  438. (fSwapRunNet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP))
  439. ||
  440. (fSwapRunCD && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP))
  441. ||
  442. (fUniprocessorOnly && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
  443. ||
  444. (fRestrictedWorkingSet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM))
  445. ||
  446. (SizeOfStackReserve && (NtHeader->OptionalHeader.SizeOfStackReserve != SizeOfStackReserve))
  447. ||
  448. (SizeOfStackCommit && (NtHeader->OptionalHeader.SizeOfStackCommit != SizeOfStackCommit)) )
  449. {
  450. return TRUE;
  451. } else {
  452. return FALSE;
  453. }
  454. }
  455. BOOL
  456. SetImageConfigInformation32(
  457. PLOADED_IMAGE LoadedImage,
  458. PIMAGE_LOAD_CONFIG_DIRECTORY32 ImageConfigInformation
  459. )
  460. {
  461. PIMAGE_LOAD_CONFIG_DIRECTORY32 ImageConfigData;
  462. ULONG i;
  463. ULONG DirectoryAddress;
  464. PIMAGE_NT_HEADERS NtHeaders;
  465. PIMAGE_DATA_DIRECTORY pLoadCfgDataDir;
  466. // We can only write native loadcfg struct
  467. ULONG V1LoadCfgLength = FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable);
  468. ULONG NewDataSize;
  469. if (LoadedImage->hFile == INVALID_HANDLE_VALUE) {
  470. return FALSE;
  471. }
  472. ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY32) ImageDirectoryEntryToData( LoadedImage->MappedAddress,
  473. FALSE,
  474. IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
  475. &i
  476. );
  477. if (ImageConfigData && (i == V1LoadCfgLength)) {
  478. if (ImageConfigInformation->Size) {
  479. // Incoming size specified?
  480. if (ImageConfigData->Size == ImageConfigInformation->Size) {
  481. // Current size same as new size? Do the copy
  482. memcpy( ImageConfigData, ImageConfigInformation, ImageConfigInformation->Size);
  483. return TRUE;
  484. }
  485. if (ImageConfigData->Size > ImageConfigInformation->Size) {
  486. // New size < old size - can't allow that
  487. return FALSE;
  488. }
  489. // Last case is new size > old size - fall through and find room for new data.
  490. } else {
  491. // Incoming size not set - must be an V1 user.
  492. if (ImageConfigData->Size) {
  493. // Existing size set? Can't overwrite new data with old data
  494. return FALSE;
  495. }
  496. // New and old are both V1 structs.
  497. memcpy( ImageConfigData, ImageConfigInformation, V1LoadCfgLength);
  498. return TRUE;
  499. }
  500. }
  501. NewDataSize = ImageConfigInformation->Size ? ImageConfigInformation->Size : V1LoadCfgLength;
  502. DirectoryAddress = GetImageUnusedHeaderBytes( LoadedImage, &i );
  503. if (i < NewDataSize) {
  504. return FALSE;
  505. }
  506. NtHeaders = LoadedImage->FileHeader;
  507. pLoadCfgDataDir = &((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
  508. pLoadCfgDataDir->VirtualAddress = DirectoryAddress;
  509. pLoadCfgDataDir->Size = V1LoadCfgLength;
  510. ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY32) ((PCHAR)LoadedImage->MappedAddress + DirectoryAddress);
  511. memcpy( ImageConfigData, ImageConfigInformation, sizeof( *ImageConfigData ) );
  512. return TRUE;
  513. }
  514. BOOL
  515. SetImageConfigInformation64(
  516. PLOADED_IMAGE LoadedImage,
  517. PIMAGE_LOAD_CONFIG_DIRECTORY64 ImageConfigInformation
  518. )
  519. {
  520. PIMAGE_LOAD_CONFIG_DIRECTORY64 ImageConfigData;
  521. ULONG i;
  522. ULONG DirectoryAddress;
  523. PIMAGE_NT_HEADERS NtHeaders;
  524. PIMAGE_DATA_DIRECTORY pLoadCfgDataDir;
  525. // We can only write native loadcfg struct
  526. ULONG V1LoadCfgLength = FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, SEHandlerTable);
  527. ULONG NewDataSize;
  528. if (LoadedImage->hFile == INVALID_HANDLE_VALUE) {
  529. return FALSE;
  530. }
  531. ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY64) ImageDirectoryEntryToData( LoadedImage->MappedAddress,
  532. FALSE,
  533. IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
  534. &i
  535. );
  536. if (ImageConfigData && (i == V1LoadCfgLength)) {
  537. if (ImageConfigInformation->Size) {
  538. // Incoming size specified?
  539. if (ImageConfigData->Size == ImageConfigInformation->Size) {
  540. // Current size same as new size? Do the copy
  541. memcpy( ImageConfigData, ImageConfigInformation, ImageConfigInformation->Size);
  542. return TRUE;
  543. }
  544. if (ImageConfigData->Size > ImageConfigInformation->Size) {
  545. // New size < old size - can't allow that
  546. return FALSE;
  547. }
  548. // Last case is new size > old size - fall through and find room for new data.
  549. } else {
  550. // Incoming size not set - must be an V1 user.
  551. if (ImageConfigData->Size) {
  552. // Existing size set? Can't overwrite new data with old data
  553. return FALSE;
  554. }
  555. // New and old are both V1 structs.
  556. memcpy( ImageConfigData, ImageConfigInformation, V1LoadCfgLength);
  557. return TRUE;
  558. }
  559. }
  560. NewDataSize = ImageConfigInformation->Size ? ImageConfigInformation->Size : V1LoadCfgLength;
  561. DirectoryAddress = GetImageUnusedHeaderBytes( LoadedImage, &i );
  562. if (i < NewDataSize) {
  563. return FALSE;
  564. }
  565. NtHeaders = LoadedImage->FileHeader;
  566. pLoadCfgDataDir = &((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
  567. pLoadCfgDataDir->VirtualAddress = DirectoryAddress;
  568. pLoadCfgDataDir->Size = V1LoadCfgLength;
  569. ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY64) ((PCHAR)LoadedImage->MappedAddress + DirectoryAddress);
  570. memcpy( ImageConfigData, ImageConfigInformation, sizeof( *ImageConfigData ) );
  571. return TRUE;
  572. }
  573. int __cdecl
  574. main(
  575. int argc,
  576. char *argv[],
  577. char *envp[]
  578. )
  579. {
  580. UCHAR c;
  581. LPSTR p, sMajor, sMinor, sReserve, sCommit;
  582. ULONG HeaderSum;
  583. SYSTEMTIME SystemTime;
  584. FILETIME LastWriteTime;
  585. DWORD OldChecksum;
  586. PVOID pNewConfigData, pOldConfigData;
  587. DWORD ImageConfigSize;
  588. fUsage = FALSE;
  589. fVerbose = FALSE;
  590. _tzset();
  591. if (argc <= 1) {
  592. goto showUsage;
  593. }
  594. while (--argc) {
  595. p = *++argv;
  596. if (*p == '/' || *p == '-') {
  597. while (c = *++p)
  598. switch (toupper( c )) {
  599. case '?':
  600. fUsage = TRUE;
  601. break;
  602. case 'A':
  603. if (--argc) {
  604. ImageProcessAffinityMask = ConvertNum( *++argv );
  605. if (ImageProcessAffinityMask == 0) {
  606. fprintf( stderr, "IMAGECFG: invalid affinity mask specified to /a switch.\n" );
  607. fUsage = TRUE;
  608. }
  609. } else {
  610. fprintf( stderr, "IMAGECFG: /a switch missing argument.\n" );
  611. fUsage = TRUE;
  612. }
  613. break;
  614. case 'C':
  615. if (--argc) {
  616. if (sscanf( *++argv, "%x", &Win32CSDVerValue ) != 1) {
  617. fprintf( stderr, "IMAGECFG: invalid version string specified to /c switch.\n" );
  618. fUsage = TRUE;
  619. }
  620. } else {
  621. fprintf( stderr, "IMAGECFG: /c switch missing argument.\n" );
  622. fUsage = TRUE;
  623. }
  624. break;
  625. case 'D':
  626. if (argc >= 2) {
  627. argc -= 2;
  628. DeCommitFreeBlockThreshold = ConvertNum( *++argv );
  629. DeCommitTotalFreeThreshold = ConvertNum( *++argv );
  630. } else {
  631. fprintf( stderr, "IMAGECFG: /d switch missing arguments.\n" );
  632. fUsage = TRUE;
  633. }
  634. break;
  635. case 'G':
  636. if (argc >= 2) {
  637. argc -= 2;
  638. GlobalFlagsClear = (ULONG) ConvertNum( *++argv );
  639. GlobalFlagsSet = (ULONG) ConvertNum( *++argv );
  640. } else {
  641. fprintf( stderr, "IMAGECFG: /g switch missing arguments.\n" );
  642. fUsage = TRUE;
  643. }
  644. break;
  645. case 'H':
  646. if (argc > 2) {
  647. INT flag = -1;
  648. if (sscanf( *++argv, "%d", &flag ) != 1) {
  649. fprintf( stderr, "IMAGECFG: invalid option string specified to /h switch.\n" );
  650. fUsage = TRUE;
  651. } else {
  652. --argc;
  653. if (flag == 0) {
  654. fDisableTerminalServerAware = TRUE;
  655. } else if (flag == 1) {
  656. fEnableTerminalServerAware = TRUE;
  657. } else {
  658. fprintf( stderr, "IMAGECFG: /h switch invalid argument.\n" );
  659. fUsage = TRUE;
  660. }
  661. }
  662. } else {
  663. fprintf( stderr, "IMAGECFG: /h switch missing argument.\n" );
  664. fUsage = TRUE;
  665. }
  666. break;
  667. case 'K':
  668. if (--argc) {
  669. sReserve = *++argv;
  670. sCommit = strchr( sReserve, '.' );
  671. if (sCommit != NULL) {
  672. *sCommit++ = '\0';
  673. SizeOfStackCommit = ConvertNum( sCommit );
  674. SizeOfStackCommit = ((SizeOfStackCommit + 0x00000FFFui64) & ~0x00000FFFui64);
  675. if (SizeOfStackCommit == 0) {
  676. fprintf( stderr, "IMAGECFG: invalid stack commit size specified to /k switch.\n" );
  677. fUsage = TRUE;
  678. }
  679. }
  680. SizeOfStackReserve = ConvertNum( sReserve );
  681. SizeOfStackReserve = ((SizeOfStackReserve + 0x0000FFFFui64) & ~0x0000FFFFui64);
  682. if (SizeOfStackReserve == 0) {
  683. fprintf( stderr, "IMAGECFG: invalid stack reserve size specified to /k switch.\n" );
  684. fUsage = TRUE;
  685. }
  686. } else {
  687. fprintf( stderr, "IMAGECFG: /w switch missing argument.\n" );
  688. fUsage = TRUE;
  689. }
  690. break;
  691. case 'L':
  692. fEnableLargeAddresses = TRUE;
  693. break;
  694. case 'M':
  695. if (--argc) {
  696. MaximumAllocationSize = ConvertNum( *++argv );
  697. } else {
  698. fprintf( stderr, "IMAGECFG: /m switch missing argument.\n" );
  699. fUsage = TRUE;
  700. }
  701. break;
  702. case 'N':
  703. fNoBind = TRUE;
  704. break;
  705. case 'O':
  706. if (--argc) {
  707. CriticalSectionDefaultTimeout = (ULONG) ConvertNum( *++argv );
  708. } else {
  709. fprintf( stderr, "IMAGECFG: /o switch missing argument.\n" );
  710. fUsage = TRUE;
  711. }
  712. break;
  713. case 'P':
  714. if (--argc) {
  715. ProcessHeapFlags = (ULONG) ConvertNum( *++argv );
  716. } else {
  717. fprintf( stderr, "IMAGECFG: /p switch missing argument.\n" );
  718. fUsage = TRUE;
  719. }
  720. break;
  721. case 'Q':
  722. fQuiet = TRUE;
  723. break;
  724. case 'R':
  725. fRestrictedWorkingSet = TRUE;
  726. break;
  727. case 'S':
  728. if (--argc) {
  729. SymbolPath = *++argv;
  730. } else {
  731. fprintf( stderr, "IMAGECFG: /s switch missing path argument.\n" );
  732. fUsage = TRUE;
  733. }
  734. break;
  735. case 'T':
  736. if (--argc) {
  737. VirtualMemoryThreshold = ConvertNum( *++argv );
  738. } else {
  739. fprintf( stderr, "IMAGECFG: /t switch missing argument.\n" );
  740. fUsage = TRUE;
  741. }
  742. break;
  743. case 'U':
  744. fUniprocessorOnly = TRUE;
  745. break;
  746. case 'V':
  747. if (--argc) {
  748. sMajor = *++argv;
  749. sMinor = strchr( sMajor, '.' );
  750. if (sMinor != NULL) {
  751. *sMinor++ = '\0';
  752. MinorSubsystemVersion = (ULONG) ConvertNum( sMinor );
  753. }
  754. MajorSubsystemVersion = (ULONG) ConvertNum( sMajor );
  755. if (MajorSubsystemVersion == 0) {
  756. fprintf( stderr, "IMAGECFG: invalid version string specified to /v switch.\n" );
  757. fUsage = TRUE;
  758. }
  759. } else {
  760. fprintf( stderr, "IMAGECFG: /v switch missing argument.\n" );
  761. fUsage = TRUE;
  762. }
  763. break;
  764. case 'W':
  765. if (--argc) {
  766. if (sscanf( *++argv, "%x", &Win32VersionValue ) != 1) {
  767. fprintf( stderr, "IMAGECFG: invalid version string specified to /w switch.\n" );
  768. fUsage = TRUE;
  769. }
  770. } else {
  771. fprintf( stderr, "IMAGECFG: /w switch missing argument.\n" );
  772. fUsage = TRUE;
  773. }
  774. break;
  775. case 'X':
  776. fSwapRunNet = TRUE;
  777. break;
  778. case 'Y':
  779. fSwapRunCD = TRUE;
  780. break;
  781. default:
  782. fprintf( stderr, "IMAGECFG: Invalid switch - /%c\n", c );
  783. fUsage = TRUE;
  784. break;
  785. }
  786. if ( fUsage ) {
  787. showUsage:
  788. fprintf( stderr,
  789. "usage: IMAGECFG [switches] image-names... \n"
  790. " [-?] display this message\n"
  791. " [-a Process Affinity mask value in hex]\n"
  792. " [-c Win32 GetVersionEx Service Pack return value in hex]\n"
  793. " [-d decommit thresholds]\n"
  794. " [-g bitsToClear bitsToSet]\n"
  795. " [-h 1|0 (Enable/Disable Terminal Server Compatible bit)\n"
  796. " [-k StackReserve[.StackCommit]\n"
  797. " [-l enable large (>2GB) addresses\n"
  798. " [-m maximum allocation size]\n"
  799. " [-n bind no longer allowed on this image\n"
  800. " [-o default critical section timeout\n"
  801. " [-p process heap flags]\n"
  802. " [-q only print config info if changed\n"
  803. " [-r run with restricted working set]\n"
  804. " [-s path to symbol files]\n"
  805. " [-t VirtualAlloc threshold]\n"
  806. " [-u Marks image as uniprocessor only]\n"
  807. " [-v MajorVersion.MinorVersion]\n"
  808. " [-w Win32 GetVersion return value in hex]\n"
  809. " [-x Mark image as Net - Run From Swapfile\n"
  810. " [-y Mark image as Removable - Run From Swapfile\n"
  811. );
  812. exit( 1 );
  813. }
  814. } else {
  815. //
  816. // Map and load the current image
  817. //
  818. CurrentImageName = p;
  819. if (MapAndLoad( CurrentImageName,
  820. NULL,
  821. &CurrentImage,
  822. FALSE,
  823. TRUE // Read only
  824. ) )
  825. {
  826. if (CurrentImage.FileHeader->OptionalHeader.Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
  827. // Don't muck with ROM images.
  828. UnMapAndLoad( &CurrentImage );
  829. continue;
  830. }
  831. if (CurrentImage.FileHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  832. f64bitImage = TRUE;
  833. }
  834. pNewConfigData = malloc(f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32));
  835. if (!pNewConfigData) {
  836. printf("Out of memory\n");
  837. exit(-1);
  838. }
  839. pOldConfigData = ImageDirectoryEntryToData(CurrentImage.MappedAddress,
  840. FALSE,
  841. IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
  842. &ImageConfigSize);
  843. if (pOldConfigData) {
  844. if (!fQuiet) {
  845. if (f64bitImage) {
  846. DisplayConfigInfo64(pOldConfigData);
  847. } else {
  848. DisplayConfigInfo32(pOldConfigData);
  849. }
  850. }
  851. if (((PIMAGE_LOAD_CONFIG_DIRECTORY)pOldConfigData)->Size) {
  852. // New format - Size is the real size.
  853. ImageConfigSize = ((PIMAGE_LOAD_CONFIG_DIRECTORY)pOldConfigData)->Size;
  854. }
  855. memcpy(pNewConfigData, pOldConfigData, ImageConfigSize);
  856. } else {
  857. ZeroMemory(pNewConfigData, f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32));
  858. ((PIMAGE_LOAD_CONFIG_DIRECTORY)pNewConfigData)->Size = f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32);
  859. }
  860. fConfigInfoChanged = f64bitImage ? CheckIfConfigInfoChanged64(pNewConfigData) : CheckIfConfigInfoChanged32(pNewConfigData);
  861. fImageHeaderChanged = f64bitImage ?
  862. CheckIfImageHeaderChanged64((PIMAGE_NT_HEADERS64)&CurrentImage.FileHeader) :
  863. CheckIfImageHeaderChanged32((PIMAGE_NT_HEADERS32)&CurrentImage.FileHeader);
  864. UnMapAndLoad( &CurrentImage );
  865. if (fConfigInfoChanged || fImageHeaderChanged) {
  866. if (MapAndLoad( CurrentImageName, NULL, &CurrentImage, FALSE, FALSE )) {
  867. // Set Load Config data
  868. if (GlobalFlagsClear) {
  869. if (f64bitImage) {
  870. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->GlobalFlagsClear = GlobalFlagsClear;
  871. } else {
  872. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->GlobalFlagsClear = GlobalFlagsClear;
  873. }
  874. }
  875. if (GlobalFlagsSet) {
  876. if (f64bitImage) {
  877. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->GlobalFlagsSet = GlobalFlagsSet;
  878. } else {
  879. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->GlobalFlagsSet = GlobalFlagsSet;
  880. }
  881. }
  882. if (CriticalSectionDefaultTimeout) {
  883. if (f64bitImage) {
  884. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->CriticalSectionDefaultTimeout = CriticalSectionDefaultTimeout;
  885. } else {
  886. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->CriticalSectionDefaultTimeout = CriticalSectionDefaultTimeout;
  887. }
  888. }
  889. if (ProcessHeapFlags) {
  890. if (f64bitImage) {
  891. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->ProcessHeapFlags = ProcessHeapFlags;
  892. } else {
  893. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->ProcessHeapFlags = ProcessHeapFlags;
  894. }
  895. }
  896. if (DeCommitFreeBlockThreshold) {
  897. if (f64bitImage) {
  898. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->DeCommitFreeBlockThreshold = DeCommitFreeBlockThreshold;
  899. } else {
  900. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->DeCommitFreeBlockThreshold = (DWORD)DeCommitFreeBlockThreshold;
  901. }
  902. }
  903. if (DeCommitTotalFreeThreshold) {
  904. if (f64bitImage) {
  905. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->DeCommitTotalFreeThreshold = DeCommitTotalFreeThreshold;
  906. } else {
  907. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->DeCommitTotalFreeThreshold = (DWORD)DeCommitTotalFreeThreshold;
  908. }
  909. }
  910. if (MaximumAllocationSize) {
  911. if (f64bitImage) {
  912. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->MaximumAllocationSize = MaximumAllocationSize;
  913. } else {
  914. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->MaximumAllocationSize = (DWORD)MaximumAllocationSize;
  915. }
  916. }
  917. if (VirtualMemoryThreshold) {
  918. if (f64bitImage) {
  919. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->VirtualMemoryThreshold = VirtualMemoryThreshold;
  920. } else {
  921. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->VirtualMemoryThreshold = (DWORD)VirtualMemoryThreshold;
  922. }
  923. }
  924. if (ImageProcessAffinityMask) {
  925. if (f64bitImage) {
  926. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->ProcessAffinityMask = ImageProcessAffinityMask;
  927. } else {
  928. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->ProcessAffinityMask = (DWORD)ImageProcessAffinityMask;
  929. }
  930. }
  931. if (Win32CSDVerValue != 0) {
  932. if (f64bitImage) {
  933. ((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->CSDVersion = (USHORT)Win32CSDVerValue;
  934. } else {
  935. ((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->CSDVersion = (USHORT)Win32CSDVerValue;
  936. }
  937. }
  938. // Set File header values
  939. if (fEnableLargeAddresses) {
  940. CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
  941. }
  942. if (fSwapRunNet) {
  943. CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
  944. }
  945. if (fSwapRunCD) {
  946. CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
  947. }
  948. if (fUniprocessorOnly) {
  949. CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
  950. }
  951. if (fRestrictedWorkingSet) {
  952. CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_AGGRESIVE_WS_TRIM;
  953. }
  954. // Set Optional header values
  955. if (fNoBind) {
  956. if (f64bitImage) {
  957. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
  958. } else {
  959. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
  960. }
  961. }
  962. if (fEnableTerminalServerAware) {
  963. if (f64bitImage) {
  964. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
  965. } else {
  966. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
  967. }
  968. }
  969. if (fDisableTerminalServerAware) {
  970. if (f64bitImage) {
  971. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
  972. } else {
  973. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
  974. }
  975. }
  976. if (MajorSubsystemVersion != 0) {
  977. if (f64bitImage) {
  978. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.MajorSubsystemVersion = (USHORT)MajorSubsystemVersion;
  979. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.MinorSubsystemVersion = (USHORT)MinorSubsystemVersion;
  980. } else {
  981. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.MajorSubsystemVersion = (USHORT)MajorSubsystemVersion;
  982. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.MinorSubsystemVersion = (USHORT)MinorSubsystemVersion;
  983. }
  984. }
  985. if (Win32VersionValue != 0) {
  986. if (f64bitImage) {
  987. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.Win32VersionValue = Win32VersionValue;
  988. } else {
  989. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.Win32VersionValue = Win32VersionValue;
  990. }
  991. }
  992. if (SizeOfStackReserve) {
  993. if (f64bitImage) {
  994. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackReserve = SizeOfStackReserve;
  995. } else {
  996. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackReserve = (DWORD)SizeOfStackReserve;
  997. }
  998. }
  999. if (SizeOfStackCommit) {
  1000. if (f64bitImage) {
  1001. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackCommit = SizeOfStackCommit;
  1002. } else {
  1003. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackCommit = (DWORD)SizeOfStackCommit;
  1004. }
  1005. }
  1006. if (fConfigInfoChanged) {
  1007. if (f64bitImage) {
  1008. if (SetImageConfigInformation64( &CurrentImage, pNewConfigData )) {
  1009. if (!fQuiet) {
  1010. printf( "%s updated with the following configuration information:\n", CurrentImageName );
  1011. DisplayConfigInfo64(pNewConfigData);
  1012. }
  1013. } else {
  1014. fprintf( stderr, "IMAGECFG: Unable to update configuration information in image.\n" );
  1015. }
  1016. } else {
  1017. if (SetImageConfigInformation32( &CurrentImage, pNewConfigData )) {
  1018. if (!fQuiet) {
  1019. printf( "%s updated with the following configuration information:\n", CurrentImageName );
  1020. DisplayConfigInfo32(pNewConfigData);
  1021. }
  1022. } else {
  1023. fprintf( stderr, "IMAGECFG: Unable to update configuration information in image.\n" );
  1024. }
  1025. }
  1026. }
  1027. //
  1028. // recompute the checksum.
  1029. //
  1030. if (f64bitImage) {
  1031. OldChecksum = ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum;
  1032. ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum = 0;
  1033. CheckSumMappedFile(
  1034. (PVOID)CurrentImage.MappedAddress,
  1035. CurrentImage.SizeOfImage,
  1036. &HeaderSum,
  1037. &((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum
  1038. );
  1039. } else {
  1040. OldChecksum = ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum;
  1041. ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum = 0;
  1042. CheckSumMappedFile(
  1043. (PVOID)CurrentImage.MappedAddress,
  1044. CurrentImage.SizeOfImage,
  1045. &HeaderSum,
  1046. &((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum
  1047. );
  1048. }
  1049. // And update the .dbg file (if requested)
  1050. if (SymbolPath &&
  1051. CurrentImage.FileHeader->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
  1052. if (UpdateDebugInfoFileEx( CurrentImageName,
  1053. SymbolPath,
  1054. DebugFilePath,
  1055. (PIMAGE_NT_HEADERS32)CurrentImage.FileHeader,
  1056. OldChecksum
  1057. )
  1058. ) {
  1059. if (GetLastError() == ERROR_INVALID_DATA) {
  1060. printf( "Warning: Old checksum did not match for %s\n", DebugFilePath);
  1061. }
  1062. printf( "Updated symbols for %s\n", DebugFilePath );
  1063. } else {
  1064. printf( "Unable to update symbols: %s\n", DebugFilePath );
  1065. }
  1066. }
  1067. GetSystemTime( &SystemTime );
  1068. if (SystemTimeToFileTime( &SystemTime, &LastWriteTime )) {
  1069. SetFileTime( CurrentImage.hFile, NULL, NULL, &LastWriteTime );
  1070. }
  1071. UnMapAndLoad( &CurrentImage );
  1072. }
  1073. }
  1074. } else
  1075. if (!CurrentImage.fDOSImage) {
  1076. fprintf( stderr, "IMAGECFG: unable to map and load %s GetLastError= %d\n", CurrentImageName, GetLastError() );
  1077. } else {
  1078. fprintf( stderr,
  1079. "IMAGECFG: unable to modify DOS or Windows image file - %s\n",
  1080. CurrentImageName
  1081. );
  1082. }
  1083. }
  1084. }
  1085. exit( 1 );
  1086. return 1;
  1087. }
  1088. #define STANDALONE_MAP
  1089. #include <mapi.c>