Getting DLL version information through Win32 - Crash in VerQueryValue (...) under Win7 x64

Dear Open Source .NET Shell ( SharpBITS ) Implementation Windows BITS does not identify the base version of BITS under Win7 x64.

Here is the source code that fails. NativeMethods are native Win32 calls wrapped in .NET methods and decorated using the DllImport attribute.

private static BitsVersion GetBitsVersion()
    {
        try
        {
            string fileName = Path.Combine(
                     System.Environment.SystemDirectory, "qmgr.dll");
            int handle = 0;
            int size = NativeMethods.GetFileVersionInfoSize(fileName, 
                                                            out handle);
            if (size == 0) return BitsVersion.Bits0_0;
            byte[] buffer = new byte[size];
            if (!NativeMethods.GetFileVersionInfo(fileName, 
                                                  handle, 
                                                  size, 
                                                  buffer))
            {
                return BitsVersion.Bits0_0;
            }
            IntPtr subBlock = IntPtr.Zero;
            uint len = 0;
            if (!NativeMethods.VerQueryValue(buffer,
                              @"\VarFileInfo\Translation", 
                              out subBlock, 
                              out len))
            {
                return BitsVersion.Bits0_0;
            }

            int block1 = Marshal.ReadInt16(subBlock);
            int block2 = Marshal.ReadInt16((IntPtr)((int)subBlock + 2 ));
            string spv = string.Format(
                 @"\StringFileInfo\{0:X4}{1:X4}\ProductVersion", 
                 block1, 
                 block2);

            string versionInfo;
            if (!NativeMethods.VerQueryValue(buffer, 
                                             spv, 
                                             out versionInfo, 
                                             out len))
            {
                return BitsVersion.Bits0_0;
            }
...

The implementation follows the letter buffer => byte [1900] - complete with binary data block1 => 1033 block2 => 1200

I looked at the target file C: \ Windows \ System32 \ qmgr.dll (BITS implementation) through Windows. It says that the product version is 7.5.7600.16385. Instead of failing, this value should be returned in the verionInfo string. Any tips?

0
3

Nobugz ( thanx !), .NET: x64.NET. ​​ .NET4.0. , Microsoft.

- IntPtr . , ( Nobugz):

int block1 = Marshal.ReadInt16(subBlock);
int block2 = Marshal.ReadInt16(subBlock, 2);
string spv = string.Format(@"\StringFileInfo\{0:X4}{1:X4}\ProductVersion", 
                             block1, block2);

IntPtr versionInfoPtr;
if (!NativeMethods.VerQueryValue(buffer, spv, out versionInfoPtr, out len))
{
     return BitsVersion.Bits0_0;
}
string versionInfo = Marshal.PtrToStringAuto(versionInfoPtr);
+1

, - , , FileVersionInfo, P/Invoke API-? ...

+1

SharpBITS . , Big Bug, 64- . , , P/Invoke. :

int block2 = Marshal.ReadInt16((IntPtr)((int)subBlock + 2 ));

IntPtr int x64. :

int block2 = Marshal.ReadInt16((IntPtr)((long)subBlock + 2 ));

:

int block2 = Marshal.ReadInt16(subBlock, 2); 

I highly recommend that you make the application run in 32-bit mode if you use this library to avoid these problems. Project + Properties, Build tab, Platform Target = x86. You can notify the author here.

+1
source

Source: https://habr.com/ru/post/1736462/


All Articles