Fix stub DllGetVersion implementation to read Dll version and put it in correct structure. Implement GetDllVersion by using DllGetVersion function and return version
-- v19: cabinet: implement GetDllVersion function
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)
From: "tobi.goergens" tobi.goergens@gmail.com
--- dlls/cabinet/cabinet.spec | 2 +- dlls/cabinet/cabinet_main.c | 63 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/dlls/cabinet/cabinet.spec b/dlls/cabinet/cabinet.spec index 7cf709de60e..3a98245acc1 100644 --- a/dlls/cabinet/cabinet.spec +++ b/dlls/cabinet/cabinet.spec @@ -1,4 +1,4 @@ -1 stub GetDllVersion +1 stdcall GetDllVersion() 2 stdcall -private DllGetVersion (ptr) cabinet_dll_get_version 3 stdcall Extract(ptr str) 4 stub DeleteExtractedFiles diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index 5823fa7cc6a..2faa2af8be2 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -133,6 +133,69 @@ VOID WINAPI cabinet_dll_get_version (PCABINETDLLVERSIONINFO cabVerInfo) } }
+/*********************************************************************** + * GetDllVersion (CABINET.2) + * + * Returns the version of the Cabinet.dll + * + * PARAMS + * This function has to parameters + * + * RETURNS + * Success: cabDllVer: string of Cabinet.dll version + * Failure: empty string. + * Use GetLastError() to find out more about why the function failed + * + */ + +LPCSTR WINAPI GetDllVersion(void) +{ + PCABINETDLLVERSIONINFO cabVerInfo; + LPSTR cabDllVer; + int sizeVerInfo; + DWORD FileVersionMS; + DWORD FileVersionLS; + int majorV; + int minorV; + int buildV; + int revisV; + + cabVerInfo = malloc(sizeof(CABINETDLLVERSIONINFO)); + if(cabVerInfo == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + TRACE("Cannot create cabVerInfo: Out of memory: Error = %ld.\n", GetLastError()); + return ""; + } + + cabinet_dll_get_version(cabVerInfo); + if (cabVerInfo->cbStruct==0) { + TRACE("Cannot access struct: The length of the version information structure is 0: Error = %ld.\n", GetLastError()); + return ""; + } + + FileVersionMS = cabVerInfo->dwFileVersionMS; + FileVersionLS = cabVerInfo->dwFileVersionLS; + + /*length of 4 DWORDs + buffer*/ + sizeVerInfo = 32; + + cabDllVer = malloc(sizeVerInfo); + if (cabDllVer == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + TRACE("Cannot create cabDllVer: Out of memory: Error = %ld.\n", GetLastError()); + return ""; + } + + majorV = (int)( FileVersionMS >> 16 ) & 0xffff; + minorV = (int)( FileVersionMS >> 0 ) & 0xffff; + buildV = (int)( FileVersionLS >> 16 ) & 0xffff; + revisV = (int)( FileVersionLS >> 0 ) & 0xffff; + + snprintf(cabDllVer, sizeVerInfo, "%d.%d.%d.%d\n",majorV,minorV,buildV,revisV); + + return cabDllVer; +} + /* FDI callback functions */
static void * CDECL mem_alloc(ULONG cb)
On Fri Aug 5 17:49:42 2022 +0000, Nikolay Sivov wrote:
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.
Ah, thank you very much for clearing that up :)