I have recently installed Windows 8 on my laptop and am having a go with new Windows 8 operating system and the newly introduced Windows Runtime (WinRT) layer. As part of this blog post, I am going to dig deep into WINMD files, which are at the heart of this new WinRT layer.
WINMD File Format
First of all I wanted to understand more about file format of WINMD files. I wanted to know more internal detail about this new file extension so I decided to check it with the old friend DUMPBIN.exe utility using following command:
D:\DDrive\Girish\temp>dumpbin /HEADERS /CLRHEADER
Great news, it worked with dumpbin.exe! I was happy to see that it worked with dumpbin.exe tool (as that confirmed that the file format is familiar) and the tool did give lot of information about the file as well. Find below the output of same, I have highlighted certain key aspects of same:
Dump of file C:\Windows\System32\WinMetadata\Windows.System.winmd
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
1 number of sections
5010588C time date stamp Wed Jul 25 21:35:24 2012
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
11.00 linker version
0 size of code
0 size of initialized data
0 size of uninitialized data
0 entry point
0 base of code
0 base of data
400000 image base (00400000 to 00405FFF)
1000 section alignment
200 file alignment
6.02 operating system version
0.00 image version
6.02 subsystem version
0 Win32 version
6000 size of image
200 size of headers
3 subsystem (Windows CUI)
540 DLL characteristics
No structured exception handler
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
0 [ 0] RVA [size] of Import Directory
0 [ 0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
0 [ 0] RVA [size] of Base Relocation Directory
0 [ 0] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
0 [ 0] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
1000 [ 48] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory
SECTION HEADER #1
45D0 virtual size
1000 virtual address (00401000 to 004055CF)
4600 size of raw data
200 file pointer to raw data (00000200 to 000047FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
2.05 runtime version
1050 [ 4580] RVA [size] of MetaData Directory
0 entry point token
0 [ 0] RVA [size] of Resources Directory
0 [ 0] RVA [size] of StrongNameSignature Directory
0 [ 0] RVA [size] of CodeManagerTable Directory
0 [ 0] RVA [size] of VTableFixups Directory
0 [ 0] RVA [size] of ExportAddressTableJumps Directory
0 [ 0] RVA [size] of ManagedNativeHeader Directory
As you can see from the highlighed parts, it is clear that:
1. WINMD files are standard PE/COFF format files.
2. WINMD files are standard Win-32 DLL files.
3. WINMD files contain CLR headers as well which means WINMD files comply with ECMA-335 CLI specification for file format and hence, contain rich metadata (which means they are not just native Win 32 DLLs but contain rich metadata just like any other CLR assembly)
In simple terms, WINMD files are DLL files (or CLR assemblies) with rich .Net framework metadata to expose underlying Windows operating system APIs.
Disassemble WINMD Files
Now we know that WINMD files comply ECMA-335 CLI specification for file format and hence, they are .Net assemblies. In that case, we should be able to open these using ILDAsm (IL Disassembler) tool or Reflector. I tried to open Windows.System.winmd file and I was able to open it in ILDASM, refer below screenshot:
Remember, you have to use latest version of ILDAsm supplied with Visual Studio 2012 as previous versions would not work with WINMD files.
Excellent! Now you would think that you can browse through all the types and methods and method IL code but there is a surprise. When you try to open any method body you will get to see below:
.method public hidebysig newslot virtual final
instance void Enable() runtime managed
} // end of method SignalNotifier::Enable
You will notice that there is no IL code in the method body and the method is marked with runtime managed flag, to understand the meaning of the flag we will need to refer ECMA-335 Common Language Infrastructure (CLI) specification.
Find below extract from ECMA-335 Common Language Infrastructure (CLI) specification. for method flags:
||Method impl is provided by the runtime
||Method impl is managed
It tells us that runtime managed means method does not have a body AND the managed implementation will be provided by runtime. This brings us to following conclusion that WINMD files (under C:\Windows\System32\WinMetadata folder) do not contain code but metadata only. Since these files do not contain code but rich metadata only hence, that also explains why these files are so small in size.
WINMD and no code?
Does it mean that WINMD files cannot contain code? Not really. Usually, WINMD files will not contain code but not that they cannot. Usually, WINMD files will only contain rich metadata but if you create a new custom windows runtime component of your own using Visual Studio 2012, it will produce a WINMD file and it will contain both, code and rich metada and you will be able to verify the same using ILDAsm tool.
1. WINMD stands for Windows Meta Data and as the name suggests these files contain rich metadata for Windows operating system APIs, making these APIs available to managed world.
2. WINMD files use DLL file format but with a different extension. Question is why did Microsoft choose to create a new file extension (WINMD) and not reuse existing DLL extension? I believe the reason would be that WINMD files can contain just metadata unlike traditional DLL files which are generally used as library of functions and therefore contain code too. Nonetheless, WINMD files are DLL files.
3. WINMD files contain CLR header and rich metadata about its types, methods, etc. and hence, these files are .Net Framework assemblies. This makes Windows APIs available to managed world in a natural and familiar manner.
4. Lastly, as we saw that these meta data only files do not contain code, it tells me that WinRT is NOT a new layer in itself but, exposes the underlying Windows operating system API layer to managed world (more about this in future post).
In my next blog post, we will go further into this new world of Windows Runtime (WinRT) introduced with Windows 8.
(A salute to motherland)
P.S. In addition to blogging, I use Twitter to share tips, links, etc. My Twitter handle is: @girishjjain