Fix stub DllGetVersion implementation to read Dll version and put it in correct structure. Implement GetDllVersion by using DllGetVersion function and return version
-- v17: 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.spec | 3 ++ dlls/cabinet/cabinet_main.c | 93 +++++++++++++++++++++++++++++++----- dlls/cabinet/tests/version.c | 5 +- 5 files changed, 107 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.spec b/dlls/cabinet/cabinet.spec index 7cf709de60e..144da9b9508 100644 --- a/dlls/cabinet/cabinet.spec +++ b/dlls/cabinet/cabinet.spec @@ -1,3 +1,6 @@ +@ stdcall -import GetFileVersionInfoA(str long long ptr) +@ stdcall -import GetFileVersionInfoSizeA(str ptr) +@ stdcall -import VerQueryValueA(ptr str ptr ptr) 1 stub GetDllVersion 2 stdcall -private DllGetVersion (ptr) cabinet_dll_get_version 3 stdcall Extract(ptr 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 Fri Aug 5 15:50:23 2022 +0000, Tobias G��rgens wrote:
changed this line in [version 14 of the diff](/wine/wine/-/merge_requests/564/diffs?diff_id=6979&start_sha=f62f81b3a9c348873efdf00ae5a60b9907a9029f#1bcf39d83b279f3adb52be80ef84e6bb4fa37dac_1075_1068)
now in cabinet.h
Nikolay Sivov (@nsivov) commented about dlls/cabinet/cabinet.spec:
+@ stdcall -import GetFileVersionInfoA(str long long ptr) +@ stdcall -import GetFileVersionInfoSizeA(str ptr) +@ stdcall -import VerQueryValueA(ptr str ptr ptr) 1 stub GetDllVersion 2 stdcall -private DllGetVersion (ptr) cabinet_dll_get_version 3 stdcall Extract(ptr str)
This file defines exported functions of cabinet.dll. You shouldn't include something this dll does not export.
On Fri Aug 5 17:00:27 2022 +0000, Nikolay Sivov wrote:
This file defines exported functions of cabinet.dll. You shouldn't include something this dll does not export.
OK, so to access functions from kernelbase I don't need to import them? I saw this in other spec files and thought it was meant for that
On Fri Aug 5 17:15:14 2022 +0000, Tobias G��rgens wrote:
OK, so to access functions from kernelbase I don't need to import them? I saw this in other spec files and thought it was meant for that
No, spec file is only for exports. To link another library you're using IMPORTLIB.
On Fri Aug 5 17:16:34 2022 +0000, Nikolay Sivov wrote:
No, spec file is only for exports. To link another library you're using IMPORTLIB.
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