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