Module: wine
Branch: master
Commit: 2a317603318d3560b4fee54b20ca961cdcf6ea38
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2a317603318d3560b4fee54b2…
Author: Juan Lang <juan.lang(a)gmail.com>
Date: Wed Jul 23 17:42:32 2008 -0700
wintrust: Implement CryptSIPGetSignedDataMsg for cabinet files.
Fixes a regression in installing the DirectX 9 runtime.
Based on code from cabinet.dll's fdi.c, thus the healthy dose of
attributions. Unfortunately there's no public API that'll get this
info for me (that I know of.)
---
dlls/wintrust/crypt.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 211 insertions(+), 1 deletions(-)
diff --git a/dlls/wintrust/crypt.c b/dlls/wintrust/crypt.c
index b1b7771..e2129df 100644
--- a/dlls/wintrust/crypt.c
+++ b/dlls/wintrust/crypt.c
@@ -2,6 +2,10 @@
* WinTrust Cryptography functions
*
* Copyright 2006 James Hawkins
+ * Copyright 2000-2002 Stuart Caie
+ * Copyright 2002 Patrik Stridvall
+ * Copyright 2003 Greg Turner
+ * Copyright 2008 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +23,7 @@
*/
#include <stdarg.h>
-
+#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "wintrust.h"
@@ -267,6 +271,207 @@ error:
return ret;
}
+/* structure offsets */
+#define cfhead_Signature (0x00)
+#define cfhead_CabinetSize (0x08)
+#define cfhead_MinorVersion (0x18)
+#define cfhead_MajorVersion (0x19)
+#define cfhead_Flags (0x1E)
+#define cfhead_SIZEOF (0x24)
+#define cfheadext_HeaderReserved (0x00)
+#define cfheadext_SIZEOF (0x04)
+#define cfsigninfo_CertOffset (0x04)
+#define cfsigninfo_CertSize (0x08)
+#define cfsigninfo_SIZEOF (0x0C)
+
+/* flags */
+#define cfheadRESERVE_PRESENT (0x0004)
+
+/* endian-neutral reading of little-endian data */
+#define EndGetI32(a) ((((a)[3])<<24)|(((a)[2])<<16)|(((a)[1])<<8)|((a)[0]))
+#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
+
+/* For documentation purposes only: this is the structure in the reserved
+ * area of a signed cabinet file. The cert offset indicates where in the
+ * cabinet file the signature resides, and the count indicates its size.
+ */
+typedef struct _CAB_SIGNINFO
+{
+ WORD unk0; /* always 0? */
+ WORD unk1; /* always 0x0010? */
+ DWORD dwCertOffset;
+ DWORD cbCertBlock;
+} CAB_SIGNINFO, *PCAB_SIGNINFO;
+
+static BOOL WINTRUST_GetSignedMsgFromCabFile(SIP_SUBJECTINFO *pSubjectInfo,
+ DWORD *pdwEncodingType, DWORD dwIndex, DWORD *pcbSignedDataMsg,
+ BYTE *pbSignedDataMsg)
+{
+ int header_resv;
+ LONG base_offset, cabsize;
+ USHORT flags;
+ BYTE buf[64];
+ DWORD cert_offset, cert_size, dwRead;
+
+ TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
+ pcbSignedDataMsg, pbSignedDataMsg);
+
+ /*
+ * FIXME: I just noticed that I am memorizing the initial file pointer
+ * offset and restoring it before reading in the rest of the header
+ * information in the cabinet. Perhaps that's correct -- that is, perhaps
+ * this API is supposed to support "streaming" cabinets which are embedded
+ * in other files, or cabinets which begin at file offsets other than zero.
+ * Otherwise, I should instead go to the absolute beginning of the file.
+ * (Either way, the semantics of wine's FDICopy require me to leave the
+ * file pointer where it is afterwards -- If Windows does not do so, we
+ * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
+ *
+ * So, the answer lies in Windows; will native cabinet.dll recognize a
+ * cabinet "file" embedded in another file? Note that cabextract.c does
+ * support this, which implies that Microsoft's might. I haven't tried it
+ * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
+ * this one) would not work in this way. To fix it, we could just make the
+ * various references to absolute file positions in the code relative to an
+ * initial "beginning" offset. Because the FDICopy API doesn't take a
+ * file-handle like this one, we would therein need to search through the
+ * file for the beginning of the cabinet (as we also do in cabextract.c).
+ * Note that this limits us to a maximum of one cabinet per. file: the first.
+ *
+ * So, in summary: either the code below is wrong, or the rest of fdi.c is
+ * wrong... I cannot imagine that both are correct ;) One of these flaws
+ * should be fixed after determining the behavior on Windows. We ought
+ * to check both FDIIsCabinet and FDICopy for the right behavior.
+ *
+ * -gmt
+ */
+
+ /* get basic offset & size info */
+ base_offset = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
+
+ if (SetFilePointer(pSubjectInfo->hFile, 0, NULL, SEEK_END) == -1)
+ {
+ TRACE("seek error\n");
+ return FALSE;
+ }
+
+ cabsize = SetFilePointer(pSubjectInfo->hFile, 0L, NULL, SEEK_CUR);
+ if ((cabsize == -1) || (base_offset == -1) ||
+ (SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET) == -1))
+ {
+ TRACE("seek error\n");
+ return FALSE;
+ }
+
+ /* read in the CFHEADER */
+ if (!ReadFile(pSubjectInfo->hFile, buf, cfhead_SIZEOF, &dwRead, NULL) ||
+ dwRead != cfhead_SIZEOF)
+ {
+ TRACE("reading header failed\n");
+ return FALSE;
+ }
+
+ /* check basic MSCF signature */
+ if (EndGetI32(buf+cfhead_Signature) != 0x4643534d)
+ {
+ WARN("cabinet signature not present\n");
+ return FALSE;
+ }
+
+ /* Ignore the number of folders and files and the set and cabinet IDs */
+
+ /* check the header revision */
+ if ((buf[cfhead_MajorVersion] > 1) ||
+ (buf[cfhead_MajorVersion] == 1 && buf[cfhead_MinorVersion] > 3))
+ {
+ WARN("cabinet format version > 1.3\n");
+ return FALSE;
+ }
+
+ /* pull the flags out */
+ flags = EndGetI16(buf+cfhead_Flags);
+
+ if (!(flags & cfheadRESERVE_PRESENT))
+ {
+ TRACE("no header present, not signed\n");
+ return FALSE;
+ }
+
+ if (!ReadFile(pSubjectInfo->hFile, buf, cfheadext_SIZEOF, &dwRead, NULL) ||
+ dwRead != cfheadext_SIZEOF)
+ {
+ ERR("bunk reserve-sizes?\n");
+ return FALSE;
+ }
+
+ header_resv = EndGetI16(buf+cfheadext_HeaderReserved);
+ if (!header_resv)
+ {
+ TRACE("no header_resv, not signed\n");
+ return FALSE;
+ }
+ else if (header_resv < cfsigninfo_SIZEOF)
+ {
+ TRACE("header_resv too small, not signed\n");
+ return FALSE;
+ }
+
+ if (header_resv > 60000)
+ {
+ WARN("WARNING; header reserved space > 60000\n");
+ }
+
+ if (!ReadFile(pSubjectInfo->hFile, buf, cfsigninfo_SIZEOF, &dwRead, NULL) ||
+ dwRead != cfsigninfo_SIZEOF)
+ {
+ ERR("couldn't read reserve\n");
+ return FALSE;
+ }
+
+ cert_offset = EndGetI32(buf+cfsigninfo_CertOffset);
+ TRACE("cert_offset: %d\n", cert_offset);
+ cert_size = EndGetI32(buf+cfsigninfo_CertSize);
+ TRACE("cert_size: %d\n", cert_size);
+
+ /* The redundant checks are to avoid wraparound */
+ if (cert_offset > cabsize || cert_size > cabsize ||
+ cert_offset + cert_size > cabsize)
+ {
+ WARN("offset beyond file, not attempting to read\n");
+ return FALSE;
+ }
+
+ SetFilePointer(pSubjectInfo->hFile, base_offset, NULL, SEEK_SET);
+ if (!pbSignedDataMsg)
+ {
+ *pcbSignedDataMsg = cert_size;
+ return TRUE;
+ }
+ if (*pcbSignedDataMsg < cert_size)
+ {
+ *pcbSignedDataMsg = cert_size;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ if (SetFilePointer(pSubjectInfo->hFile, cert_offset, NULL, SEEK_SET) == -1)
+ {
+ ERR("couldn't seek to cert location\n");
+ return FALSE;
+ }
+ if (!ReadFile(pSubjectInfo->hFile, pbSignedDataMsg, cert_size, &dwRead,
+ NULL) || dwRead != cert_size)
+ {
+ ERR("couldn't read cert\n");
+ return FALSE;
+ }
+ /* The encoding of the files I've seen appears to be in ASN.1
+ * format, and there isn't a field indicating the type, so assume it
+ * always is.
+ */
+ *pdwEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+ return TRUE;
+}
+
/***********************************************************************
* CryptSIPGetSignedDataMsg (WINTRUST.@)
*/
@@ -275,6 +480,8 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
{
static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
+ static const GUID cabGUID = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,
+ 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
BOOL ret;
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
@@ -283,6 +490,9 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
if (!memcmp(pSubjectInfo->pgSubjectType, &unknown, sizeof(unknown)))
ret = WINTRUST_GetSignedMsgFromPEFile(pSubjectInfo, pdwEncodingType,
dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
+ else if (!memcmp(pSubjectInfo->pgSubjectType, &cabGUID, sizeof(cabGUID)))
+ ret = WINTRUST_GetSignedMsgFromCabFile(pSubjectInfo, pdwEncodingType,
+ dwIndex, pcbSignedDataMsg, pbSignedDataMsg);
else
{
FIXME("unimplemented for subject type %s\n",
Module: wine
Branch: master
Commit: 726d9d47afb278e61cd86c4f05a5c4fbf671b3b6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=726d9d47afb278e61cd86c4f0…
Author: Stefan Dösinger <stefan(a)codeweavers.com>
Date: Wed Jul 23 10:39:04 2008 -0500
wined3d: ATI2N support using GL_EXT_texture_compression_rgtc.
---
dlls/wined3d/arb_program_shader.c | 23 +++++++++++++++--------
dlls/wined3d/directx.c | 3 ++-
dlls/wined3d/glsl_shader.c | 33 ++++++++++++++++++++++++---------
dlls/wined3d/utils.c | 7 ++++++-
include/wine/wined3d_gl.h | 9 +++++++++
5 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 9f074ad..22a8b55 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -820,16 +820,23 @@ static void shader_arb_color_correction(SHADER_OPCODE_ARG* arg) {
/* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
* which means the first one is replicated accross .rgb, and the 2nd one is in
* .a. We need the 2nd in .g
+ *
+ * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they
+ * are swapped compared to d3d. So swap red and green.
*/
- if(strlen(writemask) == 5) {
- /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
- shader_addline(arg->buffer, "MOV %s.%c, %s.%c;\n",
- reg, writemask[2], reg, writemask[4]);
- } else if(strlen(writemask) == 2) {
- /* Nothing to do */
+ if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
+ shader_addline(arg->buffer, "SWZ %s, %s, %c, %c, 1, 0;\n",
+ reg, reg, writemask[2], writemask[1]);
} else {
- /* This is bad: We have VL, but we need VU */
- FIXME("2 or 3 components sampled from a converted ATI2N texture\n");
+ if(strlen(writemask) == 5) {
+ shader_addline(arg->buffer, "MOV %s.%c, %s.%c;\n",
+ reg, writemask[2], reg, writemask[4]);
+ } else if(strlen(writemask) == 2) {
+ /* Nothing to do */
+ } else {
+ /* This is bad: We have VL, but we need VU */
+ FIXME("2 or 3 components sampled from a converted ATI2N texture\n");
+ }
}
break;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index f4bc0ee..a95c778 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -105,6 +105,7 @@ static const struct {
{"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP, 0 },
{"GL_EXT_texture3D", EXT_TEXTURE3D, MAKEDWORD_VERSION(1, 2) },
{"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC, 0 },
+ {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC, 0 },
{"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD, 0 },
{"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
{"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
@@ -2374,7 +2375,7 @@ static BOOL CheckTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
/* Vendor specific formats */
case WINED3DFMT_ATI2N:
- if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
+ if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 7a20ae1..ce84ea7 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1348,19 +1348,34 @@ static void shader_glsl_color_correction(SHADER_OPCODE_ARG* arg) {
/* GL_ATI_texture_compression_3dc returns the two channels as luminance-alpha,
* which means the first one is replicated accross .rgb, and the 2nd one is in
* .a. We need the 2nd in .g
+ *
+ * GL_EXT_texture_compression_rgtc returns the values in .rg, however, they
+ * are swapped compared to d3d. So swap red and green.
*/
mask = shader_glsl_add_dst_param(arg, arg->dst, WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &dst_param);
mask_size = shader_glsl_get_write_mask_size(mask);
- if(mask_size == 4) {
- /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
- shader_addline(arg->buffer, "%s.%c = %s.%c;\n",
- dst_param.reg_name, dst_param.mask_str[2],
- dst_param.reg_name, dst_param.mask_str[4]);
- } else if(mask_size == 1) {
- /* Nothing to do */
+ if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
+ if(mask_size >= 2) {
+ shader_addline(arg->buffer, "%s.%c%c = %s.%c%c;\n",
+ dst_param.reg_name, dst_param.mask_str[1],
+ dst_param.mask_str[2],
+ dst_param.reg_name, dst_param.mask_str[2],
+ dst_param.mask_str[1]);
+ } else {
+ FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
+ }
} else {
- FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
- /* This is bad: We have .r[gb], but we need .ra */
+ if(mask_size == 4) {
+ /* Swap y and z (U and L), and do a sign conversion on x and the new y(V and U) */
+ shader_addline(arg->buffer, "%s.%c = %s.%c;\n",
+ dst_param.reg_name, dst_param.mask_str[2],
+ dst_param.reg_name, dst_param.mask_str[4]);
+ } else if(mask_size == 1) {
+ /* Nothing to do */
+ } else {
+ FIXME("%u components sampled from a converted ATI2N texture\n", mask_size);
+ /* This is bad: We have .r[gb], but we need .ra */
+ }
}
break;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 370f50b..da08d4f 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -395,7 +395,12 @@ BOOL initPixelFormats(WineD3D_GL_Info *gl_info)
*/
}
- if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
+ if(GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
+ dst = getFmtIdx(WINED3DFMT_ATI2N);
+ gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
+ gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
+ gl_info->gl_formats[dst].conversion_group= WINED3DFMT_ATI2N;
+ } else if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC)) {
dst = getFmtIdx(WINED3DFMT_ATI2N);
gl_info->gl_formats[dst].glInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
gl_info->gl_formats[dst].glGammaInternal = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI;
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h
index 533c991..ac4967d 100644
--- a/include/wine/wined3d_gl.h
+++ b/include/wine/wined3d_gl.h
@@ -2996,6 +2996,14 @@ typedef void (WINE_GLAPI *PGLFNSETFRAGMENTSHADERCONSTANTATI) (GLuint dst, const
#define GL_ATI_texture_compression_3dc
#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837
#endif
+/* GL_EXT_texture_compression_rgtc */
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
/* GL_VERSION_2_0 */
#ifndef GL_VERSION_2_0
@@ -3327,6 +3335,7 @@ typedef enum _GL_SupportedExt {
EXT_STENCIL_WRAP,
EXT_TEXTURE3D,
EXT_TEXTURE_COMPRESSION_S3TC,
+ EXT_TEXTURE_COMPRESSION_RGTC,
EXT_TEXTURE_FILTER_ANISOTROPIC,
EXT_TEXTURE_LOD,
EXT_TEXTURE_LOD_BIAS,