Merge branch 'CabVersionFunctions' into 'master'

cabinet: implement DllGetVersion & GetDllVersion

See merge request wine/wine!564
This commit is contained in:
Tobias Görgens 2024-11-19 17:38:53 +00:00
commit 5dea4af74e
7 changed files with 254 additions and 17 deletions

View file

@ -1,6 +1,6 @@
MODULE = cabinet.dll
IMPORTLIB = cabinet
IMPORTS = $(ZLIB_PE_LIBS)
IMPORTS = $(ZLIB_PE_LIBS) kernelbase
EXTRAINCL = $(ZLIB_PE_CFLAGS)
SOURCES = \

View file

@ -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 */

View file

@ -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
}
}
}

View file

@ -1,5 +1,5 @@
1 stub GetDllVersion
2 stdcall -private DllGetVersion (ptr)
1 stdcall GetDllVersion()
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)

View file

@ -40,30 +40,160 @@ 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 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;
pdvi->dwMajorVersion = 5;
pdvi->dwMinorVersion = 1;
pdvi->dwBuildNumber = 1106;
pdvi->dwPlatformID = 1;
filename = "Cabinet.dll";
subBlock = "\\";
lenRoot = 0;
return S_OK;
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;
}
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;
}
}
}
/***********************************************************************
* 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 */

View file

@ -3,4 +3,5 @@ IMPORTS = cabinet
SOURCES = \
extract.c \
fdi.c
fdi.c \
version.c

View file

@ -0,0 +1,75 @@
#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);
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");
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);;
ok(strcmp(version,"0.0.0.0\n") != 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");
ok(GetDllVersion != NULL, "Function GetDllVersion in DLL not found: Error = %ld.\n", GetLastError());
if (GetDllVersion){
ok(strcmp(GetDllVersion(),"") != 0, "GetDllVersion returns empty version: Error = %ld.\n", GetLastError());
ok(strcmp(GetDllVersion(),"0.0.0.0\n") != 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);
}