Fix stub DllGetVersion implementation to read Dll version and put it in correct structure. Implement GetDllVersion by using DllGetVersion function and return version
-- v18: cabinet: correctly implement DllGetVersion
From: Tobias G��rgens tobi.goergens@gmail.com
--- dlls/cabinet/cabinet.h | 9 +++++ dlls/cabinet/cabinet.spec | 2 +- dlls/cabinet/cabinet_main.c | 2 +- dlls/cabinet/tests/Makefile.in | 3 +- dlls/cabinet/tests/version.c | 67 ++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 dlls/cabinet/tests/version.c
diff --git a/dlls/cabinet/cabinet.h b/dlls/cabinet/cabinet.h index 6193622cb11..707744e16cc 100644 --- a/dlls/cabinet/cabinet.h +++ b/dlls/cabinet/cabinet.h @@ -160,6 +160,15 @@ struct QTMstate { struct QTMmodelsym m80sym[0x40 + 1], mC0sym[0x40 + 1]; };
+/*version information used in cabinet.dll*/ +typedef struct _CABINETDLLVERSIONINFO { + DWORD cbStruct; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; +} CABINETDLLVERSIONINFO, *PCABINETDLLVERSIONINFO; + /* LZX stuff */
/* some constants defined by the LZX specification */ diff --git a/dlls/cabinet/cabinet.spec b/dlls/cabinet/cabinet.spec index 96127cfc429..7cf709de60e 100644 --- a/dlls/cabinet/cabinet.spec +++ b/dlls/cabinet/cabinet.spec @@ -1,5 +1,5 @@ 1 stub GetDllVersion -2 stdcall -private DllGetVersion (ptr) +2 stdcall -private DllGetVersion (ptr) cabinet_dll_get_version 3 stdcall Extract(ptr str) 4 stub DeleteExtractedFiles 10 cdecl FCICreate(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index f95eca93c52..4187cf0140f 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -52,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(cabinet); * NOTES * Supposedly returns version from IE6SP1RP1 */ -HRESULT WINAPI DllGetVersion (DLLVERSIONINFO *pdvi) +HRESULT WINAPI cabinet_dll_get_version (DLLVERSIONINFO *pdvi) { WARN("hmmm... not right version number "5.1.1106.1"?\n");
diff --git a/dlls/cabinet/tests/Makefile.in b/dlls/cabinet/tests/Makefile.in index f301617473d..fc9fff75c7b 100644 --- a/dlls/cabinet/tests/Makefile.in +++ b/dlls/cabinet/tests/Makefile.in @@ -3,4 +3,5 @@ IMPORTS = cabinet
C_SRCS = \ extract.c \ - fdi.c + fdi.c \ + version.c diff --git a/dlls/cabinet/tests/version.c b/dlls/cabinet/tests/version.c new file mode 100644 index 00000000000..733ad451d31 --- /dev/null +++ b/dlls/cabinet/tests/version.c @@ -0,0 +1,67 @@ +#include <stdio.h> +#include <string.h> +#include <windows.h> +#include <winbase.h> +#include <wine/test.h> + + +#include "windef.h" +#define NO_SHLWAPI_REG +#include "shlwapi.h" +#undef NO_SHLWAPI_REG +#include "winbase.h" +#include "../cabinet.h" + + +typedef VOID (__stdcall *f_dllget)(PCABINETDLLVERSIONINFO); + + +static void test_dllget(HMODULE libHandle) +{ + PCABINETDLLVERSIONINFO verInfo; + char *version; + int sizeVerInfo; + DWORD FileVersionMS; + DWORD FileVersionLS; + int majorV; + int minorV; + int buildV; + int revisV; + + f_dllget DllGetVersion = (f_dllget)GetProcAddress(libHandle, "DllGetVersion"); + ok(DllGetVersion != NULL, "Function DllGetVersion in DLL not found: Error = %ld.\n", GetLastError()); + + + verInfo = malloc(sizeof(CABINETDLLVERSIONINFO)); + ok(verInfo != NULL, "Couldn't allocate memory to run tests properly!\n"); + if (DllGetVersion) + DllGetVersion(verInfo); + + FileVersionMS = verInfo->dwFileVersionMS; + FileVersionLS = verInfo->dwFileVersionLS; + + /*length of 4 DWORDs + buffer*/ + sizeVerInfo = 32; + + version = malloc(sizeVerInfo); + ok(version != NULL, "Couldn't allocate memory to run tests properly!\n"); + + majorV = (int)( FileVersionMS >> 16 ) & 0xffff; + minorV = (int)( FileVersionMS >> 0 ) & 0xffff; + buildV = (int)( FileVersionLS >> 16 ) & 0xffff; + revisV = (int)( FileVersionLS >> 0 ) & 0xffff; + + snprintf(version, sizeVerInfo, "%d.%d.%d.%d\n",majorV,minorV,buildV,revisV);; + todo_wine { + /* FIXME - Currently DllGetVersion isn't implemented correctly */ + ok(strcmp(version,"0.0.0.0\n") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); + } +} + +START_TEST(version) +{ + HMODULE libHandle; + libHandle = LoadLibraryA("Cabinet.dll"); + ok(libHandle != NULL, "Cabinet.dll not found: Error = %ld.\n", GetLastError()); + test_dllget(libHandle); +}
From: "tobi.goergens" tobi.goergens@gmail.com
--- dlls/cabinet/Makefile.in | 2 +- dlls/cabinet/cabinet.rc | 22 +++++++++ dlls/cabinet/cabinet_main.c | 93 +++++++++++++++++++++++++++++++----- dlls/cabinet/tests/version.c | 5 +- 4 files changed, 104 insertions(+), 18 deletions(-)
diff --git a/dlls/cabinet/Makefile.in b/dlls/cabinet/Makefile.in index 4ee406480ac..22955d4027a 100644 --- a/dlls/cabinet/Makefile.in +++ b/dlls/cabinet/Makefile.in @@ -1,6 +1,6 @@ MODULE = cabinet.dll IMPORTLIB = cabinet -IMPORTS = $(ZLIB_PE_LIBS) +IMPORTS = $(ZLIB_PE_LIBS) kernelbase EXTRAINCL = $(ZLIB_PE_CFLAGS)
C_SRCS = \ diff --git a/dlls/cabinet/cabinet.rc b/dlls/cabinet/cabinet.rc index 8a022909d5c..bf045d53c28 100644 --- a/dlls/cabinet/cabinet.rc +++ b/dlls/cabinet/cabinet.rc @@ -26,3 +26,25 @@ #define WINE_PRODUCTVERSION_STR "5.0"
#include "wine/wine_common_ver.rc" + +100 VERSIONINFO +FILEVERSION WINE_FILEVERSION +PRODUCTVERSION WINE_PRODUCTVERSION +FILEOS VOS_NT +FILETYPE VFT_DLL +{ + BLOCK "StringFileInfo" + { + BLOCK "1200" + { + VALUE "FileDescription", WINE_FILEDESCRIPTION_STR + VALUE "FileVersion", WINE_FILEVERSION + VALUE "FileVersionStr", WINE_FILEVERSION_STR + VALUE "InternalName", WINE_FILENAME + VALUE "LegalCopyright", WINE_LEGALCOPYRIGHT + VALUE "OriginalFilename", WINE_FILENAME_STR + VALUE "ProductName", WINE_PRODUCTNAME_STR + VALUE "ProductVersion", WINE_PRODUCTVERSION_STR + } + } +} diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index 4187cf0140f..5823fa7cc6a 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -40,30 +40,97 @@ WINE_DEFAULT_DEBUG_CHANNEL(cabinet); /*********************************************************************** * DllGetVersion (CABINET.2) * - * Retrieves version information of the 'CABINET.DLL' + * Retrieves version information of the 'CABINET.DLL' using the + * CABINETDLLVERSIONINFO structure * * PARAMS - * pdvi [O] pointer to version information structure. + * cabVerInfo [O] pointer to CABINETDLLVERSIONINFO structure. * * RETURNS - * Success: S_OK - * Failure: E_INVALIDARG + * This function has no return value * * NOTES - * Supposedly returns version from IE6SP1RP1 + * Success: cabVerInfo points to mutet CABINETDLLVERSIONINFO structure + * Failure: cabVerInfo points to unmutet CABINETDLLVERSIONINFO structure + * Use GetLastError() to find out more about why the function failed + * */ -HRESULT WINAPI cabinet_dll_get_version (DLLVERSIONINFO *pdvi) + +VOID WINAPI cabinet_dll_get_version (PCABINETDLLVERSIONINFO cabVerInfo) { - WARN("hmmm... not right version number "5.1.1106.1"?\n");
- if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) return E_INVALIDARG; + LPCSTR filename; + LPCSTR subBlock; + DWORD lenVersionInfo; + VOID *data; + VOID *buffer; + UINT lenRoot; + DWORD *handleVerInfo; + VS_FIXEDFILEINFO *versionInfo; + + filename = "Cabinet.dll"; + subBlock = "\"; + lenRoot = 0; + + if (cabVerInfo == NULL){ + SetLastError(ERROR_INVALID_PARAMETER); + TRACE("Bad Parameter: Error = %ld.\n", GetLastError()); + return; + } + + handleVerInfo = malloc(sizeof(DWORD)); + if (handleVerInfo == NULL){ + SetLastError(ERROR_OUTOFMEMORY); + TRACE("Cannot create handleVerInfo: Out of memory: Error = %ld.\n", GetLastError()); + return; + } + + lenVersionInfo = GetFileVersionInfoSizeA(filename, handleVerInfo); + if (lenVersionInfo == 0){ + TRACE("Cannot set lenVersionInfo: Couldn't parse File Version Info Size: Error = %ld.\n", GetLastError()); + return; + } + + data=HeapAlloc(GetProcessHeap(), 0, lenVersionInfo); + if (data == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + TRACE("Cannot create data: Out of memory: Error = %ld.\n", GetLastError()); + return; + }
- pdvi->dwMajorVersion = 5; - pdvi->dwMinorVersion = 1; - pdvi->dwBuildNumber = 1106; - pdvi->dwPlatformID = 1;
- return S_OK; + if (GetFileVersionInfoA(filename, 0, lenVersionInfo, data) == 0){ + TRACE("Cannot get FileVersionInfo: Couldn't parse File Version Info Ressource: Error = %ld.\n", GetLastError()); + return; + } + + if (VerQueryValueA(data, subBlock, &buffer, &lenRoot) == 0){ + TRACE("Cannot query version info: Couldn't parse File Version Info Value: Error = %ld.\n", GetLastError()); + return; + } + else + { + if (lenRoot != 0) + { + versionInfo = (VS_FIXEDFILEINFO *)buffer; + if (versionInfo->dwSignature == 0xfeef04bd) + { + cabVerInfo->cbStruct = sizeof(CABINETDLLVERSIONINFO); + cabVerInfo->dwFileVersionMS = versionInfo->dwFileVersionMS; + cabVerInfo->dwFileVersionLS = versionInfo->dwFileVersionLS; + } + else + { + TRACE("Cannot verify struct: Version information has wrong signature: Error = %ld.\n", GetLastError()); + return; + } + } + else + { + TRACE("Cannot access struct: The length of the buffer holding version information is 0: Error = %ld.\n", GetLastError()); + return; + } + } }
/* FDI callback functions */ diff --git a/dlls/cabinet/tests/version.c b/dlls/cabinet/tests/version.c index 733ad451d31..8915bb6b775 100644 --- a/dlls/cabinet/tests/version.c +++ b/dlls/cabinet/tests/version.c @@ -52,10 +52,7 @@ static void test_dllget(HMODULE libHandle) revisV = (int)( FileVersionLS >> 0 ) & 0xffff;
snprintf(version, sizeVerInfo, "%d.%d.%d.%d\n",majorV,minorV,buildV,revisV);; - todo_wine { - /* FIXME - Currently DllGetVersion isn't implemented correctly */ - ok(strcmp(version,"0.0.0.0\n") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); - } + ok(strcmp(version,"0.0.0.0\n") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); }
START_TEST(version)
On Tue Aug 2 13:17:59 2022 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=120358 Your paranoid android. === debian11 (32 bit report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit Arabic:Morocco report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit German report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit French report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit Hebrew:Israel report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit Hindi:India report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit Japanese:Japan report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit Chinese:China report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (32 bit WoW report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 32-bit code (0x7b0122f6). === debian11 (64 bit WoW report) === cabinet: version.c:67: Test succeeded inside todo block: Function GetDllVersion in DLL not found: Error = 203. Unhandled exception: unimplemented function cabinet.dll.GetDllVersion called in 64-bit code (0x0000007b0138ae).
resolved, please hide this :(
On Fri Aug 5 17:36:23 2022 +0000, Tobias G��rgens wrote:
OK, I have two questions about that, probably both dumb, but well, I want to get smarter: a) I used IMPORTS instead of IMPORTLIB; what's the difference? It still seems to work b) what is the "-import" flag then used for in spec files? e.g. the "version" module uses it, I just copied it thinking it was the right way to do it :D Anyway, it also compiles for me without, so I'll remove it
Right, I misspoke. Using IMPORTS is the right thing to do, IMPORTLIB is a name of import library. The "-import" flag means a different thing. For example in kernel32.spec there is `@ stdcall -import ActivateActCtx(ptr ptr)`, this line means that kernel32 will have an export called "ActivateActCtx", but its actual implementation is elsewhere (in this case it's in kernelbase). `-import` will create an actual stub function in kernel32, that would immediately call real one from kernelbase. This is different from forwarding that's also used in some modules. Forwarding syntax would be `@ stdcall ActivateActCtx(ptr ptr) kernelbase.ActivateActCtx`, and won't create an actual function in kernel32, so GetProcAddress(kernel32, ...) == GetProcAddress(kernelbase, ...). With `-import` GetProcAddress() will return different addresses.