Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4fcd6d0f
Commit
4fcd6d0f
authored
Jan 24, 1999
by
Sylvain St.Germain
Committed by
Alexandre Julliard
Jan 24, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementation of the SafeArray family functions.
parent
c66f5d59
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1111 additions
and
18 deletions
+1111
-18
oleauto.h
include/oleauto.h
+119
-0
winerror.h
include/winerror.h
+3
-0
Makefile.in
ole/Makefile.in
+1
-0
safearray.c
ole/safearray.c
+970
-0
oleaut32.spec
relay32/oleaut32.spec
+18
-18
No files found.
include/oleauto.h
View file @
4fcd6d0f
...
...
@@ -26,6 +26,125 @@ int WINAPI SysStringLen32(BSTR32);
typedef
void
ITypeLib
;
typedef
ITypeLib
*
LPTYPELIB
;
/*****************************************************************
* SafeArray defines and structs
*/
#define FADF_AUTO ( 0x1 )
#define FADF_STATIC ( 0x2 )
#define FADF_EMBEDDED ( 0x4 )
#define FADF_FIXEDSIZE ( 0x10 )
#define FADF_BSTR ( 0x100 )
#define FADF_UNKNOWN ( 0x200 )
#define FADF_DISPATCH ( 0x400 )
#define FADF_VARIANT ( 0x800 )
#define FADF_RESERVED ( 0xf0e8 )
typedef
struct
tagSAFEARRAYBOUND
{
ULONG
cElements
;
/* Number of elements in dimension */
LONG
lLbound
;
/* Lower bound of dimension */
}
SAFEARRAYBOUND
;
typedef
struct
tagSAFEARRAY
{
USHORT
cDims
;
/* Count of array dimension */
USHORT
fFeatures
;
/* Flags describing the array */
ULONG
cbElements
;
/* Size of each element */
ULONG
cLocks
;
/* Number of lock on array */
PVOID
pvData
;
/* Pointer to data valid when cLocks > 0 */
SAFEARRAYBOUND
rgsabound
[
1
];
/* One bound for each dimension */
}
SAFEARRAY
;
/*****************************************************************
* SafeArray API
*/
HRESULT
WINAPI
SafeArrayAllocDescriptor32
(
UINT32
cDims
,
SAFEARRAY
**
ppsaOut
);
#define SafeArrayAllocDescriptor WINELIB_NAME(SafeArrayAllocDescriptor)
HRESULT
WINAPI
SafeArrayAllocData32
(
SAFEARRAY
*
psa
);
#define SafeArrayAllocData WINELIB_NAME(SafeArrayAllocData)
SAFEARRAY
*
WINAPI
SafeArrayCreate32
(
VARTYPE
vt
,
UINT32
cDims
,
SAFEARRAYBOUND
*
rgsabound
);
#define SafeArrayCreate WINELIB_NAME(SafeArrayCreate)
HRESULT
WINAPI
SafeArrayDestroyDescriptor32
(
SAFEARRAY
*
psa
);
#define SafeArrayDestroyDescriptor WINELIB_NAME(SafeArrayDestroyDescriptor)
HRESULT
WINAPI
SafeArrayPutElement32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
*
pv
);
#define SafeArrayPutElement WINELIB_NAME(SafeArrayPutElement)
HRESULT
WINAPI
SafeArrayGetElement32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
*
pv
);
#define SafeArrayGetElement WINELIB_NAME(SafeArrayGetElement)
HRESULT
WINAPI
SafeArrayLock32
(
SAFEARRAY
*
psa
);
#define SafeArrayLock WINELIB_NAME(SafeArrayLock)
HRESULT
WINAPI
SafeArrayUnlock32
(
SAFEARRAY
*
psa
);
#define SafeArrayUnlock WINELIB_NAME(SafeArrayUnlock)
HRESULT
WINAPI
SafeArrayGetUBound32
(
SAFEARRAY
*
psa
,
UINT32
nDim
,
LONG
*
plUbound
);
#define SafeArrayGetUBound WINELIB_NAME(SafeArrayGetUBound)
HRESULT
WINAPI
SafeArrayGetLBound32
(
SAFEARRAY
*
psa
,
UINT32
nDim
,
LONG
*
plLbound
);
#define SafeArrayGetLBound WINELIB_NAME(SafeArrayGetLBound)
UINT32
WINAPI
SafeArrayGetDim32
(
SAFEARRAY
*
psa
);
#define SafeArrayGetDim WINELIB_NAME(SafeArrayGetDim)
UINT32
WINAPI
SafeArrayGetElemsize32
(
SAFEARRAY
*
psa
);
#define SafeArrayGetElemsize WINELIB_NAME(SafeArrayGetElemsize)
HRESULT
WINAPI
SafeArrayAccessData32
(
SAFEARRAY
*
psa
,
void
**
ppvData
);
#define SafeArrayAccessData WINELIB_NAME(SafeArrayAccessData)
HRESULT
WINAPI
SafeArrayUnaccessData32
(
SAFEARRAY
*
psa
);
#define SafeArrayUnaccessData WINELIB_NAME(SafeArrayUnaccessData)
HRESULT
WINAPI
SafeArrayPtrOfIndex32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
**
ppvData
);
#define SafeArrayPtrOfIndex WINELIB_NAME(SafeArrayPtrOfIndex)
HRESULT
WINAPI
SafeArrayCopyData32
(
SAFEARRAY
*
psaSource
,
SAFEARRAY
**
psaTarget
);
#define SafeArrayCopyData WINELIB_NAME(SafeArrayCopyData)
HRESULT
WINAPI
SafeArrayDestroyData32
(
SAFEARRAY
*
psa
);
#define SafeArrayDestroyData WINELIB_NAME(SafeArrayDestroyData)
HRESULT
WINAPI
SafeArrayDestroy32
(
SAFEARRAY
*
psa
);
#define SafeArrayDestroy WINELIB_NAME(SafeArrayDestroy)
HRESULT
WINAPI
SafeArrayCopy32
(
SAFEARRAY
*
psa
,
SAFEARRAY
**
ppsaOut
);
#define SafeArrayCopy WINELIB_NAME(SafeArrayCopy)
SAFEARRAY
*
WINAPI
SafeArrayCreateVector32
(
VARTYPE
vt
,
LONG
lLbound
,
ULONG
cElements
);
#define SafeArrayCreateVector WINELIB_NAME(SafeArrayCreateVector)
HRESULT
WINAPI
SafeArrayRedim32
(
SAFEARRAY
*
psa
,
SAFEARRAYBOUND
*
psaboundNew
);
#define SafeArrayRedim WINELIB_NAME(SafeArrayRedim)
/*
* Data types for Variants.
...
...
include/winerror.h
View file @
4fcd6d0f
...
...
@@ -152,6 +152,9 @@ extern int WIN32_LastError;
#define DISP_E_BADVARTYPE 0x80020008L
#define DISP_E_OVERFLOW 0x8002000AL
#define DISP_E_TYPEMISMATCH 0x80020005L
#define DISP_E_ARRAYISLOCKED 0x8002000D
#define DISP_E_BADINDEX 0x8002000B
/* Drag and Drop */
...
...
ole/Makefile.in
View file @
4fcd6d0f
...
...
@@ -18,6 +18,7 @@ C_SRCS = \
oleobj.c
\
olesvr.c
\
parsedt.c
\
safearray.c
\
storage.c
\
typelib.c
\
variant.c
...
...
ole/safearray.c
0 → 100644
View file @
4fcd6d0f
/*************************************************************************
* OLE Automation
* SafeArray Implementation
*
* This file contains the implementation of the SafeArray interface.
*
* Copyright 1999 Sylvain St-Germain
*/
#include <wintypes.h>
#include <winerror.h>
#include <winnt.h>
#include <oleauto.h>
#include <ole.h>
#include <strings.h>
#include <stdio.h>
#include <debug.h>
#include <interfaces.h>
/* Localy used methods */
static
INT32
endOfDim
(
LONG
*
coor
,
SAFEARRAYBOUND
*
mat
,
LONG
dim
,
LONG
realDim
);
static
ULONG
calcDisplacement
(
LONG
*
coor
,
SAFEARRAYBOUND
*
mat
,
LONG
dim
);
static
BOOL32
isPointer
(
USHORT
feature
);
static
INT32
getFeatures
(
VARTYPE
vt
);
static
BOOL32
validCoordinate
(
LONG
*
coor
,
SAFEARRAY
*
psa
);
static
BOOL32
resizeSafeArray
(
SAFEARRAY
*
psa
,
LONG
lDelta
);
static
BOOL32
validArg
(
SAFEARRAY
*
psa
);
static
ULONG
getArraySize
(
SAFEARRAY
*
psa
);
static
HRESULT
duplicateData
(
SAFEARRAY
*
psa
,
SAFEARRAY
**
ppsaOut
);
/* Association between VARTYPE and their size.
A size of zero is defined for the unsupported types. */
#define VARTYPE_NOT_SUPPORTED 0
static
ULONG
VARTYPE_SIZE
[
43
]
=
{
/* 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 */
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 * */
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 */
VARTYPE_NOT_SUPPORTED
,
/* VT_I1 [T] signed 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 */
VARTYPE_NOT_SUPPORTED
,
/* VT_UI8 [T][P] unsigned 64-bit int */
VARTYPE_NOT_SUPPORTED
,
/* VT_INT [T] signed machine int */
VARTYPE_NOT_SUPPORTED
,
/* VT_UINT [T] unsigned machine int */
VARTYPE_NOT_SUPPORTED
,
/* VT_VOID [T] C style void */
VARTYPE_NOT_SUPPORTED
,
/* VT_HRESULT [T] Standard return type */
VARTYPE_NOT_SUPPORTED
,
/* VT_PTR [T] pointer type */
VARTYPE_NOT_SUPPORTED
,
/* VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT)*/
VARTYPE_NOT_SUPPORTED
,
/* VT_CARRAY [T] C style array */
VARTYPE_NOT_SUPPORTED
,
/* VT_USERDEFINED [T] user defined type */
VARTYPE_NOT_SUPPORTED
,
/* VT_LPSTR [T][P] null terminated string */
VARTYPE_NOT_SUPPORTED
,
/* VT_LPWSTR [T][P] wide null term string */
VARTYPE_NOT_SUPPORTED
,
/* VT_FILETIME [P] FILETIME */
VARTYPE_NOT_SUPPORTED
,
/* VT_BLOB [P] Length prefixed bytes */
VARTYPE_NOT_SUPPORTED
,
/* VT_STREAM [P] Name of stream follows */
VARTYPE_NOT_SUPPORTED
,
/* VT_STORAGE [P] Name of storage follows */
VARTYPE_NOT_SUPPORTED
,
/* VT_STREAMED_OBJECT[P] Stream contains an object*/
VARTYPE_NOT_SUPPORTED
,
/* VT_STORED_OBJECT [P] Storage contains object*/
VARTYPE_NOT_SUPPORTED
,
/* VT_BLOB_OBJECT [P] Blob contains an object*/
VARTYPE_NOT_SUPPORTED
,
/* VT_CF [P] Clipboard format */
VARTYPE_NOT_SUPPORTED
,
/* VT_CLSID [P] A Class ID */
VARTYPE_NOT_SUPPORTED
,
/* VT_VECTOR [P] simple counted array */
VARTYPE_NOT_SUPPORTED
,
/* VT_ARRAY [V] SAFEARRAY* */
VARTYPE_NOT_SUPPORTED
/* VT_BYREF [V] void* for local use */
};
/*************************************************************************
* Allocate the appropriate amount of memory for the SafeArray descriptor
*/
HRESULT
WINAPI
SafeArrayAllocDescriptor32
(
UINT32
cDims
,
SAFEARRAY
**
ppsaOut
)
{
SAFEARRAYBOUND
*
sab
;
LONG
allocSize
=
0
;
/* SAFEARRAY + SAFEARRAYBOUND * (cDims -1) ( -1 because there is already one
( in SAFEARRAY struct */
allocSize
=
sizeof
(
**
ppsaOut
)
+
(
sizeof
(
*
sab
)
*
(
cDims
-
1
));
/* Allocate memory for SAFEARRAY struc */
if
((
(
*
ppsaOut
)
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
allocSize
))
==
NULL
){
return
(
E_UNEXPECTED
);
}
TRACE
(
ole
,
"SafeArray: %lu bytes allocated for descriptor.
\n
"
,
allocSize
);
return
(
S_OK
);
}
/*************************************************************************
* Allocate the appropriate amount of data for the SafeArray data
*/
HRESULT
WINAPI
SafeArrayAllocData32
(
SAFEARRAY
*
psa
)
{
ULONG
ulWholeArraySize
;
/* to store the size of the whole thing */
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
ulWholeArraySize
=
getArraySize
(
psa
);
/* Allocate memory for the data itself */
if
((
psa
->
pvData
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
psa
->
cbElements
*
ulWholeArraySize
))
==
NULL
)
return
(
E_UNEXPECTED
);
TRACE
(
ole
,
"SafeArray: %lu bytes allocated for data at %p (%lu objects).
\n
"
,
psa
->
cbElements
*
ulWholeArraySize
,
psa
->
pvData
,
ulWholeArraySize
);
return
(
S_OK
);
}
/*************************************************************************
* Create a SafeArray object by encapsulating AllocDescriptor and AllocData
*/
SAFEARRAY
*
WINAPI
SafeArrayCreate32
(
VARTYPE
vt
,
UINT32
cDims
,
SAFEARRAYBOUND
*
rgsabound
)
{
SAFEARRAY
*
psa
;
HRESULT
hRes
;
USHORT
cDim
;
/* Validate supported VARTYPE */
if
(
VARTYPE_SIZE
[
vt
]
==
VARTYPE_NOT_SUPPORTED
)
return
NULL
;
/* Allocate memory for the array descriptor */
if
(
FAILED
(
hRes
=
SafeArrayAllocDescriptor32
(
cDims
,
&
psa
)))
return
NULL
;
/* setup data members... */
psa
->
cDims
=
cDims
;
psa
->
fFeatures
=
getFeatures
(
vt
);
psa
->
cLocks
=
0
;
psa
->
pvData
=
NULL
;
psa
->
cbElements
=
VARTYPE_SIZE
[
vt
];
/* Invert the bounds ... */
for
(
cDim
=
0
;
cDim
<
psa
->
cDims
;
cDim
++
)
{
psa
->
rgsabound
[
cDim
].
cElements
=
rgsabound
[
psa
->
cDims
-
cDim
-
1
].
cElements
;
psa
->
rgsabound
[
cDim
].
lLbound
=
rgsabound
[
psa
->
cDims
-
cDim
-
1
].
lLbound
;
}
/* allocate memory for the data... */
if
(
FAILED
(
hRes
=
SafeArrayAllocData32
(
psa
)))
{
SafeArrayDestroyDescriptor32
(
psa
);
return
NULL
;
}
return
(
psa
);
}
/*************************************************************************
* Frees the memory associated with the descriptor.
*/
HRESULT
WINAPI
SafeArrayDestroyDescriptor32
(
SAFEARRAY
*
psa
)
{
/* Check for lockness before to free... */
if
(
psa
->
cLocks
>
0
)
return
DISP_E_ARRAYISLOCKED
;
/* The array is unlocked, then, deallocate memory */
if
(
HeapFree
(
GetProcessHeap
(),
0
,
psa
)
==
FALSE
)
return
E_UNEXPECTED
;
return
(
S_OK
);
}
/*************************************************************************
* Increment the lock counter
*
* Doc says (MSDN Library ) that psa->pvData should be made available (!= NULL)
* only when psa->cLocks is > 0... I don't get it since pvData is allocated
* before the array is locked, therefore
*/
HRESULT
WINAPI
SafeArrayLock32
(
SAFEARRAY
*
psa
)
{
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
psa
->
cLocks
++
;
return
(
S_OK
);
}
/*************************************************************************
* Decrement the lock counter
*/
HRESULT
WINAPI
SafeArrayUnlock32
(
SAFEARRAY
*
psa
)
{
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
psa
->
cLocks
>
0
)
psa
->
cLocks
--
;
return
(
S_OK
);
}
/*************************************************************************
* Set the data at the given coordinate
*/
HRESULT
WINAPI
SafeArrayPutElement32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
*
pv
)
{
ULONG
stepCountInSAData
=
0
;
/* Number of array item to skip to get to
the desired one... */
PVOID
elementStorageAddress
=
NULL
;
/* Adress to store the data */
BSTR32
pbstrReAllocStr
=
NULL
;
/* BSTR reallocated */
/* Validate the index given */
if
(
!
validCoordinate
(
rgIndices
,
psa
))
return
DISP_E_BADINDEX
;
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
SafeArrayLock32
(
psa
)
==
S_OK
)
{
/* Figure out the number of items to skip */
stepCountInSAData
=
calcDisplacement
(
rgIndices
,
psa
->
rgsabound
,
psa
->
cDims
);
/* Figure out the number of byte to skip ... */
elementStorageAddress
=
psa
->
pvData
+
(
stepCountInSAData
*
psa
->
cbElements
);
if
(
isPointer
(
psa
->
fFeatures
))
{
/* increment ref count for this pointer */
*
((
VOID
**
)
elementStorageAddress
)
=
*
(
VOID
**
)
pv
;
IUnknown_AddRef
(
*
(
IUnknown
**
)
pv
);
}
else
{
if
(
psa
->
fFeatures
==
FADF_BSTR
)
{
/* Create a new object */
if
((
pbstrReAllocStr
=
SysAllocString32
(
(
OLECHAR32
*
)
pv
))
==
NULL
)
{
SafeArrayUnlock32
(
psa
);
return
E_OUTOFMEMORY
;
}
else
*
((
BSTR32
*
)
elementStorageAddress
)
=
pbstrReAllocStr
;
}
else
/* dupplicate the memory */
memcpy
(
elementStorageAddress
,
pv
,
SafeArrayGetElemsize32
(
psa
)
);
}
}
else
{
ERR
(
ole
,
"SafeArray: Cannot lock array....
\n
"
);
return
E_UNEXPECTED
;
/* UNDOC error condition */
}
TRACE
(
ole
,
"SafeArray: item put at adress %p.
\n
"
,
elementStorageAddress
);
return
SafeArrayUnlock32
(
psa
);
}
/*************************************************************************
* Return the data element corresponding the the given coordinate
*/
HRESULT
WINAPI
SafeArrayGetElement32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
*
pv
)
{
ULONG
stepCountInSAData
=
0
;
/* Number of array item to skip to get to
the desired one... */
PVOID
elementStorageAddress
=
NULL
;
/* Adress to store the data */
BSTR32
pbstrReturnedStr
=
NULL
;
/* BSTR reallocated */
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
!
validCoordinate
(
rgIndices
,
psa
))
/* Validate the index given */
return
(
DISP_E_BADINDEX
);
if
(
SafeArrayLock32
(
psa
)
==
S_OK
)
{
/* Figure out the number of items to skip */
stepCountInSAData
=
calcDisplacement
(
rgIndices
,
psa
->
rgsabound
,
psa
->
cDims
);
/* Figure out the number of byte to skip ... */
elementStorageAddress
=
psa
->
pvData
+
(
stepCountInSAData
*
psa
->
cbElements
);
if
(
psa
->
fFeatures
==
FADF_BSTR
)
{
/* reallocate the obj */
if
(
(
pbstrReturnedStr
=
SysAllocString32
(
*
(
OLECHAR32
**
)
elementStorageAddress
))
==
NULL
)
{
SafeArrayUnlock32
(
psa
);
return
E_OUTOFMEMORY
;
}
else
*
((
BSTR32
*
)
pv
)
=
pbstrReturnedStr
;
}
else
if
(
isPointer
(
psa
->
fFeatures
)
)
/* simply copy the pointer */
pv
=
*
((
PVOID
*
)
elementStorageAddress
);
else
/* copy the bytes */
memcpy
(
pv
,
elementStorageAddress
,
SafeArrayGetElemsize32
(
psa
)
);
}
else
{
ERR
(
ole
,
"SafeArray: Cannot lock array....
\n
"
);
return
E_UNEXPECTED
;
/* UNDOC error condition */
}
return
(
SafeArrayUnlock32
(
psa
)
);
}
/*************************************************************************
* return the UP bound for a given array dimension
*/
HRESULT
WINAPI
SafeArrayGetUBound32
(
SAFEARRAY
*
psa
,
UINT32
nDim
,
LONG
*
plUbound
)
{
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
nDim
>
psa
->
cDims
)
return
DISP_E_BADINDEX
;
*
plUbound
=
psa
->
rgsabound
[
nDim
].
lLbound
+
psa
->
rgsabound
[
nDim
].
cElements
-
1
;
return
S_OK
;
}
/*************************************************************************
* Return the LO bound for a given array dimension
*/
HRESULT
WINAPI
SafeArrayGetLBound32
(
SAFEARRAY
*
psa
,
UINT32
nDim
,
LONG
*
plLbound
)
{
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
nDim
>
psa
->
cDims
)
return
DISP_E_BADINDEX
;
*
plLbound
=
psa
->
rgsabound
[
nDim
].
lLbound
;
return
S_OK
;
}
/*************************************************************************
* returns the number of dimension in the array
*/
UINT32
WINAPI
SafeArrayGetDim32
(
SAFEARRAY
*
psa
)
{
return
psa
->
cDims
;
}
/*************************************************************************
* Return the size of the element in the array
*/
UINT32
WINAPI
SafeArrayGetElemsize32
(
SAFEARRAY
*
psa
)
{
return
psa
->
cbElements
;
}
/*************************************************************************
* increment the access count and return the data
*/
HRESULT
WINAPI
SafeArrayAccessData32
(
SAFEARRAY
*
psa
,
void
**
ppvData
)
{
HRESULT
hRes
;
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
hRes
=
SafeArrayLock32
(
psa
);
switch
(
hRes
)
{
case
S_OK
:
(
*
ppvData
)
=
psa
->
pvData
;
break
;
case
E_INVALIDARG
:
(
*
ppvData
)
=
NULL
;
return
E_INVALIDARG
;
}
return
S_OK
;
}
/*************************************************************************
* Decrement the access count
*/
HRESULT
WINAPI
SafeArrayUnaccessData32
(
SAFEARRAY
*
psa
)
{
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
return
(
SafeArrayUnlock32
(
psa
));
}
/************************************************************************
* Return a pointer to the element at rgIndices
*/
HRESULT
WINAPI
SafeArrayPtrOfIndex32
(
SAFEARRAY
*
psa
,
LONG
*
rgIndices
,
void
**
ppvData
)
{
ULONG
stepCountInSAData
=
0
;
/* Number of array item to skip to get to
the desired one... */
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
!
validCoordinate
(
rgIndices
,
psa
))
return
DISP_E_BADINDEX
;
/* Figure out the number of items to skip */
stepCountInSAData
=
calcDisplacement
(
rgIndices
,
psa
->
rgsabound
,
psa
->
cDims
);
*
ppvData
=
psa
->
pvData
+
(
stepCountInSAData
*
psa
->
cbElements
);
return
S_OK
;
}
/************************************************************************
* Frees the memory data bloc
*/
HRESULT
WINAPI
SafeArrayDestroyData32
(
SAFEARRAY
*
psa
)
{
HRESULT
hRes
;
ULONG
ulWholeArraySize
;
/* count spot in array */
ULONG
ulDataIter
;
/* to iterate the data space */
IUnknown
*
punk
;
BSTR32
bstr
;
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
psa
->
cLocks
>
0
)
return
DISP_E_ARRAYISLOCKED
;
ulWholeArraySize
=
getArraySize
(
psa
);
if
(
isPointer
(
psa
->
fFeatures
))
{
/* release the pointers */
for
(
ulDataIter
=
0
;
ulDataIter
<
ulWholeArraySize
;
ulDataIter
++
)
{
punk
=
*
(
IUnknown
**
)(
psa
->
pvData
+
(
ulDataIter
*
(
psa
->
cbElements
)));
if
(
punk
!=
NULL
)
IUnknown_Release
(
punk
);
}
}
else
if
(
psa
->
fFeatures
&
FADF_BSTR
)
{
/* deallocate the obj */
for
(
ulDataIter
=
0
;
ulDataIter
<
ulWholeArraySize
;
ulDataIter
++
)
{
bstr
=
*
(
BSTR32
*
)(
psa
->
pvData
+
(
ulDataIter
*
(
psa
->
cbElements
)));
if
(
bstr
!=
NULL
)
SysFreeString32
(
bstr
);
}
}
/* 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
deserve to be freed by DestroyDescriptor */
if
(
!
(
psa
->
fFeatures
&
FADF_FIXEDSIZE
))
{
/* Set when we do CreateVector */
/* free the whole chunk */
if
((
hRes
=
HeapFree
(
GetProcessHeap
(),
0
,
psa
->
pvData
))
==
0
)
/*falied*/
return
E_UNEXPECTED
;
/* UNDOC error condition */
psa
->
pvData
=
NULL
;
}
return
S_OK
;
}
/************************************************************************
* Copy the psaSource's data block into psaTarget if dimension and size
* permits it.
*/
HRESULT
WINAPI
SafeArrayCopyData32
(
SAFEARRAY
*
psaSource
,
SAFEARRAY
**
psaTarget
)
{
USHORT
cDimCount
;
/* looper */
LONG
lDelta
;
/* looper */
IUnknown
*
punk
;
ULONG
ulWholeArraySize
;
/* Number of item in SA */
BSTR32
bstr
;
if
(
!
(
validArg
(
psaSource
)
&&
validArg
(
*
psaTarget
))
)
return
E_INVALIDARG
;
if
(
SafeArrayGetDim32
(
psaSource
)
!=
SafeArrayGetDim32
(
*
psaTarget
))
return
E_INVALIDARG
;
ulWholeArraySize
=
getArraySize
(
psaSource
);
/* The two arrays boundaries must be of same lenght */
for
(
cDimCount
=
0
;
cDimCount
<
psaSource
->
cDims
;
cDimCount
++
)
if
(
psaSource
->
rgsabound
[
cDimCount
].
cElements
!=
(
*
psaTarget
)
->
rgsabound
[
cDimCount
].
cElements
)
return
E_INVALIDARG
;
if
(
isPointer
((
*
psaTarget
)
->
fFeatures
)
)
{
/* the target contains ptr
that must be released */
for
(
lDelta
=
0
;
lDelta
<
ulWholeArraySize
;
lDelta
++
)
{
punk
=
*
(
IUnknown
**
)
((
*
psaTarget
)
->
pvData
+
(
lDelta
*
(
*
psaTarget
)
->
cbElements
));
if
(
punk
!=
NULL
)
IUnknown_Release
(
punk
);
}
}
else
if
(
(
*
psaTarget
)
->
fFeatures
&
FADF_BSTR
)
{
/* the target contain BSTR
that must be freed */
for
(
lDelta
=
0
;
lDelta
<
ulWholeArraySize
;
lDelta
++
)
{
bstr
=
*
(
BSTR32
*
)((
*
psaTarget
)
->
pvData
+
(
lDelta
*
(
*
psaTarget
)
->
cbElements
));
if
(
bstr
!=
NULL
)
SysFreeString32
(
bstr
);
}
}
return
duplicateData
(
psaSource
,
psaTarget
);
}
/************************************************************************
* Deallocates all memory reserved for the SafeArray
*/
HRESULT
WINAPI
SafeArrayDestroy32
(
SAFEARRAY
*
psa
)
{
HRESULT
hRes
;
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
(
psa
->
cLocks
>
0
)
return
DISP_E_ARRAYISLOCKED
;
if
((
hRes
=
SafeArrayDestroyData32
(
psa
))
==
S_OK
)
if
((
hRes
=
SafeArrayDestroyDescriptor32
(
psa
))
==
S_OK
)
return
S_OK
;
return
E_UNEXPECTED
;
/* UNDOC error condition */
}
/************************************************************************
* Make a dupplicate of a SafeArray
*/
HRESULT
WINAPI
SafeArrayCopy32
(
SAFEARRAY
*
psa
,
SAFEARRAY
**
ppsaOut
)
{
HRESULT
hRes
;
DWORD
dAllocSize
;
if
(
!
validArg
(
psa
))
return
E_INVALIDARG
;
if
((
hRes
=
SafeArrayAllocDescriptor32
(
psa
->
cDims
,
ppsaOut
))
==
S_OK
){
/* Duplicate the SAFEARRAY struc */
memcpy
(
*
ppsaOut
,
psa
,
sizeof
(
*
psa
)
+
(
sizeof
(
*
(
psa
->
rgsabound
))
*
(
psa
->
cDims
-
1
)));
(
*
ppsaOut
)
->
pvData
=
NULL
;
/* do not point to the same data area */
/* Get the allocated memory size for source and allocate it for target */
dAllocSize
=
HeapSize
(
GetProcessHeap
(),
0
,
psa
->
pvData
);
(
*
ppsaOut
)
->
pvData
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
dAllocSize
);
if
(
(
*
ppsaOut
)
->
pvData
!=
NULL
)
{
/* HeapAlloc succeed */
if
(
(
hRes
=
duplicateData
(
psa
,
ppsaOut
))
!=
S_OK
)
{
/* E_OUTOFMEMORY */
HeapFree
(
GetProcessHeap
(),
0
,
(
*
ppsaOut
)
->
pvData
);
(
*
ppsaOut
)
->
pvData
=
NULL
;
SafeArrayDestroyDescriptor32
(
*
ppsaOut
);
return
hRes
;
}
}
else
{
/* failed to allocate or dupplicate... */
SafeArrayDestroyDescriptor32
(
*
ppsaOut
);
return
E_UNEXPECTED
;
/* UNDOC error condition */
}
}
else
{
/* failed to allocate mem for descriptor */
return
E_OUTOFMEMORY
;
/* UNDOC error condiftion */
}
return
S_OK
;
}
/************************************************************************
* Creates a one dimension safearray where the data is next to the
* SAFEARRAY structure.
*/
SAFEARRAY
*
WINAPI
SafeArrayCreateVector32
(
VARTYPE
vt
,
LONG
lLbound
,
ULONG
cElements
)
{
SAFEARRAY
*
psa
;
/* Validate supported VARTYPE */
if
(
VARTYPE_SIZE
[
vt
]
==
VARTYPE_NOT_SUPPORTED
)
return
NULL
;
/* Allocate memory for the array descriptor and data contiguously */
if
(
FAILED
(
psa
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
(
sizeof
(
*
psa
)
+
(
VARTYPE_SIZE
[
vt
]
*
cElements
)))))
{
return
NULL
;
}
/* setup data members... */
psa
->
cDims
=
1
;
/* always and forever */
psa
->
fFeatures
=
getFeatures
(
vt
)
|
FADF_FIXEDSIZE
;
psa
->
cLocks
=
0
;
psa
->
pvData
=
psa
+
sizeof
(
*
psa
);
psa
->
cbElements
=
VARTYPE_SIZE
[
vt
];
psa
->
rgsabound
[
0
].
cElements
=
cElements
;
psa
->
rgsabound
[
0
].
lLbound
=
lLbound
;
return
(
psa
);
}
/************************************************************************
* Changes the caracteristics of the last dimension of the SafeArray
*/
HRESULT
WINAPI
SafeArrayRedim32
(
SAFEARRAY
*
psa
,
SAFEARRAYBOUND
*
psaboundNew
)
{
LONG
lDelta
;
/* hold difference in size */
USHORT
cDims
=
1
;
/* dims counter */
if
(
!
validArg
(
psa
)
)
return
E_INVALIDARG
;
if
(
psa
->
cLocks
>
0
)
return
DISP_E_ARRAYISLOCKED
;
if
(
psa
->
fFeatures
&
FADF_FIXEDSIZE
)
return
E_INVALIDARG
;
if
(
SafeArrayLock32
(
psa
)
==
E_UNEXPECTED
)
return
E_UNEXPECTED
;
/* UNDOC error condition */
/* find the delta in number of array spot to apply to the new array */
lDelta
=
psaboundNew
->
cElements
-
psa
->
rgsabound
[
0
].
cElements
;
for
(;
cDims
<
psa
->
cDims
;
cDims
++
)
/* delta in number of spot implied by modifying the last dimension */
lDelta
*=
psa
->
rgsabound
[
cDims
].
cElements
;
if
(
lDelta
==
0
)
{
;
/* same size, maybe a change of lLbound, just set it */
}
else
/* need to enlarge (lDelta +) reduce (lDelta -) */
if
(
!
resizeSafeArray
(
psa
,
lDelta
))
return
E_UNEXPECTED
;
/* UNDOC error condition */
/* the only modifyable dimension sits in [0] as the dimensions were reversed
at array creation time... */
psa
->
rgsabound
[
0
].
cElements
=
psaboundNew
->
cElements
;
psa
->
rgsabound
[
0
].
lLbound
=
psaboundNew
->
lLbound
;
return
SafeArrayUnlock32
(
psa
);
}
/************************************************************************
* NOT WINDOWS API - SafeArray* Utility functions
************************************************************************/
/************************************************************************
* Used to validate the SAFEARRAY type of arg
*/
static
BOOL32
validArg
(
SAFEARRAY
*
psa
)
{
SAFEARRAYBOUND
*
sab
;
LONG
psaSize
=
0
;
LONG
descSize
=
0
;
LONG
fullSize
=
0
;
/* Check whether the size of the chunk make sens... That's the only thing
I can think of now... */
psaSize
=
HeapSize
(
GetProcessHeap
(),
0
,
psa
);
/* size of the descriptor when the SA is not created with CreateVector */
descSize
=
sizeof
(
*
psa
)
+
(
sizeof
(
*
sab
)
*
(
psa
->
cDims
-
1
));
/* size of the descriptor + data when created with CreateVector */
fullSize
=
sizeof
(
*
psa
)
+
(
psa
->
cbElements
*
psa
->
rgsabound
[
0
].
cElements
);
return
((
psaSize
==
descSize
)
|
(
psaSize
==
fullSize
));
}
/************************************************************************
* Used to reallocate memory
*/
static
BOOL32
resizeSafeArray
(
SAFEARRAY
*
psa
,
LONG
lDelta
)
{
ULONG
ulWholeArraySize
;
/* use as multiplicator */
PVOID
pvNewBlock
=
NULL
;
IUnknown
*
punk
;
BSTR32
bstr
;
ulWholeArraySize
=
getArraySize
(
psa
);
if
(
lDelta
<
0
)
{
/* array needs to be shorthen */
if
(
isPointer
(
psa
->
fFeatures
))
/* ptr that need to be released */
for
(;
lDelta
<
0
;
lDelta
++
)
{
punk
=
*
(
IUnknown
**
)
(
psa
->
pvData
+
((
ulWholeArraySize
+
lDelta
)
*
psa
->
cbElements
));
if
(
punk
!=
NULL
)
IUnknown_Release
(
punk
);
}
else
if
(
psa
->
fFeatures
&
FADF_BSTR
)
/* BSTR that need to be freed */
for
(;
lDelta
<
0
;
lDelta
++
)
{
bstr
=
*
(
BSTR32
*
)
(
psa
->
pvData
+
((
ulWholeArraySize
+
lDelta
)
*
psa
->
cbElements
));
if
(
bstr
!=
NULL
)
SysFreeString32
(
bstr
);
}
}
/* Ok now, if we are enlarging the array, we *MUST* move the whole block
pointed to by pvData. If we are shorthening the array, this move is
optional but we do it anyway becuase the benefit is that we are
releasing to the system the unused memory */
if
((
pvNewBlock
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
psa
->
pvData
,
(
ulWholeArraySize
+
lDelta
)
*
psa
->
cbElements
))
==
NULL
)
return
FALSE
;
/* TODO If we get here it means:
SHRINK situation : we've deleted the undesired
data and did not release the memory
GROWING situation: we've been unable to grow the array
*/
/* reassign to the new block of data */
psa
->
pvData
=
pvNewBlock
;
return
TRUE
;
}
/************************************************************************
* Used to set the fFeatures data member of the SAFEARRAY structure.
*/
static
INT32
getFeatures
(
VARTYPE
vt
)
{
switch
(
vt
)
{
case
VT_UNKNOWN
:
return
FADF_UNKNOWN
;
case
VT_DISPATCH
:
return
FADF_DISPATCH
;
case
VT_BSTR
:
return
FADF_BSTR
;
}
return
0
;
}
/************************************************************************
* Used to figure out if the fFeatures data member of the SAFEARRAY
* structure contain any information about the type of data stored...
*/
static
BOOL32
isPointer
(
USHORT
feature
)
{
switch
(
feature
)
{
case
FADF_UNKNOWN
:
return
TRUE
;
/* those are pointers */
case
FADF_DISPATCH
:
return
TRUE
;
}
return
FALSE
;
}
/************************************************************************
* Used to calculate the displacement when accessing or modifying
* safearray data set.
*
* Parameters: - LONG *coor is the desired location in the multidimension
* table. Ex for a 3 dim table: coor[] = {1,2,3};
* - ULONG *mat is the format of the table. Ex for a 3 dim
* table mat[] = {4,4,4};
* - USHORT dim is the number of dimension of the SafeArray
*/
static
ULONG
calcDisplacement
(
LONG
*
coor
,
SAFEARRAYBOUND
*
mat
,
LONG
dim
)
{
ULONG
res
=
0
;
LONG
iterDim
;
for
(
iterDim
=
0
;
iterDim
<
dim
;
iterDim
++
)
/* the -mat[dim] bring coor[dim] relative to 0 for calculation */
res
+=
((
coor
[
iterDim
]
-
mat
[
iterDim
].
lLbound
)
*
endOfDim
(
coor
,
mat
,
iterDim
+
1
,
dim
));
TRACE
(
ole
,
"SafeArray: calculated displacement is %lu.
\n
"
,
res
);
return
(
res
);
}
/************************************************************************
* Recursivity agent for calcDisplacement method. Used within Put and
* Get methods.
*/
static
INT32
endOfDim
(
LONG
*
coor
,
SAFEARRAYBOUND
*
mat
,
LONG
dim
,
LONG
realDim
)
{
if
(
dim
==
realDim
)
return
1
;
else
return
(
endOfDim
(
coor
,
mat
,
dim
+
1
,
realDim
)
*
mat
[
dim
].
cElements
);
}
/************************************************************************
* Method used to validate the coordinate received in Put and Get
* methods.
*/
static
BOOL32
validCoordinate
(
LONG
*
coor
,
SAFEARRAY
*
psa
)
{
INT32
iter
=
0
;
LONG
lUBound
;
LONG
lLBound
;
HRESULT
hRes
;
for
(;
iter
<
psa
->
cDims
;
iter
++
)
{
if
((
hRes
=
SafeArrayGetLBound32
(
psa
,
iter
,
&
lLBound
))
!=
S_OK
)
return
FALSE
;
if
((
hRes
=
SafeArrayGetUBound32
(
psa
,
iter
,
&
lUBound
))
!=
S_OK
)
return
FALSE
;
if
(
lLBound
==
lUBound
)
return
FALSE
;
if
((
coor
[
iter
]
>=
lLBound
)
&&
(
coor
[
iter
]
<=
lUBound
))
return
TRUE
;
else
return
FALSE
;
}
return
FALSE
;
}
/************************************************************************
* Method used to calculate the number of cells of the SA
*/
static
ULONG
getArraySize
(
SAFEARRAY
*
psa
)
{
USHORT
cCount
;
ULONG
ulWholeArraySize
=
1
;
for
(
cCount
=
0
;
cCount
<
psa
->
cDims
;
cCount
++
)
/* foreach dimensions... */
ulWholeArraySize
*=
psa
->
rgsabound
[
cCount
].
cElements
;
return
ulWholeArraySize
;
}
/************************************************************************
* Method used to handle data space dupplication for Copy32 and CopyData32
*/
static
HRESULT
duplicateData
(
SAFEARRAY
*
psa
,
SAFEARRAY
**
ppsaOut
)
{
ULONG
ulWholeArraySize
;
/* size of the thing */
LONG
lDelta
;
IUnknown
*
punk
;
BSTR32
pbstrReAllocStr
=
NULL
;
/* BSTR reallocated */
ulWholeArraySize
=
getArraySize
(
psa
);
/* Number of item in SA */
SafeArrayLock32
(
*
ppsaOut
);
if
(
isPointer
(
psa
->
fFeatures
)
)
{
/* If datatype is object increment
object's reference count */
for
(
lDelta
=
0
;
lDelta
<
ulWholeArraySize
;
lDelta
++
)
{
punk
=
*
(
IUnknown
**
)(
psa
->
pvData
+
(
lDelta
*
psa
->
cbElements
));
if
(
punk
!=
NULL
)
IUnknown_AddRef
(
punk
);
}
/* Copy the source array data into target array */
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 */
for
(
lDelta
=
0
;
lDelta
<
ulWholeArraySize
;
lDelta
++
)
{
if
((
pbstrReAllocStr
=
SysAllocString32
(
*
(
BSTR32
*
)(
psa
->
pvData
+
(
lDelta
*
psa
->
cbElements
))))
==
NULL
)
{
SafeArrayUnlock32
(
*
ppsaOut
);
return
E_OUTOFMEMORY
;
}
*
((
BSTR32
*
)((
*
ppsaOut
)
->
pvData
+
(
lDelta
*
psa
->
cbElements
)))
=
pbstrReAllocStr
;
}
}
else
{
/* Simply copy the source array data into target array */
memcpy
((
*
ppsaOut
)
->
pvData
,
psa
->
pvData
,
ulWholeArraySize
*
psa
->
cbElements
);
}
SafeArrayUnlock32
(
*
ppsaOut
);
return
S_OK
;
}
relay32/oleaut32.spec
View file @
4fcd6d0f
...
...
@@ -15,19 +15,19 @@ type win32
12 stdcall VariantChangeType(ptr ptr) VariantChangeType32
13 stub VariantTimeToDosDateTime
14 stub DosDateTimeToVariantTime
15 st
ub SafeArrayCreate
16 st
ub SafeArrayDestroy
17 st
ub SafeArrayGetDim
18 st
ub SafeArrayGetElemsize
19 st
ub SafeArrayGetUBound
20 st
ub SafeArrayGetLBound
21 st
ub SafeArrayLock
22 st
ub SafeArrayUnlock
23 st
ub SafeArrayAccessData
24 st
ub SafeArrayUnaccessData
25 st
ub SafeArrayGetElement
26 st
ub SafeArrayPutElement
27 st
ub SafeArrayCopy
15 st
dcall SafeArrayCreate(long long ptr) SafeArrayCreate32
16 st
dcall SafeArrayDestroy(ptr) SafeArrayDestroy32
17 st
dcall SafeArrayGetDim(ptr) SafeArrayGetDim32
18 st
dcall SafeArrayGetElemsize(ptr) SafeArrayGetElemsize32
19 st
dcall SafeArrayGetUBound(ptr long long) SafeArrayGetUBound32
20 st
dcall SafeArrayGetLBound(ptr long long) SafeArrayGetLBound32
21 st
dcall SafeArrayLock(ptr) SafeArrayLock32
22 st
dcall SafeArrayUnlock(ptr) SafeArrayUnlock32
23 st
dcall SafeArrayAccessData(ptr ptr) SafeArrayAccessData32
24 st
dcall SafeArrayUnaccessData(ptr) SafeArrayUnaccessData32
25 st
dcall SafeArrayGetElement(ptr ptr ptr) SafeArrayGetElement32
26 st
dcall SafeArrayPutElement(ptr ptr ptr) SafeArrayPutElement32
27 st
dcall SafeArrayCopy(ptr ptr) SafeArrayCopy32
28 stub DispGetParam
29 stub DispGetIDsOfNames
30 stub DispInvoke
...
...
@@ -36,11 +36,11 @@ type win32
33 stub RegisterActiveObject
34 stub RevokeActiveObject
35 stub GetActiveObject
36 st
ub SafeArrayAllocDescriptor
37 st
ub SafeArrayAllocData
38 st
ub SafeArrayDestroyDescriptor
39 st
ub SafeArrayDestroyData
40 st
ub SafeArrayRedim
36 st
dcall SafeArrayAllocDescriptor(long ptr) SafeArrayAllocDescriptor32
37 st
dcall SafeArrayAllocData(ptr) SafeArrayAllocData32
38 st
dcall SafeArrayDestroyDescriptor(ptr) SafeArrayDestroyDescriptor32
39 st
dcall SafeArrayDestroyData(ptr) SafeArrayDestroyData32
40 st
dcall SafeArrayRedim(ptr ptr) SafeArrayRedim32
41 stub OACreateTypeLib2
46 stub VarParseNumFromStr
47 stub VarNumFromParseNum
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment