Mt.exe generates 0 size DLL on x64 machine when then size of the input DLL is greater than 32 MB

Dotyczy: Microsoft Windows XP Professional x64 EditionMicrosoft Windows Server 2003 Standard x64 Edition

Summary


MT.exe is used to embed the manifest inside the final DLL to guarantee correct runtime behavior.  There is a specific scenario where final DLL size is zero after embedding the manifest. This issue happens on XP/Win server 2003 x64 bit machines while using local C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\bin\mt.exe to embed manifest into the DLL, where manifest file and the DLL are present on network share. This behavior can be seen only when the input DLL size is greater than ~32 MB. 

Environment:
Window XP x64
Windows Server 2003 x64

Mt.exe Version:
C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\bin>mt -?
Microsoft (R) Manifest Tool version 6.0.4071.0
Copyright (c) Microsoft Corporation 2004.
All rights reserved.

Repro Steps:
1. Take any DLL compiled with Visual Studio 2005 whose size exceeds 32 MB. Say the name of the DLL is Test.DLL. Make sure that manifest is not
embed in the DLL.
 
 2. Copy Test.DLL and following Test.DLL.Manifest on to some network share, say \\NetworkShare\Test
 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
 <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
   <dependency>
     <dependentAssembly>
       <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.4053' processorArchitecture='amd64' publicKeyToken='1fc8b3b9a1e18e3b' />
     </dependentAssembly>
   </dependency>
 </assembly>
 
 3. Now go to XP/Win 2003 server x64 where you have Visual Studio 2005 installed and map a network drive, say Z:\ to \\NetworkShare\Test
 
 4. Run the following command,
 Z:\Test>"C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\bin\mt.exe" -manifest Test.dll.manifest -outputresource:Test.dll;2
 
Expected output:
Test.dll of size ~32 MB

Actual output:
Test.dll of size 0 bytes

More Information


You will find following log in the procmon logs in case of failure scenario:
mt.exe <PID> WriteFile Z:\Test\Test.dll   INSUFFICIENT RESOURCES Offset: 0, Length: ~32

MT.exe uses the WriteFile API, which fails with INSUFFICIENT RESOURCES errors in the non-working scenario. INSUFFICIENT RESOURCES implies ERROR_NO_SYSTEM_RESOURCES(1450) Win32 error. Applications that read and write files may encounter ERROR_NO_SYSTEM_RESOURCES(1450) when using data buffers larger than 32MB or 64MB. The reason for this error is that WriteFile is used with a no-buffering flag, and the maximum buffer size (for mapping virtual addresses to physical addresses with a memory descriptor list) has been exceeded by the file size. On x86 (32-bit) or IA64 (Itanium 64-bit) systems, the maximum buffer size is just under 64MB. For x64 systems, the maximum buffer size is just under 32MB. The maximum unbuffered read and write size limits are imposed by the design of the IO manager inside the Windows executive. The same problem could occur on x86 or IA64 machines, but not until the file size is exceeding 64MB.

Workaround:
This issue does not occur in MT.exe version that comes with Microsoft Windows SDK v6.0A and v7.0A. So you can replace Visual Studio 2005 MT.exe with any of Windows SDK v6.0A and v7.0A.