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