Changeset 6648 for trunk/src/oleaut32/safearray.c
- Timestamp:
- Sep 5, 2001, 3:19:02 PM (24 years ago)
- File:
- 
      - 1 edited
 
 - 
          
  trunk/src/oleaut32/safearray.c (modified) (68 diffs)
 
Legend:
- Unmodified
- Added
- Removed
- 
      trunk/src/oleaut32/safearray.cr6507 r6648 1 /* $Id: safearray.c,v 1.3 2001-09-05 13:19:01 bird Exp $ */ 1 2 /************************************************************************* 2 3 * OLE Automation … … 25 26 26 27 /* Localy used methods */ 27 static INT 28 static INT 28 29 endOfDim(LONG *coor, SAFEARRAYBOUND *mat, LONG dim, LONG realDim); 29 30 30 static ULONG 31 static ULONG 31 32 calcDisplacement(LONG *coor, SAFEARRAYBOUND *mat, LONG dim); 32 33 33 static BOOL 34 static BOOL 34 35 isPointer(USHORT feature); 35 36 36 static INT 37 static INT 37 38 getFeatures(VARTYPE vt); 38 39 39 static BOOL 40 static BOOL 40 41 validCoordinate(LONG *coor, SAFEARRAY *psa); 41 42 42 static BOOL 43 static BOOL 43 44 resizeSafeArray(SAFEARRAY *psa, LONG lDelta); 44 45 45 static BOOL 46 static BOOL 46 47 validArg(SAFEARRAY *psa); 47 48 48 static ULONG 49 static ULONG 49 50 getArraySize(SAFEARRAY *psa); 50 51 51 static HRESULT 52 static HRESULT 52 53 duplicateData(SAFEARRAY *psa, SAFEARRAY **ppsaOut); 53 54 … … 59 60 { 60 61 /* this is taken from wtypes.h. Only [S]es are supported by the SafeArray */ 61 VARTYPE_NOT_SUPPORTED, /* VT_EMPTY [V] [P] nothing*/62 VARTYPE_NOT_SUPPORTED, /* VT_NULL [V] [P] SQL style Nul*/63 2, 64 4, 65 4, /* VT_R4 [V][T][P][S] 4 byte real*/66 8, /* VT_R8 [V][T][P][S] 8 byte real*/62 VARTYPE_NOT_SUPPORTED, /* VT_EMPTY [V] [P] nothing */ 63 VARTYPE_NOT_SUPPORTED, /* VT_NULL [V] [P] SQL style Nul */ 64 2, /* VT_I2 [V][T][P][S] 2 byte signed int */ 65 4, /* VT_I4 [V][T][P][S] 4 byte signed int */ 66 4, /* VT_R4 [V][T][P][S] 4 byte real */ 67 8, /* VT_R8 [V][T][P][S] 8 byte real */ 67 68 8, /* VT_CY [V][T][P][S] currency */ 68 8, 69 4, 70 4, /* VT_DISPATCH [V][T][P][S] IDispatch **/71 4, /* VT_ERROR [V][T] [S] SCODE 72 4, 73 24, /* VT_VARIANT [V][T][P][S] VARIANT * 74 4, 75 16, /* VT_DECIMAL [V][T] [S] 16 byte fixed point*/69 8, /* VT_DATE [V][T][P][S] date */ 70 4, /* VT_BSTR [V][T][P][S] OLE Automation string*/ 71 4, /* VT_DISPATCH [V][T][P][S] IDispatch * */ 72 4, /* VT_ERROR [V][T] [S] SCODE */ 73 4, /* VT_BOOL [V][T][P][S] True=-1, False=0*/ 74 24, /* VT_VARIANT [V][T][P][S] VARIANT * */ 75 4, /* VT_UNKNOWN [V][T] [S] IUnknown * */ 76 16, /* VT_DECIMAL [V][T] [S] 16 byte fixed point */ 76 77 VARTYPE_NOT_SUPPORTED, /* no VARTYPE here..... */ 77 VARTYPE_NOT_SUPPORTED, /* VT_I1 [T] signed char*/78 1, /* VT_UI1 [V][T][P][S] unsigned char*/79 VARTYPE_NOT_SUPPORTED, /* VT_UI2 [T][P] unsigned short*/80 VARTYPE_NOT_SUPPORTED, /* VT_UI4 [T][P] unsigned short*/81 VARTYPE_NOT_SUPPORTED, /* VT_I8 [T][P] signed 64-bit int*/82 VARTYPE_NOT_SUPPORTED, /* VT_UI8 [T][P] unsigned 64-bit int*/83 VARTYPE_NOT_SUPPORTED, /* VT_INT [T] signed machine int*/84 VARTYPE_NOT_SUPPORTED, /* VT_UINT [T] unsigned machine int*/85 VARTYPE_NOT_SUPPORTED, /* VT_VOID [T] C style void*/86 VARTYPE_NOT_SUPPORTED, /* VT_HRESULT [T] Standard return type*/87 VARTYPE_NOT_SUPPORTED, /* VT_PTR [T] pointer type*/88 VARTYPE_NOT_SUPPORTED, 89 VARTYPE_NOT_SUPPORTED, /* VT_CARRAY [T] C style array*/90 VARTYPE_NOT_SUPPORTED, /* VT_USERDEFINED [T] user defined type*/91 VARTYPE_NOT_SUPPORTED, /* VT_LPSTR [T][P] null terminated string*/92 VARTYPE_NOT_SUPPORTED, /* VT_LPWSTR [T][P] wide null term string*/93 VARTYPE_NOT_SUPPORTED, /* VT_FILETIME [P] FILETIME*/94 VARTYPE_NOT_SUPPORTED, 95 VARTYPE_NOT_SUPPORTED, /* VT_STREAM [P] Name of stream follows*/96 VARTYPE_NOT_SUPPORTED, /* VT_STORAGE [P] Name of storage follows*/97 VARTYPE_NOT_SUPPORTED, 98 VARTYPE_NOT_SUPPORTED, 99 VARTYPE_NOT_SUPPORTED, 100 VARTYPE_NOT_SUPPORTED, /* VT_CF [P] Clipboard format*/101 VARTYPE_NOT_SUPPORTED, /* VT_CLSID [P] A Class ID*/102 VARTYPE_NOT_SUPPORTED, /* VT_VECTOR [P] simple counted array*/103 VARTYPE_NOT_SUPPORTED, /* VT_ARRAY [V] SAFEARRAY**/104 VARTYPE_NOT_SUPPORTED /* VT_BYREF [V] void* for local use*/78 VARTYPE_NOT_SUPPORTED, /* VT_I1 [T] signed char */ 79 1, /* VT_UI1 [V][T][P][S] unsigned char */ 80 VARTYPE_NOT_SUPPORTED, /* VT_UI2 [T][P] unsigned short */ 81 VARTYPE_NOT_SUPPORTED, /* VT_UI4 [T][P] unsigned short */ 82 VARTYPE_NOT_SUPPORTED, /* VT_I8 [T][P] signed 64-bit int */ 83 VARTYPE_NOT_SUPPORTED, /* VT_UI8 [T][P] unsigned 64-bit int */ 84 VARTYPE_NOT_SUPPORTED, /* VT_INT [T] signed machine int */ 85 VARTYPE_NOT_SUPPORTED, /* VT_UINT [T] unsigned machine int */ 86 VARTYPE_NOT_SUPPORTED, /* VT_VOID [T] C style void */ 87 VARTYPE_NOT_SUPPORTED, /* VT_HRESULT [T] Standard return type */ 88 VARTYPE_NOT_SUPPORTED, /* VT_PTR [T] pointer type */ 89 VARTYPE_NOT_SUPPORTED, /* VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT)*/ 90 VARTYPE_NOT_SUPPORTED, /* VT_CARRAY [T] C style array */ 91 VARTYPE_NOT_SUPPORTED, /* VT_USERDEFINED [T] user defined type */ 92 VARTYPE_NOT_SUPPORTED, /* VT_LPSTR [T][P] null terminated string */ 93 VARTYPE_NOT_SUPPORTED, /* VT_LPWSTR [T][P] wide null term string */ 94 VARTYPE_NOT_SUPPORTED, /* VT_FILETIME [P] FILETIME */ 95 VARTYPE_NOT_SUPPORTED, /* VT_BLOB [P] Length prefixed bytes */ 96 VARTYPE_NOT_SUPPORTED, /* VT_STREAM [P] Name of stream follows */ 97 VARTYPE_NOT_SUPPORTED, /* VT_STORAGE [P] Name of storage follows */ 98 VARTYPE_NOT_SUPPORTED, /* VT_STREAMED_OBJECT[P] Stream contains an object*/ 99 VARTYPE_NOT_SUPPORTED, /* VT_STORED_OBJECT [P] Storage contains object*/ 100 VARTYPE_NOT_SUPPORTED, /* VT_BLOB_OBJECT [P] Blob contains an object*/ 101 VARTYPE_NOT_SUPPORTED, /* VT_CF [P] Clipboard format */ 102 VARTYPE_NOT_SUPPORTED, /* VT_CLSID [P] A Class ID */ 103 VARTYPE_NOT_SUPPORTED, /* VT_VECTOR [P] simple counted array */ 104 VARTYPE_NOT_SUPPORTED, /* VT_ARRAY [V] SAFEARRAY* */ 105 VARTYPE_NOT_SUPPORTED /* VT_BYREF [V] void* for local use */ 105 106 }; 106 107 … … 109 110 110 111 /************************************************************************* 111 * 112 * SafeArrayAllocDescriptor 112 113 * Allocate the appropriate amount of memory for the SafeArray descriptor 113 114 */ 114 HRESULT WINAPI SafeArrayAllocDescriptor( 115 UINT cDims, 116 SAFEARRAY **ppsaOut) 115 HRESULT WINAPI SafeArrayAllocDescriptor( 116 UINT cDims, 117 SAFEARRAY **ppsaOut) 117 118 { 118 119 SAFEARRAYBOUND *sab; … … 124 125 125 126 /* Allocate memory for SAFEARRAY struc */ 126 if(( (*ppsaOut)=HeapAlloc( 127 if(( (*ppsaOut)=HeapAlloc( 127 128 GetProcessHeap(), HEAP_ZERO_MEMORY, allocSize)) == NULL){ 128 129 return(E_UNEXPECTED); … … 134 135 135 136 /************************************************************************* 136 * 137 * SafeArrayAllocData 137 138 * Allocate the appropriate amount of data for the SafeArray data 138 139 */ 139 140 HRESULT WINAPI SafeArrayAllocData( 140 SAFEARRAY *psa) 141 SAFEARRAY *psa) 141 142 { 142 143 ULONG ulWholeArraySize; /* to store the size of the whole thing */ … … 144 145 dprintf(("SafeArrayAllocData %x", psa)); 145 146 146 if(! validArg(psa)) 147 if(! validArg(psa)) 147 148 return E_INVALIDARG; 148 149 … … 150 151 151 152 /* Allocate memory for the data itself */ 152 if((psa->pvData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 153 if((psa->pvData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 153 154 psa->cbElements*ulWholeArraySize)) == NULL) 154 155 return(E_UNEXPECTED); 155 156 156 TRACE("SafeArray: %lu bytes allocated for data at %p (%lu objects).\n", 157 TRACE("SafeArray: %lu bytes allocated for data at %p (%lu objects).\n", 157 158 psa->cbElements*ulWholeArraySize, psa->pvData, ulWholeArraySize); 158 159 … … 161 162 162 163 /************************************************************************* 163 * 164 * Create a SafeArray object by encapsulating AllocDescriptor and AllocData 164 * SafeArrayCreate 165 * Create a SafeArray object by encapsulating AllocDescriptor and AllocData 165 166 */ 166 167 SAFEARRAY* WINAPI SafeArrayCreate( 167 VARTYPE vt, 168 UINT cDims, 168 VARTYPE vt, 169 UINT cDims, 169 170 SAFEARRAYBOUND *rgsabound) 170 171 { … … 184 185 return NULL; 185 186 186 /* setup data members... */ 187 /* setup data members... */ 187 188 psa->cDims = cDims; 188 189 psa->fFeatures = getFeatures(vt); … … 197 198 } 198 199 199 /* allocate memory for the data... */ 200 /* allocate memory for the data... */ 200 201 if( FAILED( hRes = SafeArrayAllocData(psa))) { 201 SafeArrayDestroyDescriptor(psa); 202 SafeArrayDestroyDescriptor(psa); 202 203 ERR("() : Failed to allocate the Safe Array data\n"); 203 204 return NULL; 204 205 } 205 206 206 return(psa); 207 } 208 209 /************************************************************************* 210 * 207 return(psa); 208 } 209 210 /************************************************************************* 211 * SafeArrayDestroyDescriptor 211 212 * Frees the memory associated with the descriptor. 212 213 */ … … 217 218 218 219 /* Check for lockness before to free... */ 219 if(psa->cLocks > 0) 220 if(psa->cLocks > 0) 220 221 return DISP_E_ARRAYISLOCKED; 221 222 222 223 /* The array is unlocked, then, deallocate memory */ 223 if(HeapFree( GetProcessHeap(), 0, psa) == FALSE) 224 if(HeapFree( GetProcessHeap(), 0, psa) == FALSE) 224 225 return E_UNEXPECTED; 225 226 226 227 return(S_OK); 227 228 } … … 229 230 230 231 /************************************************************************* 231 * 232 * SafeArrayLock 232 233 * Increment the lock counter 233 234 * 234 235 * Doc says (MSDN Library ) that psa->pvData should be made available (!= NULL) 235 * only when psa->cLocks is > 0... I don't get it since pvData is allocated 236 * before the array is locked, therefore 236 * only when psa->cLocks is > 0... I don't get it since pvData is allocated 237 * before the array is locked, therefore 237 238 */ 238 239 HRESULT WINAPI SafeArrayLock( … … 241 242 dprintf(("SafeArrayLock %x", psa)); 242 243 243 if(! validArg(psa)) 244 if(! validArg(psa)) 244 245 return E_INVALIDARG; 245 246 … … 250 251 251 252 /************************************************************************* 252 * 253 * SafeArrayUnlock 253 254 * Decrement the lock counter 254 255 */ … … 258 259 dprintf(("SafeArrayUnlock %x", psa)); 259 260 260 if(! validArg(psa)) 261 return E_INVALIDARG; 262 263 if (psa->cLocks > 0) 261 if(! validArg(psa)) 262 return E_INVALIDARG; 263 264 if (psa->cLocks > 0) 264 265 psa->cLocks--; 265 266 … … 269 270 270 271 /************************************************************************* 271 * 272 * SafeArrayPutElement 272 273 * Set the data at the given coordinate 273 274 */ 274 275 HRESULT WINAPI SafeArrayPutElement( 275 SAFEARRAY *psa, 276 LONG *rgIndices, 276 SAFEARRAY *psa, 277 LONG *rgIndices, 277 278 void *pv) 278 279 { 279 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 280 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 280 281 the desired one... */ 281 282 PVOID elementStorageAddress = NULL; /* Adress to store the data */ … … 285 286 286 287 /* Validate the index given */ 287 if(! validCoordinate(rgIndices, psa)) 288 if(! validCoordinate(rgIndices, psa)) 288 289 return DISP_E_BADINDEX; 289 290 if(! validArg(psa)) … … 294 295 /* Figure out the number of items to skip */ 295 296 stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims); 296 297 297 298 /* Figure out the number of byte to skip ... */ 298 299 elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements); 299 300 300 301 if(isPointer(psa->fFeatures)) { /* increment ref count for this pointer */ 301 302 302 *((VOID**)elementStorageAddress) = *(VOID**)pv; 303 *((VOID**)elementStorageAddress) = *(VOID**)pv; 303 304 IUnknown_AddRef( *(IUnknown**)pv); 304 305 305 } else { 306 } else { 306 307 307 308 if(psa->fFeatures == FADF_BSTR) { /* Create a new object */ 308 309 309 310 if((pbstrReAllocStr = SysAllocString( (OLECHAR*)pv )) == NULL) { 310 SafeArrayUnlock(psa); 311 SafeArrayUnlock(psa); 311 312 return E_OUTOFMEMORY; 312 } else 313 } else 313 314 *((BSTR*)elementStorageAddress) = pbstrReAllocStr; 314 315 … … 323 324 324 325 TRACE("SafeArray: item put at adress %p.\n",elementStorageAddress); 325 return SafeArrayUnlock(psa); 326 } 327 328 329 /************************************************************************* 330 * 326 return SafeArrayUnlock(psa); 327 } 328 329 330 /************************************************************************* 331 * SafeArrayGetElement 331 332 * Return the data element corresponding the the given coordinate 332 333 */ 333 334 HRESULT WINAPI SafeArrayGetElement( 334 SAFEARRAY *psa, 335 LONG *rgIndices, 335 SAFEARRAY *psa, 336 LONG *rgIndices, 336 337 void *pv) 337 338 { 338 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 339 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 339 340 the desired one... */ 340 341 PVOID elementStorageAddress = NULL; /* Adress to store the data */ … … 343 344 dprintf(("SafeArrayGetElement %x %x %x", psa, rgIndices, pv)); 344 345 345 if(! validArg(psa)) 346 return E_INVALIDARG; 347 346 if(! validArg(psa)) 347 return E_INVALIDARG; 348 348 349 if(! validCoordinate(rgIndices, psa)) /* Validate the index given */ 349 350 return(DISP_E_BADINDEX); … … 353 354 /* Figure out the number of items to skip */ 354 355 stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims); 355 356 356 357 /* Figure out the number of byte to skip ... */ 357 358 elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements); 358 359 359 360 if( psa->fFeatures == FADF_BSTR) { /* reallocate the obj */ 360 if( (pbstrReturnedStr = 361 if( (pbstrReturnedStr = 361 362 SysAllocString( *(OLECHAR**)elementStorageAddress )) == NULL) { 362 363 SafeArrayUnlock(psa); 363 364 return E_OUTOFMEMORY; 364 } else 365 *((BSTR*)pv) = pbstrReturnedStr; 366 365 } else 366 *((BSTR*)pv) = pbstrReturnedStr; 367 367 368 } else if( isPointer(psa->fFeatures) ) /* simply copy the pointer */ 368 pv = *((PVOID*)elementStorageAddress); 369 pv = *((PVOID*)elementStorageAddress); 369 370 else /* copy the bytes */ 370 371 memcpy(pv, elementStorageAddress, SafeArrayGetElemsize(psa) ); … … 375 376 } 376 377 377 return( SafeArrayUnlock(psa) ); 378 } 379 380 /************************************************************************* 381 * 378 return( SafeArrayUnlock(psa) ); 379 } 380 381 /************************************************************************* 382 * SafeArrayGetUBound 382 383 * return the UP bound for a given array dimension 383 384 */ 384 385 HRESULT WINAPI SafeArrayGetUBound( 385 SAFEARRAY *psa, 386 SAFEARRAY *psa, 386 387 UINT nDim, 387 388 LONG *plUbound) … … 390 391 dprintf(("SafeArrayGetUBound %x %x %x", psa, nDim, plUbound)); 391 392 392 if(! validArg(psa)) 393 return E_INVALIDARG; 394 395 if(nDim > psa->cDims) 393 if(! validArg(psa)) 394 return E_INVALIDARG; 395 396 if(nDim > psa->cDims) 396 397 return DISP_E_BADINDEX; 397 398 398 *plUbound = psa->rgsabound[nDim-1].lLbound + 399 *plUbound = psa->rgsabound[nDim-1].lLbound + 399 400 psa->rgsabound[nDim-1].cElements - 1; 400 401 … … 403 404 404 405 /************************************************************************* 405 * 406 * Return the LO bound for a given array dimension 406 * SafeArrayGetLBound 407 * Return the LO bound for a given array dimension 407 408 */ 408 409 HRESULT WINAPI SafeArrayGetLBound( 409 410 SAFEARRAY *psa, 410 UINT nDim, 411 UINT nDim, 411 412 LONG *plLbound) 412 413 { 413 if(! validArg(psa)) 414 return E_INVALIDARG; 415 416 if(nDim > psa->cDims) 414 if(! validArg(psa)) 415 return E_INVALIDARG; 416 417 if(nDim > psa->cDims) 417 418 return DISP_E_BADINDEX; 418 419 … … 422 423 423 424 /************************************************************************* 424 * 425 * SafeArrayGetDim 425 426 * returns the number of dimension in the array 426 427 */ 427 428 UINT WINAPI SafeArrayGetDim( 428 429 SAFEARRAY * psa) 429 { 430 { 430 431 /* 431 432 * A quick test in Windows shows that the behavior here for an invalid 432 433 * pointer is to return 0. 433 434 */ 434 if(! validArg(psa)) 435 if(! validArg(psa)) 435 436 return 0; 436 437 … … 439 440 440 441 /************************************************************************* 441 * 442 * SafeArrayGetElemsize 442 443 * Return the size of the element in the array 443 444 */ 444 445 UINT WINAPI SafeArrayGetElemsize( 445 446 SAFEARRAY * psa) 446 { 447 { 447 448 /* 448 449 * A quick test in Windows shows that the behavior here for an invalid 449 450 * pointer is to return 0. 450 451 */ 451 if(! validArg(psa)) 452 if(! validArg(psa)) 452 453 return 0; 453 454 … … 456 457 457 458 /************************************************************************* 458 * 459 * increment the access count and return the data 459 * SafeArrayAccessData 460 * increment the access count and return the data 460 461 */ 461 462 HRESULT WINAPI SafeArrayAccessData( 462 SAFEARRAY *psa, 463 SAFEARRAY *psa, 463 464 void **ppvData) 464 { 465 { 465 466 HRESULT hRes; 466 467 467 if(! validArg(psa)) 468 if(! validArg(psa)) 468 469 return E_INVALIDARG; 469 470 … … 471 472 472 473 switch (hRes) { 473 case S_OK: 474 case S_OK: 474 475 (*ppvData) = psa->pvData; 475 476 break; … … 478 479 return E_INVALIDARG; 479 480 } 480 481 481 482 return S_OK; 482 483 } … … 484 485 485 486 /************************************************************************* 486 * 487 * SafeArrayUnaccessData 487 488 * Decrement the access count 488 489 */ 489 490 HRESULT WINAPI SafeArrayUnaccessData( 490 491 SAFEARRAY * psa) 491 { 492 if(! validArg(psa)) 492 { 493 if(! validArg(psa)) 493 494 return E_INVALIDARG; 494 495 … … 496 497 } 497 498 498 /************************************************************************ 499 * 499 /************************************************************************ 500 * SafeArrayPtrOfIndex 500 501 * Return a pointer to the element at rgIndices 501 502 */ 502 503 HRESULT WINAPI SafeArrayPtrOfIndex( 503 SAFEARRAY *psa, 504 LONG *rgIndices, 504 SAFEARRAY *psa, 505 LONG *rgIndices, 505 506 void **ppvData) 506 { 507 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 507 { 508 ULONG stepCountInSAData = 0; /* Number of array item to skip to get to 508 509 the desired one... */ 509 510 510 if(! validArg(psa)) 511 return E_INVALIDARG; 512 513 if(! validCoordinate(rgIndices, psa)) 511 if(! validArg(psa)) 512 return E_INVALIDARG; 513 514 if(! validCoordinate(rgIndices, psa)) 514 515 return DISP_E_BADINDEX; 515 516 516 517 /* Figure out the number of items to skip */ 517 518 stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims); 518 519 519 520 *ppvData = (char *) psa->pvData+(stepCountInSAData*psa->cbElements); 520 521 … … 522 523 } 523 524 524 /************************************************************************ 525 * 525 /************************************************************************ 526 * SafeArrayDestroyData 526 527 * Frees the memory data bloc 527 528 */ 528 529 HRESULT WINAPI SafeArrayDestroyData( 529 530 SAFEARRAY *psa) 530 { 531 { 531 532 HRESULT hRes; 532 533 ULONG ulWholeArraySize; /* count spot in array */ … … 535 536 BSTR bstr; 536 537 537 if(! validArg(psa)) 538 return E_INVALIDARG; 539 540 if(psa->cLocks > 0) 538 if(! validArg(psa)) 539 return E_INVALIDARG; 540 541 if(psa->cLocks > 0) 541 542 return DISP_E_ARRAYISLOCKED; 542 543 … … 546 547 547 548 for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) { 548 punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements))); 549 550 if( punk != NULL) 549 punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements))); 550 551 if( punk != NULL) 551 552 IUnknown_Release(punk); 552 553 } … … 557 558 bstr = *(BSTR*)((char *) psa->pvData+(ulDataIter*(psa->cbElements))); 558 559 559 if( bstr != NULL) 560 if( bstr != NULL) 560 561 SysFreeString( bstr ); 561 562 } 562 563 } 563 564 /* check if this array is a Vector, in which case do not free the data 564 565 /* check if this array is a Vector, in which case do not free the data 565 566 block since it has been allocated by AllocDescriptor and therefore 566 567 deserve to be freed by DestroyDescriptor */ … … 573 574 psa->pvData = NULL; 574 575 } 575 576 576 577 return S_OK; 577 578 } 578 579 579 /************************************************************************ 580 * 580 /************************************************************************ 581 * SafeArrayCopyData 581 582 * Copy the psaSource's data block into psaTarget if dimension and size 582 583 * permits it. … … 585 586 SAFEARRAY *psaSource, 586 587 SAFEARRAY **psaTarget) 587 { 588 { 588 589 USHORT cDimCount; /* looper */ 589 590 LONG lDelta; /* looper */ 590 IUnknown *punk; 591 IUnknown *punk; 591 592 ULONG ulWholeArraySize; /* Number of item in SA */ 592 593 BSTR bstr; 593 594 594 if(! (validArg(psaSource) && validArg(*psaTarget)) ) 595 if(! (validArg(psaSource) && validArg(*psaTarget)) ) 595 596 return E_INVALIDARG; 596 597 … … 598 599 return E_INVALIDARG; 599 600 600 ulWholeArraySize = getArraySize(psaSource); 601 ulWholeArraySize = getArraySize(psaSource); 601 602 602 603 /* The two arrays boundaries must be of same lenght */ 603 604 for(cDimCount=0;cDimCount < psaSource->cDims; cDimCount++) 604 if( psaSource->rgsabound[cDimCount].cElements != 605 if( psaSource->rgsabound[cDimCount].cElements != 605 606 (*psaTarget)->rgsabound[cDimCount].cElements) 606 607 return E_INVALIDARG; 607 608 608 if( isPointer((*psaTarget)->fFeatures) ) { /* the target contains ptr 609 if( isPointer((*psaTarget)->fFeatures) ) { /* the target contains ptr 609 610 that must be released */ 610 611 for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) { … … 612 613 ((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)); 613 614 614 if( punk != NULL) 615 if( punk != NULL) 615 616 IUnknown_Release(punk); 616 617 } 617 618 618 619 } else if( (*psaTarget)->fFeatures & FADF_BSTR) { /* the target contain BSTR 619 that must be freed */ 620 that must be freed */ 620 621 for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) { 621 bstr = 622 bstr = 622 623 *(BSTR*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)); 623 624 624 if( bstr != NULL) 625 if( bstr != NULL) 625 626 SysFreeString( bstr ); 626 627 } … … 630 631 } 631 632 632 /************************************************************************ 633 * 633 /************************************************************************ 634 * SafeArrayDestroy 634 635 * Deallocates all memory reserved for the SafeArray 635 636 */ 636 637 HRESULT WINAPI SafeArrayDestroy( 637 638 SAFEARRAY * psa) 638 { 639 { 639 640 HRESULT hRes; 640 641 641 if(! validArg(psa)) 642 return E_INVALIDARG; 643 644 if(psa->cLocks > 0) 642 if(! validArg(psa)) 643 return E_INVALIDARG; 644 645 if(psa->cLocks > 0) 645 646 return DISP_E_ARRAYISLOCKED; 646 647 … … 652 653 } 653 654 654 /************************************************************************ 655 * 655 /************************************************************************ 656 * SafeArrayCopy 656 657 * Make a dupplicate of a SafeArray 657 658 */ 658 659 HRESULT WINAPI SafeArrayCopy( 659 SAFEARRAY *psa, 660 SAFEARRAY *psa, 660 661 SAFEARRAY **ppsaOut) 661 { 662 { 662 663 HRESULT hRes; 663 664 DWORD dAllocSize; 664 665 ULONG ulWholeArraySize; /* size of the thing */ 665 666 666 if(! validArg(psa)) 667 if(! validArg(psa)) 667 668 return E_INVALIDARG; 668 669 … … 670 671 671 672 /* Duplicate the SAFEARRAY struc */ 672 memcpy(*ppsaOut, psa, 673 memcpy(*ppsaOut, psa, 673 674 sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1))); 674 675 … … 677 678 /* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag, 678 679 because the data has not been allocated with the descriptor. */ 679 (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR; 680 681 /* Get the allocated memory size for source and allocate it for target */ 680 (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR; 681 682 /* Get the allocated memory size for source and allocate it for target */ 682 683 ulWholeArraySize = getArraySize(psa); /* Number of item in SA */ 683 684 dAllocSize = ulWholeArraySize*psa->cbElements; 684 685 685 (*ppsaOut)->pvData = 686 (*ppsaOut)->pvData = 686 687 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize); 687 688 if( (*ppsaOut)->pvData != NULL) { /* HeapAlloc succeed */ … … 693 694 return hRes; 694 695 } 695 696 696 697 } else { /* failed to allocate or dupplicate... */ 697 698 SafeArrayDestroyDescriptor(*ppsaOut); … … 705 706 } 706 707 707 /************************************************************************ 708 * 709 * Creates a one dimension safearray where the data is next to the 708 /************************************************************************ 709 * SafeArrayCreateVector 710 * Creates a one dimension safearray where the data is next to the 710 711 * SAFEARRAY structure. 711 712 */ 712 713 SAFEARRAY* WINAPI SafeArrayCreateVector( 713 VARTYPE vt, 714 LONG lLbound, 715 ULONG cElements) 716 { 714 VARTYPE vt, 715 LONG lLbound, 716 ULONG cElements) 717 { 717 718 SAFEARRAY *psa; 718 719 … … 723 724 724 725 /* Allocate memory for the array descriptor and data contiguously */ 725 if( FAILED( psa = HeapAlloc( GetProcessHeap(), 726 HEAP_ZERO_MEMORY, 726 if( FAILED( psa = HeapAlloc( GetProcessHeap(), 727 HEAP_ZERO_MEMORY, 727 728 (sizeof(*psa) + (VARTYPE_SIZE[vt] * cElements))))) { 728 729 return NULL; 729 730 } 730 731 /* setup data members... */ 731 732 /* setup data members... */ 732 733 psa->cDims = 1; /* always and forever */ 733 734 psa->fFeatures = getFeatures(vt) | FADF_CREATEVECTOR; /* undocumented flag used by Microsoft */ … … 739 740 psa->rgsabound[0].lLbound = lLbound; 740 741 741 return(psa); 742 } 743 744 /************************************************************************ 745 * 742 return(psa); 743 } 744 745 /************************************************************************ 746 * SafeArrayRedim 746 747 * Changes the caracteristics of the last dimension of the SafeArray 747 748 */ 748 749 HRESULT WINAPI SafeArrayRedim( 749 SAFEARRAY *psa, 750 SAFEARRAY *psa, 750 751 SAFEARRAYBOUND *psaboundNew) 751 { 752 { 752 753 LONG lDelta; /* hold difference in size */ 753 754 USHORT cDims=1; /* dims counter */ 754 755 755 if( !validArg(psa) ) 756 return E_INVALIDARG; 757 758 if( psa->cLocks > 0 ) 756 if( !validArg(psa) ) 757 return E_INVALIDARG; 758 759 if( psa->cLocks > 0 ) 759 760 return DISP_E_ARRAYISLOCKED; 760 761 761 if( psa->fFeatures & FADF_FIXEDSIZE ) 762 return E_INVALIDARG; 763 764 if( SafeArrayLock(psa)==E_UNEXPECTED ) 762 if( psa->fFeatures & FADF_FIXEDSIZE ) 763 return E_INVALIDARG; 764 765 if( SafeArrayLock(psa)==E_UNEXPECTED ) 765 766 return E_UNEXPECTED;/* UNDOC error condition */ 766 767 … … 774 775 775 776 } else /* need to enlarge (lDelta +) reduce (lDelta -) */ 776 if(! resizeSafeArray(psa, lDelta)) 777 if(! resizeSafeArray(psa, lDelta)) 777 778 return E_UNEXPECTED; /* UNDOC error condition */ 778 779 779 /* the only modifyable dimension sits in [0] as the dimensions were reversed 780 /* the only modifyable dimension sits in [0] as the dimensions were reversed 780 781 at array creation time... */ 781 782 psa->rgsabound[0].cElements = psaboundNew->cElements; … … 789 790 ************************************************************************/ 790 791 791 /************************************************************************ 792 /************************************************************************ 792 793 * Used to validate the SAFEARRAY type of arg 793 794 */ 794 795 static BOOL validArg( 795 SAFEARRAY *psa) 796 SAFEARRAY *psa) 796 797 { 797 798 SAFEARRAYBOUND *sab; … … 822 823 } 823 824 824 /************************************************************************ 825 /************************************************************************ 825 826 * Used to reallocate memory 826 827 */ 827 828 static BOOL resizeSafeArray( 828 SAFEARRAY *psa, 829 SAFEARRAY *psa, 829 830 LONG lDelta) 830 831 { 831 832 ULONG ulWholeArraySize; /* use as multiplicator */ 832 PVOID pvNewBlock = NULL; 833 PVOID pvNewBlock = NULL; 833 834 IUnknown *punk; 834 835 BSTR bstr; … … 838 839 if(lDelta < 0) { /* array needs to be shorthen */ 839 840 if( isPointer(psa->fFeatures)) /* ptr that need to be released */ 840 841 841 for(;lDelta < 0; lDelta++) { 842 punk = *(IUnknown**) 842 843 ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements)); 843 844 844 845 if( punk != NULL ) 845 846 IUnknown_Release(punk); 846 847 } 847 848 848 849 else if(psa->fFeatures & FADF_BSTR) /* BSTR that need to be freed */ 849 850 for(;lDelta < 0; lDelta++) { 850 851 bstr = *(BSTR*) 851 852 ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements)); … … 858 859 if (!(psa->fFeatures & FADF_CREATEVECTOR)) 859 860 { 860 /* Ok now, if we are enlarging the array, we *MUST* move the whole block 861 /* Ok now, if we are enlarging the array, we *MUST* move the whole block 861 862 pointed to by pvData. If we are shorthening the array, this move is 862 optional but we do it anyway becuase the benefit is that we are 863 optional but we do it anyway becuase the benefit is that we are 863 864 releasing to the system the unused memory */ 864 865 865 if((pvNewBlock = HeapReAlloc(GetProcessHeap(), 0, psa->pvData, 866 (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) 866 if((pvNewBlock = HeapReAlloc(GetProcessHeap(), 0, psa->pvData, 867 (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) 867 868 return FALSE; /* TODO If we get here it means: 868 869 SHRINK situation : we've deleted the undesired … … 873 874 else 874 875 { 875 /* Allocate a new block, because the previous data has been allocated with 876 /* Allocate a new block, because the previous data has been allocated with 876 877 the descriptor in SafeArrayCreateVector function. */ 877 878 878 879 if((pvNewBlock = HeapAlloc(GetProcessHeap(), 0, 879 ulWholeArraySize * psa->cbElements)) == NULL) 880 ulWholeArraySize * psa->cbElements)) == NULL) 880 881 return FALSE; 881 882 … … 887 888 } 888 889 889 /************************************************************************ 890 * Used to set the fFeatures data member of the SAFEARRAY structure. 890 /************************************************************************ 891 * Used to set the fFeatures data member of the SAFEARRAY structure. 891 892 */ 892 893 static INT getFeatures( 893 VARTYPE vt) 894 VARTYPE vt) 894 895 { 895 896 switch(vt) { … … 901 902 } 902 903 903 /************************************************************************ 904 * Used to figure out if the fFeatures data member of the SAFEARRAY 905 * structure contain any information about the type of data stored... 904 /************************************************************************ 905 * Used to figure out if the fFeatures data member of the SAFEARRAY 906 * structure contain any information about the type of data stored... 906 907 */ 907 908 static BOOL isPointer( 908 USHORT feature) 909 USHORT feature) 909 910 { 910 911 switch(feature) { … … 915 916 } 916 917 917 /************************************************************************ 918 * Used to calculate the displacement when accessing or modifying 918 /************************************************************************ 919 * Used to calculate the displacement when accessing or modifying 919 920 * safearray data set. 920 921 * … … 926 927 */ 927 928 static ULONG calcDisplacement( 928 LONG *coor, 929 SAFEARRAYBOUND *mat, 930 LONG dim) 929 LONG *coor, 930 SAFEARRAYBOUND *mat, 931 LONG dim) 931 932 { 932 933 ULONG res = 0; 933 934 LONG iterDim; 934 935 935 for(iterDim=0; iterDim<dim; iterDim++) 936 for(iterDim=0; iterDim<dim; iterDim++) 936 937 /* the -mat[dim] bring coor[dim] relative to 0 for calculation */ 937 res += ((coor[iterDim]-mat[iterDim].lLbound) * 938 res += ((coor[iterDim]-mat[iterDim].lLbound) * 938 939 endOfDim(coor, mat, iterDim+1, dim)); 939 940 … … 942 943 } 943 944 944 /************************************************************************ 945 * Recursivity agent for calcDisplacement method. Used within Put and 945 /************************************************************************ 946 * Recursivity agent for calcDisplacement method. Used within Put and 946 947 * Get methods. 947 948 */ 948 949 static INT endOfDim( 949 LONG *coor, 950 SAFEARRAYBOUND *mat, 951 LONG dim, 952 LONG realDim) 953 { 954 if(dim==realDim) 950 LONG *coor, 951 SAFEARRAYBOUND *mat, 952 LONG dim, 953 LONG realDim) 954 { 955 if(dim==realDim) 955 956 return 1; 956 else 957 else 957 958 return (endOfDim(coor, mat, dim+1, realDim) * mat[dim].cElements); 958 959 } 959 960 960 961 961 /************************************************************************ 962 * Method used to validate the coordinate received in Put and Get 962 /************************************************************************ 963 * Method used to validate the coordinate received in Put and Get 963 964 * methods. 964 965 */ 965 966 static BOOL validCoordinate( 966 LONG *coor, 967 SAFEARRAY *psa) 967 LONG *coor, 968 SAFEARRAY *psa) 968 969 { 969 970 INT iter=0; … … 977 978 if((hRes = SafeArrayGetUBound(psa, iter, &lUBound)) != S_OK) 978 979 return FALSE; 979 980 if(lLBound == lUBound) 981 return FALSE; 982 980 981 if(lLBound == lUBound) 982 return FALSE; 983 983 984 if((coor[iter] >= lLBound) && (coor[iter] <= lUBound)) 984 985 return TRUE; … … 987 988 } 988 989 return FALSE; 989 } 990 991 /************************************************************************ 990 } 991 992 /************************************************************************ 992 993 * Method used to calculate the number of cells of the SA 993 994 */ 994 995 static ULONG getArraySize( 995 SAFEARRAY *psa) 996 { 997 USHORT cCount; 996 SAFEARRAY *psa) 997 { 998 USHORT cCount; 998 999 ULONG ulWholeArraySize = 1; 999 1000 … … 1001 1002 ulWholeArraySize *= psa->rgsabound[cCount].cElements; 1002 1003 1003 return ulWholeArraySize; 1004 } 1005 1006 1007 /************************************************************************ 1004 return ulWholeArraySize; 1005 } 1006 1007 1008 /************************************************************************ 1008 1009 * Method used to handle data space dupplication for Copy32 and CopyData32 1009 1010 */ 1010 1011 static HRESULT duplicateData( 1011 SAFEARRAY *psa, 1012 SAFEARRAY **ppsaOut) 1012 SAFEARRAY *psa, 1013 SAFEARRAY **ppsaOut) 1013 1014 { 1014 1015 ULONG ulWholeArraySize; /* size of the thing */ … … 1018 1019 1019 1020 ulWholeArraySize = getArraySize(psa); /* Number of item in SA */ 1020 1021 1021 1022 SafeArrayLock(*ppsaOut); 1022 1023 1023 if( isPointer(psa->fFeatures) ) { /* If datatype is object increment 1024 if( isPointer(psa->fFeatures) ) { /* If datatype is object increment 1024 1025 object's reference count */ 1025 1026 … … 1032 1033 1033 1034 /* Copy the source array data into target array */ 1034 memcpy((*ppsaOut)->pvData, psa->pvData, 1035 memcpy((*ppsaOut)->pvData, psa->pvData, 1035 1036 ulWholeArraySize*psa->cbElements); 1036 1037 1037 } else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 1038 } else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 1038 1039 the BSTR in the new array */ 1039 1040 … … 1046 1047 } 1047 1048 1048 *((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) = 1049 *((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) = 1049 1050 pbstrReAllocStr; 1050 1051 } … … 1052 1053 } else { /* Simply copy the source array data into target array */ 1053 1054 1054 memcpy((*ppsaOut)->pvData, psa->pvData, 1055 memcpy((*ppsaOut)->pvData, psa->pvData, 1055 1056 ulWholeArraySize*psa->cbElements); 1056 1057 } … … 1062 1063 1063 1064 1064 /************************************************************************ 1065 * 1065 /************************************************************************ 1066 * SafeArrayGetVarType 1066 1067 * Returns the VARTYPE stored in the given safearray 1067 1068 */ … … 1099 1100 hr = S_OK; 1100 1101 } 1101 1102 1102 1103 TRACE("HRESULT = %08lx", hr); 1103 1104 return hr; 
  Note:
 See   TracChangeset
 for help on using the changeset viewer.
  
