Fix stub DllGetVersion implementation to read Dll version and put it in correct structure. Implement GetDllVersion by using DllGetVersion function and return version
-- v6: cabinet: Implement GetDllVersion
From: Tobias G��rgens tobi.goergens@gmail.com
--- dlls/cabinet/tests/Makefile.in | 3 +- dlls/cabinet/tests/version.c | 79 ++++++++++++++++++++++++++++++++++ include/shlwapi.h | 9 ++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 dlls/cabinet/tests/version.c
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..60f5dc74efe --- /dev/null +++ b/dlls/cabinet/tests/version.c @@ -0,0 +1,79 @@ +#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" + + +typedef VOID (__stdcall *f_dllget)(PCABINETDLLVERSIONINFO); +typedef LPCSTR (__stdcall *f_getdll)(void); + + +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"); + todo_wine { + /* FIXME - Currently DllGetVersion isn't implemented correctly */ + ok(libHandle != 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"); + DllGetVersion(verInfo); + + FileVersionMS = verInfo->dwFileVersionMS; + FileVersionLS = verInfo->dwFileVersionLS; + + /*length of 4 DWORDs + buffer*/ + sizeVerInfo = 32; + + version = malloc(sizeVerInfo); + + + 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);; + + ok(strcmp(version,"") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); + } +} + + +static void test_getdll(HMODULE libHandle) +{ + f_getdll GetDllVersion = (f_getdll)GetProcAddress(libHandle, "GetDllVersion"); + todo_wine { + /* FIXME - Currently GetDllVersion isn't implemented */ + ok(libHandle != NULL, "Function GetDllVersion in DLL not found: Error = %ld.\n", GetLastError()); + ok(strcmp(GetDllVersion(),"") != 0, "GetDllVersion doesn't return 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); + test_getdll(libHandle); +} diff --git a/include/shlwapi.h b/include/shlwapi.h index 6149c7081a3..028a6e7efba 100644 --- a/include/shlwapi.h +++ b/include/shlwapi.h @@ -1065,6 +1065,15 @@ typedef struct _DllVersionInfo { DWORD dwPlatformID; } DLLVERSIONINFO;
+/*version information used in cabinet.dll*/ +typedef struct _CABINETDLLVERSIONINFO { + DWORD cbStruct; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; +} CABINETDLLVERSIONINFO, *PCABINETDLLVERSIONINFO; + #define DLLVER_PLATFORM_WINDOWS 0x01 /* Win9x */ #define DLLVER_PLATFORM_NT 0x02 /* WinNT */
From: Tobias G��rgens tobi.goergens@gmail.com
--- dlls/cabinet/cabinet.rc | 22 +++++++++ dlls/cabinet/cabinet.spec | 31 ++++++------ dlls/cabinet/cabinet_main.c | 94 ++++++++++++++++++++++++++++++------ dlls/cabinet/tests/version.c | 35 ++++++-------- 4 files changed, 135 insertions(+), 47 deletions(-)
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 96127cfc429..1953582e1de 100644 --- a/dlls/cabinet/cabinet.spec +++ b/dlls/cabinet/cabinet.spec @@ -1,14 +1,17 @@ -1 stub GetDllVersion -2 stdcall -private DllGetVersion (ptr) -3 stdcall Extract(ptr str) -4 stub DeleteExtractedFiles -10 cdecl FCICreate(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) -11 cdecl FCIAddFile(long ptr ptr long ptr ptr ptr long) -12 cdecl FCIFlushFolder(long ptr ptr) -13 cdecl FCIFlushCabinet(long long ptr ptr) -14 cdecl FCIDestroy(long) -20 cdecl FDICreate(ptr ptr ptr ptr ptr ptr ptr long ptr) -21 cdecl FDIIsCabinet(long long ptr) -22 cdecl FDICopy(long ptr ptr long ptr ptr ptr) -23 cdecl FDIDestroy(long) -24 cdecl FDITruncateCabinet(long ptr long) +@ stdcall -import GetFileVersionInfoA(str long long ptr) +@ stdcall -import GetFileVersionInfoSizeA(str ptr) +@ stdcall -import VerQueryValueA(ptr str ptr ptr) +@ stub GetDllVersion() +@ stdcall -private DllGetVersion (ptr) +@ stdcall Extract(ptr str) +@ stub DeleteExtractedFiles +@ cdecl FCICreate(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ cdecl FCIAddFile(long ptr ptr long ptr ptr ptr long) +@ cdecl FCIFlushFolder(long ptr ptr) +@ cdecl FCIFlushCabinet(long long ptr ptr) +@ cdecl FCIDestroy(long) +@ cdecl FDICreate(ptr ptr ptr ptr ptr ptr ptr long ptr) +@ cdecl FDIIsCabinet(long long ptr) +@ cdecl FDICopy(long ptr ptr long ptr ptr ptr) +@ cdecl FDIDestroy(long) +@ cdecl FDITruncateCabinet(long ptr long) diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index f95eca93c52..b35226b2c9d 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -36,34 +36,100 @@
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 DllGetVersion (DLLVERSIONINFO *pdvi) + +VOID WINAPI DllGetVersion(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; + if (GetFileVersionInfoA(filename, 0, lenVersionInfo, data) == 0){ + TRACE("Cannot get FileVersionInfo: Couldn't parse File Version Info Ressource: Error = %ld.\n", GetLastError()); + return; + }
- return S_OK; + 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 60f5dc74efe..3b4040ad383 100644 --- a/dlls/cabinet/tests/version.c +++ b/dlls/cabinet/tests/version.c @@ -29,33 +29,30 @@ static void test_dllget(HMODULE libHandle) int revisV;
f_dllget DllGetVersion = (f_dllget)GetProcAddress(libHandle, "DllGetVersion"); - todo_wine { - /* FIXME - Currently DllGetVersion isn't implemented correctly */ - ok(libHandle != NULL, "Function DllGetVersion in DLL not found: Error = %ld.\n", GetLastError()); - + ok(libHandle != 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"); - DllGetVersion(verInfo);
- FileVersionMS = verInfo->dwFileVersionMS; - FileVersionLS = verInfo->dwFileVersionLS; + verInfo = malloc(sizeof(CABINETDLLVERSIONINFO)); + ok(verInfo != NULL, "Couldn't allocate memory to run tests properly!\n"); + DllGetVersion(verInfo);
- /*length of 4 DWORDs + buffer*/ - sizeVerInfo = 32; + FileVersionMS = verInfo->dwFileVersionMS; + FileVersionLS = verInfo->dwFileVersionLS;
- version = malloc(sizeVerInfo); + /*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; + 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);; + snprintf(version, sizeVerInfo, "%d.%d.%d.%d\n",majorV,minorV,buildV,revisV);;
- ok(strcmp(version,"") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); - } + ok(strcmp(version,"") != 0, "Cabinet struct doesn't contain correct version: Error = %ld.\n", GetLastError()); }
From: Tobias G��rgens tobi.goergens@gmail.com
--- dlls/cabinet/cabinet.spec | 2 +- dlls/cabinet/cabinet_main.c | 63 ++++++++++++++++++++++++++++++++++++ dlls/cabinet/tests/version.c | 7 ++-- 3 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/dlls/cabinet/cabinet.spec b/dlls/cabinet/cabinet.spec index 1953582e1de..4de06cf303b 100644 --- a/dlls/cabinet/cabinet.spec +++ b/dlls/cabinet/cabinet.spec @@ -1,7 +1,7 @@ @ stdcall -import GetFileVersionInfoA(str long long ptr) @ stdcall -import GetFileVersionInfoSizeA(str ptr) @ stdcall -import VerQueryValueA(ptr str ptr ptr) -@ stub GetDllVersion() +@ stdcall GetDllVersion() @ stdcall -private DllGetVersion (ptr) @ stdcall Extract(ptr str) @ stub DeleteExtractedFiles diff --git a/dlls/cabinet/cabinet_main.c b/dlls/cabinet/cabinet_main.c index b35226b2c9d..4de1d817a1a 100644 --- a/dlls/cabinet/cabinet_main.c +++ b/dlls/cabinet/cabinet_main.c @@ -132,6 +132,69 @@ VOID WINAPI DllGetVersion(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 ""; + } + + DllGetVersion(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) diff --git a/dlls/cabinet/tests/version.c b/dlls/cabinet/tests/version.c index 3b4040ad383..5c7f0fbc6ec 100644 --- a/dlls/cabinet/tests/version.c +++ b/dlls/cabinet/tests/version.c @@ -59,11 +59,8 @@ static void test_dllget(HMODULE libHandle) static void test_getdll(HMODULE libHandle) { f_getdll GetDllVersion = (f_getdll)GetProcAddress(libHandle, "GetDllVersion"); - todo_wine { - /* FIXME - Currently GetDllVersion isn't implemented */ - ok(libHandle != NULL, "Function GetDllVersion in DLL not found: Error = %ld.\n", GetLastError()); - ok(strcmp(GetDllVersion(),"") != 0, "GetDllVersion doesn't return correct version: Error = %ld.\n", GetLastError()); - } + ok(libHandle != NULL, "Function GetDllVersion in DLL not found: Error = %ld.\n", GetLastError()); + ok(strcmp(GetDllVersion(),"") != 0, "GetDllVersion doesn't return correct version: Error = %ld.\n", GetLastError()); }
START_TEST(version)
On Mon Aug 1 09:06:07 2022 +0000, Bernhard K��lbl wrote:
Oh, and the prefix for any commit is usually the folder where you do commit to. So instead of `cabinet.dll: Do foobar.` it's just `cabinet: Do foobar.` One exception are headers, where it's `include/foo.h: Do foobar.`
So, I renamed this pr and my commits to follow the (hopefully now) correct name scheme and split the commit into smaller ones, one adding the test itself and expecting it to fail, one with the implementation of DllGetVersion and related changes + not failing test and one with DllGetVersion + not failing test anymore. Is this the recommended way? Can I improve my pr/commits in any other way?
Thank you very much! :)
On Mon Aug 1 18:01:50 2022 +0000, Tobias G��rgens wrote:
So, I renamed this pr and my commits to follow the (hopefully now) correct name scheme and split the commit into smaller ones, one adding the test itself and expecting it to fail, one with the implementation of DllGetVersion and related changes + not failing test and one with DllGetVersion + not failing test anymore. Is this the recommended way? Can I improve my pr/commits in any other way? Thank you very much! :)
Tests cannot fail in their own commit. You need to denote stuff, that's going to be implemented with todo_wine, which expects a failure. Then the commit message for tests needs to be cabinet/tests: