oleaut32 patch

Ove Kaaven ovehk at ping.uio.no
Thu Sep 20 15:15:49 CDT 2001


Here's fixes for numerous OLE Automation bugs found while debugging
installshield v6... if anyone happen to find other any bugs still lurking
around in this area of wine, it just might help my efforts a lot...

Log:
Ove Kaaven <ovek at transgaming.com>
Variants and safe arrays is now able to copy BSTR swith embedded null
characters. Safe arrays now handle BSTRs and variants.

Index: dlls/oleaut32/safearray.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/safearray.c,v
retrieving revision 1.10
diff -u -r1.10 safearray.c
--- dlls/oleaut32/safearray.c	2001/06/19 18:20:49	1.10
+++ dlls/oleaut32/safearray.c	2001/09/20 18:50:49
@@ -18,6 +18,8 @@
 
 DEFAULT_DEBUG_CHANNEL(ole);
 
+#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))
+
 /* Localy used methods */
 static INT  
 endOfDim(LONG *coor, SAFEARRAYBOUND *mat, LONG dim, LONG realDim);
@@ -53,24 +55,24 @@
 static const ULONG VARTYPE_SIZE[] =
 {
   /* this is taken from wtypes.h.  Only [S]es are supported by the SafeArray */
-VARTYPE_NOT_SUPPORTED,	/* VT_EMPTY    [V]   [P]    nothing			*/
-VARTYPE_NOT_SUPPORTED,	/* VT_NULL     [V]   [P]    SQL style Nul	*/
-2,	                    /* VT_I2       [V][T][P][S] 2 byte signed int */
-4, 	                    /* VT_I4       [V][T][P][S] 4 byte signed int */
-4, 	                    /* VT_R4       [V][T][P][S] 4 byte real	*/
-8,	                    /* VT_R8       [V][T][P][S] 8 byte real	*/
+VARTYPE_NOT_SUPPORTED,  /* VT_EMPTY    [V]   [P]    nothing			*/
+VARTYPE_NOT_SUPPORTED,  /* VT_NULL     [V]   [P]    SQL style Nul	*/
+2,                      /* VT_I2       [V][T][P][S] 2 byte signed int */
+4,                      /* VT_I4       [V][T][P][S] 4 byte signed int */
+4,                      /* VT_R4       [V][T][P][S] 4 byte real	*/
+8,                      /* VT_R8       [V][T][P][S] 8 byte real	*/
 8,                      /* VT_CY       [V][T][P][S] currency */
-8,	                    /* VT_DATE     [V][T][P][S] date */
-4,	                    /* VT_BSTR     [V][T][P][S] OLE Automation string*/
-4,	                    /* VT_DISPATCH [V][T][P][S] IDispatch *	*/
+8,                      /* VT_DATE     [V][T][P][S] date */
+sizeof(BSTR),           /* VT_BSTR     [V][T][P][S] OLE Automation string*/
+sizeof(LPDISPATCH),     /* VT_DISPATCH [V][T][P][S] IDispatch *	*/
 4,                      /* VT_ERROR    [V][T]   [S] SCODE	*/
-4,	                    /* VT_BOOL     [V][T][P][S] True=-1, False=0*/
-24,                     /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
-4,	                    /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
-16,	                    /* VT_DECIMAL  [V][T]   [S] 16 byte fixed point	*/
+4,                      /* VT_BOOL     [V][T][P][S] True=-1, False=0*/
+sizeof(VARIANT),        /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
+sizeof(LPUNKNOWN),      /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
+sizeof(DECIMAL),        /* VT_DECIMAL  [V][T]   [S] 16 byte fixed point	*/
 VARTYPE_NOT_SUPPORTED,                         /* no VARTYPE here..... */
 VARTYPE_NOT_SUPPORTED,	/* VT_I1          [T]       signed char	*/
-1,	                    /* VT_UI1      [V][T][P][S] unsigned char			*/
+1,                      /* VT_UI1      [V][T][P][S] unsigned char			*/
 VARTYPE_NOT_SUPPORTED,	/* VT_UI2         [T][P]    unsigned short	*/
 VARTYPE_NOT_SUPPORTED,	/* VT_UI4         [T][P]    unsigned short	*/
 VARTYPE_NOT_SUPPORTED,	/* VT_I8          [T][P]    signed 64-bit int			*/
@@ -264,7 +266,6 @@
   ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
-  BSTR  pbstrReAllocStr     = NULL; /* BSTR reallocated */
 
   /* Validate the index given */
   if(! validCoordinate(rgIndices, psa)) 
@@ -282,20 +283,28 @@
   
     if(isPointer(psa->fFeatures)) { /* increment ref count for this pointer */
 
-      *((VOID**)elementStorageAddress) = *(VOID**)pv; 
+      *((PVOID*)elementStorageAddress) = *(PVOID*)pv; 
       IUnknown_AddRef( *(IUnknown**)pv);
 
     } else { 
 
       if(psa->fFeatures == FADF_BSTR) { /* Create a new object */
-
-        if((pbstrReAllocStr = SysAllocString( (OLECHAR*)pv )) == NULL) {
+        BSTR pbstrReAllocStr = NULL;
+        if(pv &&
+           ((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
           SafeArrayUnlock(psa);  
           return E_OUTOFMEMORY;
         } else 
           *((BSTR*)elementStorageAddress) = pbstrReAllocStr;
-
-      } else /* dupplicate the memory */
+      }
+      else if(psa->fFeatures == FADF_VARIANT) {
+        HRESULT hr = VariantCopy(elementStorageAddress, pv);
+        if (FAILED(hr)) {
+          SafeArrayUnlock(psa);
+          return hr;
+        }
+      }
+      else /* duplicate the memory */
         memcpy(elementStorageAddress, pv, SafeArrayGetElemsize(psa) );
     }
 
@@ -321,7 +330,6 @@
   ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
-  BSTR  pbstrReturnedStr    = NULL; /* BSTR reallocated */
 
   if(! validArg(psa)) 
     return E_INVALIDARG;
@@ -338,17 +346,26 @@
     elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
   
     if( psa->fFeatures == FADF_BSTR) {           /* reallocate the obj */
-      if( (pbstrReturnedStr = 
-          SysAllocString( *(OLECHAR**)elementStorageAddress )) == NULL) {
+      BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
+      BSTR pbstrReturnedStr = NULL;
+      if( pbstrStoredStr &&
+          ((pbstrReturnedStr = SYSDUPSTRING( pbstrStoredStr )) == NULL) ) {
         SafeArrayUnlock(psa);
         return E_OUTOFMEMORY;
       } else 
         *((BSTR*)pv) = pbstrReturnedStr; 
-        
-    } else if( isPointer(psa->fFeatures) )       /* simply copy the pointer */
-       pv = *((PVOID*)elementStorageAddress); 
+    }
+    else if( psa->fFeatures == FADF_VARIANT) {
+      HRESULT hr = VariantCopy(pv, elementStorageAddress);
+      if (FAILED(hr)) {
+        SafeArrayUnlock(psa);
+        return hr;
+      }
+    }
+    else if( isPointer(psa->fFeatures) )         /* simply copy the pointer */
+      *(PVOID*)pv = *((PVOID*)elementStorageAddress); 
     else                                         /* copy the bytes */
-      memcpy(pv, elementStorageAddress, SafeArrayGetElemsize(psa) );
+      memcpy(pv, elementStorageAddress, psa->cbElements );
 
   } else {
     ERR("SafeArray: Cannot lock array....\n");
@@ -515,8 +532,6 @@
   HRESULT  hRes;
   ULONG    ulWholeArraySize; /* count spot in array  */
   ULONG    ulDataIter;       /* to iterate the data space */
-  IUnknown *punk;
-  BSTR   bstr;
 
   if(! validArg(psa)) 
     return E_INVALIDARG;
@@ -527,6 +542,7 @@
   ulWholeArraySize = getArraySize(psa);
 
   if(isPointer(psa->fFeatures)) {           /* release the pointers */
+    IUnknown *punk;
 
     for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
       punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));	
@@ -535,7 +551,9 @@
         IUnknown_Release(punk);
     }
 
-  } else if(psa->fFeatures & FADF_BSTR) {  /* deallocate the obj */
+  }
+  else if(psa->fFeatures & FADF_BSTR) {  /* deallocate the obj */
+    BSTR bstr;
 
     for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
       bstr = *(BSTR*)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));
@@ -544,6 +562,12 @@
         SysFreeString( bstr );
     }
   }
+  else if(psa->fFeatures & FADF_VARIANT) {  /* deallocate the obj */
+
+    for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
+      VariantClear((VARIANT*)((char *) psa->pvData+(ulDataIter*(psa->cbElements))));
+    }
+  }
       
   /* check if this array is a Vector, in which case do not free the data 
      block since it has been allocated by AllocDescriptor and therefore
@@ -599,7 +623,8 @@
         IUnknown_Release(punk);
     }
 
-  } else if( (*psaTarget)->fFeatures & FADF_BSTR) {  /* the target contain BSTR
+  }
+  else if( (*psaTarget)->fFeatures & FADF_BSTR) {    /* the target contain BSTR
                                                         that must be freed */ 
     for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
       bstr = 
@@ -609,6 +634,12 @@
         SysFreeString( bstr );
     }
   }
+  else if( (*psaTarget)->fFeatures & FADF_VARIANT) {
+
+    for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
+      VariantClear((VARIANT*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)));
+    }
+  }
 
   return duplicateData(psaSource, psaTarget);
 }
@@ -822,7 +853,7 @@
 
   if(lDelta < 0) {                    /* array needs to be shorthen  */
     if( isPointer(psa->fFeatures))    /* ptr that need to be released */
-	    for(;lDelta < 0; lDelta++) {
+      for(;lDelta < 0; lDelta++) {
 	      punk = *(IUnknown**)
           ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
 	
@@ -831,13 +862,17 @@
 	    }
 
     else if(psa->fFeatures & FADF_BSTR)  /* BSTR that need to be freed */
-	    for(;lDelta < 0; lDelta++) {
+      for(;lDelta < 0; lDelta++) {
         bstr = *(BSTR*)
           ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
 
         if( bstr != NULL )
           SysFreeString( bstr );
       }
+    else if(psa->fFeatures & FADF_VARIANT)
+      for(;lDelta < 0; lDelta++) {
+        VariantClear((VARIANT*)((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements)));
+      }
   }
 
   if (!(psa->fFeatures & FADF_CREATEVECTOR))
@@ -878,9 +913,10 @@
   VARTYPE vt) 
 {
   switch(vt) {
+    case VT_BSTR:      return FADF_BSTR;
     case VT_UNKNOWN:   return FADF_UNKNOWN;
     case VT_DISPATCH:  return FADF_DISPATCH;
-    case VT_BSTR:      return FADF_BSTR;
+    case VT_VARIANT:   return FADF_VARIANT;
   }
   return 0;
 }
@@ -998,8 +1034,6 @@
 {
   ULONG    ulWholeArraySize; /* size of the thing */
   LONG     lDelta;
-  IUnknown *punk;
-  BSTR   pbstrReAllocStr = NULL; /* BSTR reallocated */
 
   ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
   
@@ -1007,6 +1041,7 @@
 
   if( isPointer(psa->fFeatures) ) {  /* If datatype is object increment 
                                         object's reference count */
+    IUnknown *punk;
 
     for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
       punk = *(IUnknown**)((char *) psa->pvData+(lDelta * psa->cbElements));
@@ -1019,11 +1054,13 @@
     memcpy((*ppsaOut)->pvData, psa->pvData, 
       ulWholeArraySize*psa->cbElements);
 
-  } else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
-                                               the BSTR in the new array */
+  }
+  else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
+                                             the BSTR in the new array */
+    BSTR   pbstrReAllocStr = NULL;
 
     for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
-      if(( pbstrReAllocStr = SysAllocString(
+      if(( pbstrReAllocStr = SYSDUPSTRING(
             *(BSTR*)((char *) psa->pvData+(lDelta * psa->cbElements)))) == NULL) {
 
         SafeArrayUnlock(*ppsaOut);
@@ -1034,8 +1071,17 @@
         pbstrReAllocStr;
     }
 
-  } else { /* Simply copy the source array data into target array */
+  }
+  else if( psa->fFeatures & FADF_VARIANT ) {
 
+    for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
+      VariantCopy((VARIANT*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements)),
+                  (VARIANT*)((char *) psa->pvData+(lDelta * psa->cbElements)));
+    }
+
+  }
+  else { /* Simply copy the source array data into target array */
+
     memcpy((*ppsaOut)->pvData, psa->pvData, 
       ulWholeArraySize*psa->cbElements);
   }
@@ -1069,13 +1115,21 @@
   {
     vt = VT_RECORD;
   }
-  else if (psa->fFeatures & FADF_DISPATCH)
+  else if (psa->fFeatures & FADF_BSTR)
   {
-    vt = VT_DISPATCH;
+    vt = VT_BSTR;
   }
   else if (psa->fFeatures & FADF_UNKNOWN)
   {
     vt = VT_UNKNOWN;
+  }
+  else if (psa->fFeatures & FADF_DISPATCH)
+  {
+    vt = VT_DISPATCH;
+  }
+  else if (psa->fFeatures & FADF_VARIANT)
+  {
+    vt = VT_VARIANT;
   }
 
   if (vt != VT_EMPTY)
Index: dlls/oleaut32/variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.25
diff -u -r1.25 variant.c
--- dlls/oleaut32/variant.c	2001/09/10 23:16:31	1.25
+++ dlls/oleaut32/variant.c	2001/09/20 18:50:55
@@ -41,6 +41,8 @@
 
 DEFAULT_DEBUG_CHANNEL(ole);
 
+#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))
+
 #ifndef FLT_MAX
 # ifdef MAXFLOAT
 #  define FLT_MAX MAXFLOAT
@@ -1675,7 +1675,7 @@
  */
 void WINAPI VariantInit(VARIANTARG* pvarg)
 {
-  TRACE("(%p),stub\n",pvarg);
+  TRACE("(%p)\n",pvarg);
 
   memset(pvarg, 0, sizeof (VARIANTARG));
   V_VT(pvarg) = VT_EMPTY;
@@ -1754,7 +1754,7 @@
 {
   HRESULT res = S_OK;
 
-  TRACE("(%p, %p)\n", pvargDest, pvargSrc);
+  TRACE("(%p, %p), vt=%d\n", pvargDest, pvargSrc, V_VT(pvargSrc));
 
   res = ValidateVariantType( V_VT(pvargSrc) );
 
@@ -1795,7 +1795,7 @@
 	  switch( V_VT(pvargSrc) & VT_TYPEMASK )
 	  {
 	    case( VT_BSTR ):
-	      V_UNION(pvargDest,bstrVal) = SysAllocString( V_UNION(pvargSrc,bstrVal) );
+	      V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( V_UNION(pvargSrc,bstrVal) );
 	      break;
 	    case( VT_DISPATCH ):
 	      V_UNION(pvargDest,pdispVal) = V_UNION(pvargSrc,pdispVal);
@@ -1884,7 +1884,7 @@
 	  switch( V_VT(pvargSrc) & VT_TYPEMASK )
 	  {
 	    case( VT_BSTR ):
-	      V_UNION(pvargDest,bstrVal) = SysAllocString( *(V_UNION(pvargSrc,pbstrVal)) );
+	      V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( *(V_UNION(pvargSrc,pbstrVal)) );
 	      break;
 	    case( VT_DISPATCH ):
 	      break;
@@ -1976,7 +1976,7 @@
 	VARIANTARG varg;
 	VariantInit( &varg );
 	
-	TRACE("(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
+	TRACE("(%p, %p, %ld, %u, %u) vt=%d\n", pvargDest, pvargSrc, lcid, wFlags, vt, V_VT(pvargSrc));
 
 	/* validate our source argument.
 	 */





More information about the wine-patches mailing list