Care for write protected resource in propsheet
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Sat Oct 12 14:33:56 CDT 2002
>>>>> "Alexandre" == Alexandre Julliard <julliard at winehq.com> writes:
Alexandre> Uwe Bonnes <bon at elektron.ikp.physik.tu-darmstadt.de> writes:
>> Please give at least a hint for a proper fix ...
Alexandre> Well I don't really know, someone needs to investigate how
Alexandre> Windows does it. But it should be possible to change the
Alexandre> window style without copying the template, or if we really
Alexandre> need to do the copy write a single routine for that, that
Alexandre> parses the template to determine the proper size to copy.
To unlock write protected resources, we have a handler check_resource... in
win32/except.c. However with the webpack application and builtin comctl32,
the application gets the exception first, popping up a message box and when
check_resource is reached, it doesn't trigger for this in-memory resource.
Running with native comctl32 doesn't show an exception happening. So I
guess, NT does the size determination and copying too.
Changelog:
dlls/comctl32/propsheet.c:
Add function to get size of in-memory resource and used this
function to copy resouce to writable memory.
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Index: wine/dlls/comctl32/propsheet.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/propsheet.c,v
retrieving revision 1.70
diff -u -r1.70 propsheet.c
--- wine/dlls/comctl32/propsheet.c 10 Oct 2002 21:22:10 -0000 1.70
+++ wine/dlls/comctl32/propsheet.c 12 Oct 2002 18:31:10 -0000
@@ -36,6 +36,8 @@
/******************************************************************************
* Data structures
*/
+#include "pshpack2.h"
+
typedef struct
{
WORD dlgVer;
@@ -45,6 +47,18 @@
DWORD style;
} MyDLGTEMPLATEEX;
+typedef struct
+{
+ DWORD helpid;
+ DWORD exStyle;
+ DWORD style;
+ short x;
+ short y;
+ short cy;
+ DWORD id;
+} MyDLGITEMTEMPLATEEX;
+#include "poppack.h"
+
typedef struct tagPropPageInfo
{
HPROPSHEETPAGE hpage; /* to keep track of pages not passed to PropertySheet */
@@ -1159,6 +1173,129 @@
return TRUE;
}
+/*
+ * Get the size of an in-memory Template
+ *
+ *( Based on the code of PROPSHEET_CollectPageInfo)
+ */
+
+static UINT GetTemplateSize(DLGTEMPLATE* pTemplate)
+
+{
+ const WORD* p = (const WORD *)pTemplate;
+ BOOL istemplateex = (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF);
+ WORD nrofitems;
+
+ if (istemplateex)
+ {
+ /* DIALOGEX template */
+
+ p++; /* dlgVer */
+ p++; /* signature */
+ p += 2; /* help ID */
+ p += 2; /* ext style */
+ p += 2; /* style */
+ }
+ else
+ {
+ /* DIALOG template */
+
+ p += 2; /* style */
+ p += 2; /* ext style */
+ }
+
+ nrofitems = (WORD)*p; p++; /* nb items */
+ p++; /* x */
+ p++; /* y */
+ p++; /* width */
+ p++; /* height */
+
+ /* menu */
+ switch ((WORD)*p)
+ {
+ case 0x0000:
+ p++;
+ break;
+ case 0xffff:
+ p += 2;
+ break;
+ default:
+ TRACE("menu %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW( (LPCWSTR)p ) + 1;
+ break;
+ }
+
+ /* class */
+ switch ((WORD)*p)
+ {
+ case 0x0000:
+ p++;
+ break;
+ case 0xffff:
+ p += 2;
+ break;
+ default:
+ TRACE("class %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW( (LPCWSTR)p ) + 1;
+ break;
+ }
+
+ /*title */
+ TRACE("title %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW((LPCWSTR)p) + 1;
+
+ /* font, if DS_FONT set */
+ if ((DS_SETFONT & ((istemplateex)? ((MyDLGTEMPLATEEX*)pTemplate)->style :
+ pTemplate->style)))
+ {
+ p+=(istemplateex)?3:1;
+ TRACE("font %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW( (LPCWSTR)p ) + 1; /* the font name*/
+ }
+
+ TRACE("%d items\n",nrofitems);
+ while (nrofitems > 0)
+ {
+ p = (WORD*)(((DWORD)p + 3) & ~3); // DWORD align
+
+ p += (istemplateex ? sizeof(MyDLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE))/sizeof(WORD);
+
+ switch ((WORD)*p)
+ {
+ case 0x0000:
+ p++;
+ break;
+ case 0xffff:
+ TRACE("class ordinal 0x%08lx\n",*(DWORD*)p);
+ p += 2;
+ break;
+ default:
+ TRACE("class %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW( (LPCWSTR)p ) + 1;
+ break;
+ }
+ switch ((WORD)*p)
+ {
+ case 0x0000:
+ p++;
+ break;
+ case 0xffff:
+ TRACE("text ordinal 0x%08lx\n",*(DWORD*)p);
+ p += 2;
+ break;
+ default:
+ TRACE("text %s\n",debugstr_w((LPCWSTR)p));
+ p += lstrlenW( (LPCWSTR)p ) + 1;
+ break;
+ }
+ p += *p + 1; // Skip extra data
+ --nrofitems;
+ }
+
+ TRACE("%p %p size 0x%08x\n",p, (WORD*)pTemplate,sizeof(WORD)*(p - (WORD*)pTemplate));
+ return (p - (WORD*)pTemplate)*sizeof(WORD);
+
+}
/******************************************************************************
* PROPSHEET_CreatePage
@@ -1187,7 +1324,10 @@
}
if (ppshpage->dwFlags & PSP_DLGINDIRECT)
- pTemplate = (DLGTEMPLATE*)ppshpage->u.pResource;
+ {
+ pTemplate = (DLGTEMPLATE*)ppshpage->u.pResource;
+ resSize = GetTemplateSize(pTemplate);
+ }
else
{
HRSRC hResource;
@@ -1209,13 +1349,13 @@
/*
* Make a copy of the dialog template to make it writable
*/
- temp = COMCTL32_Alloc(resSize);
- if (!temp)
- return FALSE;
-
- memcpy(temp, pTemplate, resSize);
- pTemplate = temp;
}
+ temp = COMCTL32_Alloc(resSize);
+ if (!temp)
+ return FALSE;
+
+ memcpy(temp, pTemplate, resSize);
+ pTemplate = temp;
if (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
{
More information about the wine-patches
mailing list