📄 info.c
字号:
if(len)
memcpy(data, buf, len);
else
len = 0xFFFFFFFF;
}
END:
FreeResource16(hMem);
FreeLibrary16(hModule);
return len;
}
#endif /* ! __REACTOS__ */
/***********************************************************************
* GetFileVersionInfoSizeW [VERSION.@]
*/
DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
{
DWORD len;
TRACE("(%s,%p)\n", debugstr_w(filename), handle );
if (handle) *handle = 0;
if (!filename)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!*filename)
{
SetLastError(ERROR_BAD_PATHNAME);
return 0;
}
len = VERSION_GetFileVersionInfo_PE(filename, 0, NULL);
/* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
if(len == 0xFFFFFFFF)
{
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return 0;
}
if (!len)
{
#ifdef __REACTOS__
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
#else /* __REACTOS__ */
LPSTR filenameA;
len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
filenameA = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
len = VERSION_GetFileVersionInfo_16(filenameA, 0, NULL);
HeapFree( GetProcessHeap(), 0, filenameA );
/* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
if (!len)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
}
if (len == 0xFFFFFFFF)
{
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return 0;
}
/* We have a 16bit resource.
*
* XP/W2K/W2K3 uses a buffer which is more than the actual needed space:
*
* (info->wLength - sizeof(VS_FIXEDFILEINFO)) * 4
*
* This extra buffer is used for ANSI to Unicode conversions in W-Calls.
* info->wLength should be the same as len. Currently it isn't but that
* doesn't seem to be a problem (len is bigger then info->wLength).
*/
len = (len - sizeof(VS_FIXEDFILEINFO)) * 4;
#endif /* ! __REACTOS__ */
}
else
{
/* We have a 32bit resource.
*
* XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
* This extra buffer is used for Unicode to ANSI conversions in A-Calls
*/
len = (len * 2) + 4;
}
SetLastError(0);
return len;
}
/***********************************************************************
* GetFileVersionInfoSizeA [VERSION.@]
*/
DWORD WINAPI GetFileVersionInfoSizeA( LPCSTR filename, LPDWORD handle )
{
UNICODE_STRING filenameW;
DWORD retval;
TRACE("(%s,%p)\n", debugstr_a(filename), handle );
if(filename)
RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else
filenameW.Buffer = NULL;
retval = GetFileVersionInfoSizeW(filenameW.Buffer, handle);
RtlFreeUnicodeString(&filenameW);
return retval;
}
/***********************************************************************
* GetFileVersionInfoW [VERSION.@]
*/
BOOL WINAPI GetFileVersionInfoW( LPCWSTR filename, DWORD handle,
DWORD datasize, LPVOID data )
{
DWORD len;
VS_VERSION_INFO_STRUCT32* vvis = (VS_VERSION_INFO_STRUCT32*)data;
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_w(filename), handle, datasize, data );
if (!data)
{
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
len = VERSION_GetFileVersionInfo_PE(filename, datasize, data);
/* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
if (len == 0xFFFFFFFF)
{
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return FALSE;
}
if (!len)
{
#ifdef __REACTOS__
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return FALSE;
#else /* __REACTOS__ */
LPSTR filenameA;
len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
filenameA = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
len = VERSION_GetFileVersionInfo_16(filenameA, datasize, data);
HeapFree( GetProcessHeap(), 0, filenameA );
/* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
if (!len || len == 0xFFFFFFFF)
{
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return FALSE;
}
/* We have a 16bit resource. */
#endif /* ! __REACTOS__ */
}
else
{
static const char signature[] = "FE2X";
DWORD bufsize = vvis->wLength + strlen(signature);
DWORD convbuf;
/* We have a 32bit resource.
*
* XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
* This extra buffer is used for Unicode to ANSI conversions in A-Calls
*/
/* information is truncated to datasize bytes */
if (datasize >= bufsize)
{
convbuf = datasize - vvis->wLength;
memcpy( ((char*)(data))+vvis->wLength, signature, convbuf > 4 ? 4 : convbuf );
}
}
SetLastError(0);
return TRUE;
}
/***********************************************************************
* GetFileVersionInfoA [VERSION.@]
*/
BOOL WINAPI GetFileVersionInfoA( LPCSTR filename, DWORD handle,
DWORD datasize, LPVOID data )
{
UNICODE_STRING filenameW;
BOOL retval;
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_a(filename), handle, datasize, data );
if(filename)
RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else
filenameW.Buffer = NULL;
retval = GetFileVersionInfoW(filenameW.Buffer, handle, datasize, data);
RtlFreeUnicodeString(&filenameW);
return retval;
}
/***********************************************************************
* VersionInfo16_FindChild [internal]
*/
static VS_VERSION_INFO_STRUCT16 *VersionInfo16_FindChild( VS_VERSION_INFO_STRUCT16 *info,
LPCSTR szKey, UINT cbKey )
{
VS_VERSION_INFO_STRUCT16 *child = VersionInfo16_Children( info );
while ((char *)child < (char *)info + info->wLength )
{
if ( !strncasecmp( child->szKey, szKey, cbKey ) )
return child;
if (!(child->wLength)) return NULL;
child = VersionInfo16_Next( child );
}
return NULL;
}
/***********************************************************************
* VersionInfo32_FindChild [internal]
*/
static VS_VERSION_INFO_STRUCT32 *VersionInfo32_FindChild( VS_VERSION_INFO_STRUCT32 *info,
LPCWSTR szKey, UINT cbKey )
{
VS_VERSION_INFO_STRUCT32 *child = VersionInfo32_Children( info );
while ((char *)child < (char *)info + info->wLength )
{
if ( !strncmpiW( child->szKey, szKey, cbKey ) )
return child;
child = VersionInfo32_Next( child );
}
return NULL;
}
/***********************************************************************
* VersionInfo16_QueryValue [internal]
*
* Gets a value from a 16-bit NE resource
*/
static BOOL WINAPI VersionInfo16_QueryValue( VS_VERSION_INFO_STRUCT16 *info, LPCSTR lpSubBlock,
LPVOID *lplpBuffer, UINT *puLen )
{
while ( *lpSubBlock )
{
/* Find next path component */
LPCSTR lpNextSlash;
for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )
if ( *lpNextSlash == '\\' )
break;
/* Skip empty components */
if ( lpNextSlash == lpSubBlock )
{
lpSubBlock++;
continue;
}
/* We have a non-empty component: search info for key */
info = VersionInfo16_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );
if ( !info ) return FALSE;
/* Skip path component */
lpSubBlock = lpNextSlash;
}
/* Return value */
*lplpBuffer = VersionInfo16_Value( info );
if (puLen)
*puLen = info->wValueLength;
return TRUE;
}
/***********************************************************************
* VersionInfo32_QueryValue [internal]
*
* Gets a value from a 32-bit PE resource
*/
static BOOL WINAPI VersionInfo32_QueryValue( VS_VERSION_INFO_STRUCT32 *info, LPCWSTR lpSubBlock,
LPVOID *lplpBuffer, UINT *puLen )
{
TRACE("lpSubBlock : (%s)\n", debugstr_w(lpSubBlock));
while ( *lpSubBlock )
{
/* Find next path component */
LPCWSTR lpNextSlash;
for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )
if ( *lpNextSlash == '\\' )
break;
/* Skip empty components */
if ( lpNextSlash == lpSubBlock )
{
lpSubBlock++;
continue;
}
/* We have a non-empty component: search info for key */
info = VersionInfo32_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );
if ( !info ) return FALSE;
/* Skip path component */
lpSubBlock = lpNextSlash;
}
/* Return value */
*lplpBuffer = VersionInfo32_Value( info );
if (puLen)
*puLen = info->wValueLength;
return TRUE;
}
/***********************************************************************
* VerQueryValueA [VERSION.@]
*/
BOOL WINAPI VerQueryValueA( LPVOID pBlock, LPSTR lpSubBlock,
LPVOID *lplpBuffer, UINT *puLen )
{
static const char rootA[] = "\\";
static const char varfileinfoA[] = "\\VarFileInfo\\Translation";
VS_VERSION_INFO_STRUCT16 *info = (VS_VERSION_INFO_STRUCT16 *)pBlock;
TRACE("(%p,%s,%p,%p)\n",
pBlock, debugstr_a(lpSubBlock), lplpBuffer, puLen );
if ( !VersionInfoIs16( info ) )
{
BOOL ret;
INT len;
LPWSTR lpSubBlockW;
len = MultiByteToWideChar(CP_ACP, 0, lpSubBlock, -1, NULL, 0);
lpSubBlockW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!lpSubBlockW)
return FALSE;
MultiByteToWideChar(CP_ACP, 0, lpSubBlock, -1, lpSubBlockW, len);
ret = VersionInfo32_QueryValue(pBlock, lpSubBlockW, lplpBuffer, puLen);
HeapFree(GetProcessHeap(), 0, lpSubBlockW);
if (ret && strcasecmp( lpSubBlock, rootA ) && strcasecmp( lpSubBlock, varfileinfoA ))
{
LPSTR lpBufferA = (LPSTR)pBlock + info->wLength + 4;
DWORD pos = (LPSTR)*lplpBuffer - (LPSTR)pBlock;
len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)*lplpBuffer, -1,
lpBufferA + pos, info->wLength - pos, NULL, NULL);
*lplpBuffer = lpBufferA + pos;
*puLen = len;
}
return ret;
}
return VersionInfo16_QueryValue(info, lpSubBlock, lplpBuffer, puLen);
}
/***********************************************************************
* VerQueryValueW [VERSION.@]
*/
BOOL WINAPI VerQueryValueW( LPVOID pBlock, LPWSTR lpSubBlock,
LPVOID *lplpBuffer, UINT *puLen )
{
static const WCHAR rootW[] = { '\\', 0 };
static const WCHAR varfileinfoW[] = { '\\','V','a','r','F','i','l','e','I','n','f','o',
'\\','T','r','a','n','s','l','a','t','i','o','n', 0 };
VS_VERSION_INFO_STRUCT32 *info = (VS_VERSION_INFO_STRUCT32 *)pBlock;
TRACE("(%p,%s,%p,%p)\n",
pBlock, debugstr_w(lpSubBlock), lplpBuffer, puLen );
if ( VersionInfoIs16( info ) )
{
BOOL ret;
int len;
LPSTR lpSubBlockA;
len = WideCharToMultiByte(CP_ACP, 0, lpSubBlock, -1, NULL, 0, NULL, NULL);
lpSubBlockA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
if (!lpSubBlockA)
return FALSE;
WideCharToMultiByte(CP_ACP, 0, lpSubBlock, -1, lpSubBlockA, len, NULL, NULL);
ret = VersionInfo16_QueryValue(pBlock, lpSubBlockA, lplpBuffer, puLen);
HeapFree(GetProcessHeap(), 0, lpSubBlockA);
if (ret && strcmpiW( lpSubBlock, rootW ) && strcmpiW( lpSubBlock, varfileinfoW ))
{
LPWSTR lpBufferW = (LPWSTR)((LPSTR)pBlock + info->wLength);
DWORD pos = (LPSTR)*lplpBuffer - (LPSTR)pBlock;
DWORD max = (info->wLength - sizeof(VS_FIXEDFILEINFO)) * 4 - info->wLength;
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)*lplpBuffer, -1,
lpBufferW + pos, max/sizeof(WCHAR) - pos );
*lplpBuffer = lpBufferW + pos;
*puLen = len;
}
return ret;
}
return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -