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
cb816d2c
Commit
cb816d2c
authored
Mar 11, 2003
by
Mike Hearn
Committed by
Alexandre Julliard
Mar 11, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented the global interface table object using a simple linked
list.
parent
0b36e34a
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
294 additions
and
2 deletions
+294
-2
Makefile.in
dlls/ole32/Makefile.in
+1
-0
compobj.c
dlls/ole32/compobj.c
+18
-0
compobj_private.h
dlls/ole32/compobj_private.h
+3
-0
git.c
dlls/ole32/git.c
+263
-0
marshal.c
dlls/ole32/marshal.c
+1
-1
winedefault.reg
winedefault.reg
+8
-1
No files found.
dlls/ole32/Makefile.in
View file @
cb816d2c
...
@@ -22,6 +22,7 @@ C_SRCS = \
...
@@ -22,6 +22,7 @@ C_SRCS = \
errorinfo.c
\
errorinfo.c
\
filemoniker.c
\
filemoniker.c
\
ftmarshal.c
\
ftmarshal.c
\
git.c
\
hglobalstream.c
\
hglobalstream.c
\
ifs.c
\
ifs.c
\
itemmoniker.c
\
itemmoniker.c
\
...
...
dlls/ole32/compobj.c
View file @
cb816d2c
...
@@ -58,6 +58,10 @@ static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext,
...
@@ -58,6 +58,10 @@ static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext,
static
void
COM_RevokeAllClasses
();
static
void
COM_RevokeAllClasses
();
static
void
COM_ExternalLockFreeList
();
static
void
COM_ExternalLockFreeList
();
const
CLSID
CLSID_StdGlobalInterfaceTable
=
{
0x00000323
,
0
,
0
,
{
0xc0
,
0
,
0
,
0
,
0
,
0
,
0
,
0x46
}
};
static
void
*
StdGlobalInterfaceTableInstance
;
/*****************************************************************************
/*****************************************************************************
* Appartment management stuff
* Appartment management stuff
*
*
...
@@ -1317,6 +1321,20 @@ HRESULT WINAPI CoCreateInstance(
...
@@ -1317,6 +1321,20 @@ HRESULT WINAPI CoCreateInstance(
*
ppv
=
0
;
*
ppv
=
0
;
/*
/*
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
* Rather than create a class factory, we can just check for it here
*/
if
(
IsEqualIID
(
rclsid
,
&
CLSID_StdGlobalInterfaceTable
))
{
if
(
StdGlobalInterfaceTableInstance
==
NULL
)
StdGlobalInterfaceTableInstance
=
StdGlobalInterfaceTable_Construct
();
hres
=
IGlobalInterfaceTable_QueryInterface
(
(
IGlobalInterfaceTable
*
)
StdGlobalInterfaceTableInstance
,
iid
,
ppv
);
if
(
hres
)
return
hres
;
TRACE
(
"Retrieved GIT (%p)
\n
"
,
*
ppv
);
return
S_OK
;
}
/*
* Get a class factory to construct the object we want.
* Get a class factory to construct the object we want.
*/
*/
hres
=
CoGetClassObject
(
rclsid
,
hres
=
CoGetClassObject
(
rclsid
,
...
...
dlls/ole32/compobj_private.h
View file @
cb816d2c
...
@@ -27,6 +27,9 @@
...
@@ -27,6 +27,9 @@
#include "wtypes.h"
#include "wtypes.h"
extern
void
*
StdGlobalInterfaceTable_Construct
();
extern
void
StdGlobalInterfaceTable_Destroy
(
void
*
self
);
extern
HRESULT
WINE_StringFromCLSID
(
const
CLSID
*
id
,
LPSTR
idstr
);
extern
HRESULT
WINE_StringFromCLSID
(
const
CLSID
*
id
,
LPSTR
idstr
);
extern
HRESULT
create_marshalled_proxy
(
REFCLSID
rclsid
,
REFIID
iid
,
LPVOID
*
ppv
);
extern
HRESULT
create_marshalled_proxy
(
REFCLSID
rclsid
,
REFIID
iid
,
LPVOID
*
ppv
);
...
...
dlls/ole32/git.c
0 → 100644
View file @
cb816d2c
/*
* Implementation of the StdGlobalInterfaceTable object
*
* The GlobalInterfaceTable (GIT) object is used to marshal interfaces between
* threading apartments (contexts). When you want to pass an interface but not
* as a parameter, it wouldn't get marshalled automatically, so you can use this
* object to insert the interface into a table, and you get back a cookie.
* Then when it's retrieved, it'll be unmarshalled into the right apartment.
*
* Copyright 1999 Mike Hearn <mike@theoretic.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "objbase.h"
#include "ole2.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "compobj_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ole
);
/****************************************************************************
* StdGlobalInterfaceTable definition
*
* This class implements IGlobalInterfaceTable and is a process-wide singleton
* used for marshalling interfaces between threading apartments using cookies.
*/
/* Each entry in the linked list of GIT entries */
typedef
struct
StdGITEntry
{
DWORD
cookie
;
IID
iid
;
/* IID of the interface */
IStream
*
stream
;
/* Holds the marshalled interface */
struct
StdGITEntry
*
next
;
struct
StdGITEntry
*
prev
;
}
StdGITEntry
;
/* Class data */
typedef
struct
StdGlobalInterfaceTableImpl
{
ICOM_VFIELD
(
IGlobalInterfaceTable
);
ULONG
ref
;
struct
StdGITEntry
*
firstEntry
;
struct
StdGITEntry
*
lastEntry
;
ULONG
nextCookie
;
}
StdGlobalInterfaceTableImpl
;
/* IUnknown */
static
HRESULT
WINAPI
StdGlobalInterfaceTable_QueryInterface
(
IGlobalInterfaceTable
*
iface
,
REFIID
riid
,
void
**
ppvObject
);
static
ULONG
WINAPI
StdGlobalInterfaceTable_AddRef
(
IGlobalInterfaceTable
*
iface
);
static
ULONG
WINAPI
StdGlobalInterfaceTable_Release
(
IGlobalInterfaceTable
*
iface
);
/* IGlobalInterfaceTable */
static
HRESULT
WINAPI
StdGlobalInterfaceTable_RegisterInterfaceInGlobal
(
IGlobalInterfaceTable
*
iface
,
IUnknown
*
pUnk
,
REFIID
riid
,
DWORD
*
pdwCookie
);
static
HRESULT
WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal
(
IGlobalInterfaceTable
*
iface
,
DWORD
dwCookie
);
static
HRESULT
WINAPI
StdGlobalInterfaceTable_GetInterfaceFromGlobal
(
IGlobalInterfaceTable
*
iface
,
DWORD
dwCookie
,
REFIID
riid
,
void
**
ppv
);
/* Virtual function table */
static
ICOM_VTABLE
(
IGlobalInterfaceTable
)
StdGlobalInterfaceTableImpl_Vtbl
=
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
StdGlobalInterfaceTable_QueryInterface
,
StdGlobalInterfaceTable_AddRef
,
StdGlobalInterfaceTable_Release
,
StdGlobalInterfaceTable_RegisterInterfaceInGlobal
,
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal
,
StdGlobalInterfaceTable_GetInterfaceFromGlobal
};
/***
* Let's go! Here is the constructor and destructor for the class.
*
*/
/** This function constructs the GIT. It should only be called once **/
void
*
StdGlobalInterfaceTable_Construct
()
{
StdGlobalInterfaceTableImpl
*
newGIT
;
newGIT
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
StdGlobalInterfaceTableImpl
));
if
(
newGIT
==
0
)
return
newGIT
;
ICOM_VTBL
(
newGIT
)
=
&
StdGlobalInterfaceTableImpl_Vtbl
;
newGIT
->
ref
=
0
;
/* Initialise the reference count */
newGIT
->
firstEntry
=
NULL
;
/* we start with an empty table */
newGIT
->
lastEntry
=
NULL
;
newGIT
->
nextCookie
=
0xf100
;
/* that's where windows starts, so that's where we start */
TRACE
(
"Created the GIT at %p
\n
"
,
newGIT
);
return
(
void
*
)
newGIT
;
}
/** This destroys it again. It should revoke all the held interfaces first **/
void
StdGlobalInterfaceTable_Destroy
(
void
*
self
)
{
TRACE
(
"(%p)
\n
"
,
self
);
FIXME
(
"Revoke held interfaces here
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
self
);
}
/***
* A helper function to traverse the list and find the entry that matches the cookie.
* Returns NULL if not found
*/
StdGITEntry
*
StdGlobalInterfaceTable_FindEntry
(
IGlobalInterfaceTable
*
iface
,
DWORD
cookie
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
StdGITEntry
*
e
;
TRACE
(
"iface=%p, cookie=0x%x
\n
"
,
iface
,
(
UINT
)
cookie
);
e
=
self
->
firstEntry
;
while
(
e
!=
NULL
)
{
if
(
e
->
cookie
==
cookie
)
return
e
;
e
=
e
->
next
;
}
return
NULL
;
}
/***
* Here's the boring boilerplate stuff for IUnknown
*/
HRESULT
WINAPI
StdGlobalInterfaceTable_QueryInterface
(
IGlobalInterfaceTable
*
iface
,
REFIID
riid
,
void
**
ppvObject
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
/* Make sure silly coders can't crash us */
if
(
ppvObject
==
0
)
return
E_INVALIDARG
;
*
ppvObject
=
0
;
/* assume we don't have the interface */
/* Do we implement that interface? */
if
(
IsEqualIID
(
&
IID_IUnknown
,
riid
))
{
*
ppvObject
=
(
IGlobalInterfaceTable
*
)
self
;
}
else
if
(
IsEqualIID
(
&
IID_IGlobalInterfaceTable
,
riid
))
{
*
ppvObject
=
(
IGlobalInterfaceTable
*
)
self
;
}
else
return
E_NOINTERFACE
;
/* Now inc the refcount */
/* we don't use refcounts for now: StdGlobalInterfaceTable_AddRef(iface); */
return
S_OK
;
}
ULONG
WINAPI
StdGlobalInterfaceTable_AddRef
(
IGlobalInterfaceTable
*
iface
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
self
->
ref
++
;
return
self
->
ref
;
}
ULONG
WINAPI
StdGlobalInterfaceTable_Release
(
IGlobalInterfaceTable
*
iface
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
self
->
ref
--
;
if
(
self
->
ref
==
0
)
{
/* Hey ho, it's time to go, so long again 'till next weeks show! */
StdGlobalInterfaceTable_Destroy
(
self
);
return
0
;
}
return
self
->
ref
;
}
/***
* Now implement the actual IGlobalInterfaceTable interface
*/
HRESULT
WINAPI
StdGlobalInterfaceTable_RegisterInterfaceInGlobal
(
IGlobalInterfaceTable
*
iface
,
IUnknown
*
pUnk
,
REFIID
riid
,
DWORD
*
pdwCookie
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
IStream
*
stream
=
NULL
;
HRESULT
hres
;
StdGITEntry
*
entry
;
TRACE
(
"iface=%p, pUnk=%p, riid=%s, pdwCookie=%p
\n
"
,
iface
,
pUnk
,
debugstr_guid
(
riid
),
pdwCookie
);
if
(
pUnk
==
NULL
)
return
E_INVALIDARG
;
/* marshal the interface */
hres
=
CoMarshalInterThreadInterfaceInStream
(
riid
,
pUnk
,
&
stream
);
if
(
hres
)
return
hres
;
entry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
StdGITEntry
));
if
(
entry
==
NULL
)
return
E_OUTOFMEMORY
;
entry
->
iid
=
*
riid
;
entry
->
stream
=
stream
;
entry
->
cookie
=
self
->
nextCookie
;
self
->
nextCookie
++
;
/* inc the cookie count */
/* insert the new entry at the end of the list */
entry
->
next
=
NULL
;
entry
->
prev
=
self
->
lastEntry
;
if
(
entry
->
prev
)
entry
->
prev
->
next
=
entry
;
else
self
->
firstEntry
=
entry
;
self
->
lastEntry
=
entry
;
/* and return the cookie */
*
pdwCookie
=
entry
->
cookie
;
return
S_OK
;
}
HRESULT
WINAPI
StdGlobalInterfaceTable_RevokeInterfaceFromGlobal
(
IGlobalInterfaceTable
*
iface
,
DWORD
dwCookie
)
{
StdGlobalInterfaceTableImpl
*
const
self
=
(
StdGlobalInterfaceTableImpl
*
)
iface
;
StdGITEntry
*
entry
;
TRACE
(
"iface=%p, dwCookie=0x%x
\n
"
,
iface
,
(
UINT
)
dwCookie
);
entry
=
StdGlobalInterfaceTable_FindEntry
(
iface
,
dwCookie
);
if
(
entry
==
NULL
)
{
TRACE
(
"Entry not found
\n
"
);
return
E_INVALIDARG
;
/* not found */
}
/* chop entry out of the list, and free the memory */
if
(
entry
->
prev
)
entry
->
prev
->
next
=
entry
->
next
;
else
self
->
firstEntry
=
entry
->
next
;
if
(
entry
->
next
)
entry
->
next
->
prev
=
entry
->
prev
;
else
self
->
lastEntry
=
entry
->
prev
;
HeapFree
(
GetProcessHeap
(),
0
,
entry
);
return
S_OK
;
}
HRESULT
WINAPI
StdGlobalInterfaceTable_GetInterfaceFromGlobal
(
IGlobalInterfaceTable
*
iface
,
DWORD
dwCookie
,
REFIID
riid
,
void
**
ppv
)
{
StdGITEntry
*
entry
;
HRESULT
hres
;
entry
=
StdGlobalInterfaceTable_FindEntry
(
iface
,
dwCookie
);
if
(
entry
==
NULL
)
return
E_INVALIDARG
;
if
(
!
IsEqualIID
(
&
entry
->
iid
,
&
riid
))
return
E_INVALIDARG
;
/* unmarshal the interface */
hres
=
CoGetInterfaceAndReleaseStream
(
entry
->
stream
,
riid
,
*
ppv
);
if
(
hres
)
return
hres
;
return
S_OK
;
}
dlls/ole32/marshal.c
View file @
cb816d2c
...
@@ -555,7 +555,7 @@ CoMarshalInterThreadInterfaceInStream(
...
@@ -555,7 +555,7 @@ CoMarshalInterThreadInterfaceInStream(
LARGE_INTEGER
seekto
;
LARGE_INTEGER
seekto
;
HRESULT
hres
;
HRESULT
hres
;
TRACE
(
"(
,%s,)
\n
"
,
debugstr_guid
(
riid
)
);
TRACE
(
"(
%s, %p, %p)
\n
"
,
debugstr_guid
(
riid
),
pUnk
,
ppStm
);
hres
=
CreateStreamOnHGlobal
(
0
,
TRUE
,
ppStm
);
hres
=
CreateStreamOnHGlobal
(
0
,
TRUE
,
ppStm
);
if
(
hres
)
return
hres
;
if
(
hres
)
return
hres
;
/* CoMarshalInterface(...); */
/* CoMarshalInterface(...); */
...
...
winedefault.reg
View file @
cb816d2c
...
@@ -146,6 +146,14 @@
...
@@ -146,6 +146,14 @@
# Entries for OLE32 (COM/OLE base)
# Entries for OLE32 (COM/OLE base)
#
#
# The GlobalInterfaceTable is used for marshalling interfaces between threading contexts by cookie lookup table
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000323-0000-0000-c000-000000000046}]
@="StdGlobalInterfaceTable"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000323-0000-0000-c000-000000000046}\InProcServer32]
@="ole32.dll"
"ThreadingModel"="Apartment"
# OLE32's built-in marshaler, handles standard interfaces such as IClassFactory.
# OLE32's built-in marshaler, handles standard interfaces such as IClassFactory.
# (PSFactoryBuffer = Proxy/Stub factory)
# (PSFactoryBuffer = Proxy/Stub factory)
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000320-0000-0000-C000-000000000046}]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000320-0000-0000-C000-000000000046}]
...
@@ -2852,4 +2860,3 @@
...
@@ -2852,4 +2860,3 @@
[HKEY_CLASSES_ROOT\txtfile\shell\print\command]
[HKEY_CLASSES_ROOT\txtfile\shell\print\command]
@="C:\\WINDOWS\\NOTEPAD.EXE /p %1"
@="C:\\WINDOWS\\NOTEPAD.EXE /p %1"
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