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
d53bdeca
Commit
d53bdeca
authored
Apr 27, 2012
by
Jacek Caban
Committed by
Alexandre Julliard
Apr 30, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Added BSTR cache implementation.
parent
016afa04
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
122 additions
and
111 deletions
+122
-111
oleaut.c
dlls/oleaut32/oleaut.c
+122
-111
No files found.
dlls/oleaut32/oleaut.c
View file @
d53bdeca
...
...
@@ -42,8 +42,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
static
BOOL
BSTR_bCache
=
TRUE
;
/* Cache allocations to minimise alloc calls? */
/******************************************************************************
* BSTR {OLEAUT32}
*
...
...
@@ -71,6 +69,70 @@ static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
* 'Inside OLE, second edition' by Kraig Brockshmidt.
*/
static
BOOL
bstr_cache_enabled
;
static
CRITICAL_SECTION
cs_bstr_cache
;
static
CRITICAL_SECTION_DEBUG
cs_bstr_cache_dbg
=
{
0
,
0
,
&
cs_bstr_cache
,
{
&
cs_bstr_cache_dbg
.
ProcessLocksList
,
&
cs_bstr_cache_dbg
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": bstr_cache"
)
}
};
static
CRITICAL_SECTION
cs_bstr_cache
=
{
&
cs_bstr_cache_dbg
,
-
1
,
0
,
0
,
0
,
0
};
typedef
struct
{
unsigned
short
head
;
unsigned
short
cnt
;
DWORD
*
buf
[
6
];
}
bstr_cache_entry_t
;
#define BUCKET_SIZE 16
static
bstr_cache_entry_t
bstr_cache
[
0x10000
/
BUCKET_SIZE
];
static
inline
size_t
bstr_alloc_size
(
size_t
size
)
{
return
(
size
+
sizeof
(
DWORD
)
+
BUCKET_SIZE
)
&
~
(
BUCKET_SIZE
-
1
);
}
static
inline
bstr_cache_entry_t
*
get_cache_entry
(
size_t
size
)
{
unsigned
cache_idx
=
(
size
+
sizeof
(
DWORD
)
-
1
)
/
BUCKET_SIZE
;
return
bstr_cache_enabled
&&
cache_idx
<
sizeof
(
bstr_cache
)
/
sizeof
(
*
bstr_cache
)
?
bstr_cache
+
cache_idx
:
NULL
;
}
static
DWORD
*
alloc_bstr
(
size_t
size
)
{
bstr_cache_entry_t
*
cache_entry
=
get_cache_entry
(
size
);
if
(
cache_entry
)
{
DWORD
*
ret
=
NULL
;
EnterCriticalSection
(
&
cs_bstr_cache
);
if
(
!
cache_entry
->
cnt
)
{
cache_entry
=
get_cache_entry
(
size
+
BUCKET_SIZE
);
if
(
cache_entry
&&
!
cache_entry
->
cnt
)
cache_entry
=
NULL
;
}
if
(
cache_entry
)
{
ret
=
cache_entry
->
buf
[
cache_entry
->
head
++
];
cache_entry
->
head
%=
sizeof
(
cache_entry
->
buf
)
/
sizeof
(
*
cache_entry
->
buf
);
cache_entry
->
cnt
--
;
}
LeaveCriticalSection
(
&
cs_bstr_cache
);
if
(
ret
)
return
ret
;
}
return
HeapAlloc
(
GetProcessHeap
(),
0
,
bstr_alloc_size
(
size
));
}
/******************************************************************************
* SysStringLen [OLEAUT32.7]
*
...
...
@@ -177,24 +239,28 @@ BSTR WINAPI SysAllocString(LPCOLESTR str)
*/
void
WINAPI
SysFreeString
(
BSTR
str
)
{
DWORD
*
bufferPointer
;
bstr_cache_entry_t
*
cache_entry
;
DWORD
*
ptr
;
/* NULL is a valid parameter */
if
(
!
str
)
return
;
if
(
!
str
)
return
;
/*
* We have to be careful when we free a BSTR pointer, it points to
* the beginning of the string but it skips the byte count contained
* before the string.
*/
bufferPointer
=
(
DWORD
*
)
str
;
ptr
=
(
DWORD
*
)
str
-
1
;
cache_entry
=
get_cache_entry
(
*
ptr
+
sizeof
(
WCHAR
));
if
(
cache_entry
)
{
EnterCriticalSection
(
&
cs_bstr_cache
);
bufferPointer
--
;
if
(
cache_entry
->
cnt
<
sizeof
(
cache_entry
->
buf
)
/
sizeof
(
*
cache_entry
->
buf
))
{
cache_entry
->
buf
[(
cache_entry
->
head
+
cache_entry
->
cnt
)
%
((
sizeof
(
cache_entry
->
buf
)
/
sizeof
(
*
cache_entry
->
buf
)))]
=
ptr
;
cache_entry
->
cnt
++
;
LeaveCriticalSection
(
&
cs_bstr_cache
);
return
;
}
/*
* Free the memory from its "real" origin.
*/
HeapFree
(
GetProcessHeap
(),
0
,
bufferPointe
r
);
LeaveCriticalSection
(
&
cs_bstr_cache
);
}
HeapFree
(
GetProcessHeap
(),
0
,
pt
r
);
}
/******************************************************************************
...
...
@@ -215,61 +281,28 @@ void WINAPI SysFreeString(BSTR str)
*/
BSTR
WINAPI
SysAllocStringLen
(
const
OLECHAR
*
str
,
unsigned
int
len
)
{
DWORD
bufferSize
;
DWORD
*
newBuffer
;
WCHAR
*
stringBuffer
;
DWORD
size
,
*
ptr
;
BSTR
ret
;
/* Detect integer overflow. */
if
(
len
>=
((
UINT_MAX
-
sizeof
(
WCHAR
)
-
sizeof
(
DWORD
))
/
sizeof
(
WCHAR
)))
return
NULL
;
/*
* Find the length of the buffer passed-in, in bytes.
*/
bufferSize
=
len
*
sizeof
(
WCHAR
);
/*
* Allocate a new buffer to hold the string.
* don't forget to keep an empty spot at the beginning of the
* buffer for the character count and an extra character at the
* end for the NULL.
*/
newBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
bufferSize
+
sizeof
(
WCHAR
)
+
sizeof
(
DWORD
));
/*
* If the memory allocation failed, return a null pointer.
*/
if
(
!
newBuffer
)
return
NULL
;
/*
* Copy the length of the string in the placeholder.
*/
*
newBuffer
=
bufferSize
;
/*
* Skip the byte count.
*/
newBuffer
++
;
/*
* Copy the information in the buffer.
* Since it is valid to pass a NULL pointer here, we'll initialize the
* buffer to nul if it is the case.
*/
if
(
str
!=
0
)
memcpy
(
newBuffer
,
str
,
bufferSize
);
else
memset
(
newBuffer
,
0
,
bufferSize
);
/*
* Make sure that there is a nul character at the end of the
* string.
*/
stringBuffer
=
(
WCHAR
*
)
newBuffer
;
stringBuffer
[
len
]
=
'\0'
;
size
=
len
*
sizeof
(
WCHAR
);
ptr
=
alloc_bstr
(
size
+
sizeof
(
WCHAR
));
if
(
!
ptr
)
return
NULL
;
*
ptr
=
size
;
ret
=
(
BSTR
)(
ptr
+
1
);
if
(
str
)
{
memcpy
(
ret
,
str
,
size
);
ret
[
len
]
=
0
;
}
else
{
memset
(
ret
,
0
,
size
+
sizeof
(
WCHAR
));
}
return
stringBuffer
;
return
ret
;
}
/******************************************************************************
...
...
@@ -299,12 +332,13 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
if
(
*
old
!=
NULL
)
{
BSTR
old_copy
=
*
old
;
DWORD
newbytelen
=
len
*
sizeof
(
WCHAR
);
DWORD
*
ptr
=
HeapReAlloc
(
GetProcessHeap
(),
0
,((
DWORD
*
)
*
old
)
-
1
,
newbytelen
+
sizeof
(
WCHAR
)
+
sizeof
(
DWORD
));
DWORD
*
ptr
=
HeapReAlloc
(
GetProcessHeap
(),
0
,((
DWORD
*
)
*
old
)
-
1
,
bstr_alloc_size
(
newbytelen
+
sizeof
(
WCHAR
)
));
*
old
=
(
BSTR
)(
ptr
+
1
);
*
ptr
=
newbytelen
;
/* Subtle hidden feature: The old string data is still there
* when 'in' is NULL!
* Some Microsoft program needs it.
* FIXME: Is it a sideeffect of BSTR caching?
*/
if
(
str
&&
old_copy
!=
str
)
memmove
(
*
old
,
str
,
newbytelen
);
(
*
old
)[
len
]
=
0
;
...
...
@@ -340,55 +374,27 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
*/
BSTR
WINAPI
SysAllocStringByteLen
(
LPCSTR
str
,
UINT
len
)
{
DWORD
*
newBuffe
r
;
char
*
stringBuffer
;
DWORD
*
pt
r
;
char
*
ret
;
/* Detect integer overflow. */
if
(
len
>=
(
UINT_MAX
-
sizeof
(
WCHAR
)
-
sizeof
(
DWORD
)))
return
NULL
;
/*
* Allocate a new buffer to hold the string.
* don't forget to keep an empty spot at the beginning of the
* buffer for the character count and an extra character at the
* end for the NULL.
*/
newBuffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
+
sizeof
(
WCHAR
)
+
sizeof
(
DWORD
));
/*
* If the memory allocation failed, return a null pointer.
*/
if
(
newBuffer
==
0
)
return
0
;
/*
* Copy the length of the string in the placeholder.
*/
*
newBuffer
=
len
;
/*
* Skip the byte count.
*/
newBuffer
++
;
/*
* Copy the information in the buffer.
* Since it is valid to pass a NULL pointer here, we'll initialize the
* buffer to nul if it is the case.
*/
if
(
str
!=
0
)
memcpy
(
newBuffer
,
str
,
len
);
/*
* Make sure that there is a nul character at the end of the
* string.
*/
stringBuffer
=
(
char
*
)
newBuffer
;
stringBuffer
[
len
]
=
0
;
stringBuffer
[
len
+
1
]
=
0
;
ptr
=
alloc_bstr
(
len
+
sizeof
(
WCHAR
));
if
(
!
ptr
)
return
NULL
;
*
ptr
=
len
;
ret
=
(
char
*
)(
ptr
+
1
);
if
(
str
)
{
memcpy
(
ret
,
str
,
len
);
ret
[
len
]
=
ret
[
len
+
1
]
=
0
;
}
else
{
memset
(
ret
,
0
,
len
+
sizeof
(
WCHAR
));
}
return
(
LPWSTR
)
stringBuffer
;
return
(
BSTR
)
ret
;
}
/******************************************************************************
...
...
@@ -440,11 +446,12 @@ INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str)
* Nothing.
*
* NOTES
* Se
e BSTR
.
* Se
tOaNoCache does not release cached strings, so it leaks by design
.
*/
void
WINAPI
SetOaNoCache
(
void
)
{
BSTR_bCache
=
FALSE
;
TRACE
(
"
\n
"
);
bstr_cache_enabled
=
FALSE
;
}
static
const
WCHAR
_delimiter
[]
=
{
'!'
,
0
};
/* default delimiter apparently */
...
...
@@ -840,6 +847,10 @@ HRESULT WINAPI DllCanUnloadNow(void)
*/
BOOL
WINAPI
DllMain
(
HINSTANCE
hInstDll
,
DWORD
fdwReason
,
LPVOID
lpvReserved
)
{
static
const
WCHAR
oanocacheW
[]
=
{
'o'
,
'a'
,
'n'
,
'o'
,
'c'
,
'a'
,
'c'
,
'h'
,
'e'
,
0
};
bstr_cache_enabled
=
!
GetEnvironmentVariableW
(
oanocacheW
,
NULL
,
0
);
return
OLEAUTPS_DllMain
(
hInstDll
,
fdwReason
,
lpvReserved
);
}
...
...
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