* Sync with Wine 1.7.17.
CORE-8080
svn path=/trunk/; revision=62938
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
+ /* destroy the object if there are no more references to it */
if (ref == 0)
{
if (This->pMarshal) IUnknown_Release(This->pMarshal);
LPOLESTR pszkey,
DWORD *index)
{
-
DWORD i;
- BYTE found=0;
+ BOOL found = FALSE;
TRACE("(%p,%p,%p,%p)\n",This,punk,pszkey,index);
)
)
- found=1;
+ found = TRUE;
}
}
else
/* search object identified by a moniker*/
for(i=0; ( (i<This->bindCtxTableLastIndex) && (!found));i++)
if(This->bindCtxTable[i].pObj==punk)
- found=1;
+ found = TRUE;
if (index != NULL)
*index=i-1;
return InterlockedIncrement(&This->ref);
}
-/******************************************************************************
- * ClassMoniker_Destroy (local function)
- *******************************************************************************/
-static HRESULT ClassMoniker_Destroy(ClassMoniker* This)
-{
- TRACE("(%p)\n",This);
-
- if (This->pMarshal) IUnknown_Release(This->pMarshal);
-
- HeapFree(GetProcessHeap(),0,This);
-
- return S_OK;
-}
-
/******************************************************************************
* ClassMoniker_Release
******************************************************************************/
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
- if (ref == 0) ClassMoniker_Destroy(This);
+ /* destroy the object if there are no more references to it */
+ if (ref == 0)
+ {
+ if (This->pMarshal) IUnknown_Release(This->pMarshal);
+ HeapFree(GetProcessHeap(),0,This);
+ }
return ref;
}
VOID** ppvResult)
{
TRACE("(%p,%p,%p,%p)\n",pbc, pmkToLeft, riid, ppvResult);
- return ClassMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
+ return IMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult);
}
/******************************************************************************
if (!ppmkReduced)
return E_POINTER;
- ClassMoniker_AddRef(iface);
+ IMoniker_AddRef(iface);
*ppmkReduced = iface;
TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
- return ClassMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
+ return IMoniker_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
}
/***********************************************************************
TRACE("(%p)\n",iface);
- return ClassMoniker_AddRef(&This->IMoniker_iface);
+ return IMoniker_AddRef(&This->IMoniker_iface);
}
/***********************************************************************
TRACE("(%p)\n",iface);
- return ClassMoniker_Release(&This->IMoniker_iface);
+ return IMoniker_Release(&This->IMoniker_iface);
}
/******************************************************************************
ClassMonikerCF_CreateInstance,
ClassMonikerCF_LockServer
};
-static const IClassFactoryVtbl *ClassMonikerCF = &ClassMonikerCFVtbl;
+
+static IClassFactory ClassMonikerCF = { &ClassMonikerCFVtbl };
HRESULT ClassMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
- return IClassFactory_QueryInterface((IClassFactory *)&ClassMonikerCF, riid, ppv);
+ return IClassFactory_QueryInterface(&ClassMonikerCF, riid, ppv);
}
{ &COMCAT_ICatInformation_Vtbl }
};
-struct class_categories {
- LPCWSTR impl_strings;
- LPCWSTR req_strings;
+struct class_categories
+{
+ ULONG size; /* total length, including structure itself */
+ ULONG impl_offset;
+ ULONG req_offset;
};
-static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid);
-static LPENUMGUID COMCAT_CLSID_IEnumGUID_Construct(struct class_categories *class_categories);
-static LPENUMGUID COMCAT_CATID_IEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req);
+static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret);
+static HRESULT CLSIDEnumGUID_Construct(struct class_categories *class_categories, IEnumCLSID **ret);
+static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR impl_req, IEnumCATID **ret);
/**********************************************************************
* File-scope string constants
ULONG cCategories,
const CATID *rgcatid)
{
- WCHAR keyname[39];
+ WCHAR keyname[CHARS_IN_GUID];
HRESULT res;
HKEY clsid_key, class_key, type_key;
if (cCategories && rgcatid == NULL) return E_POINTER;
/* Format the class key name. */
- res = StringFromGUID2(rclsid, keyname, 39);
+ res = StringFromGUID2(rclsid, keyname, CHARS_IN_GUID);
if (FAILED(res)) return res;
/* Create (or open) the CLSID key. */
HKEY key;
/* Format the category key name. */
- res = StringFromGUID2(rgcatid, keyname, 39);
+ res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID);
if (FAILED(res)) continue;
/* Do the register. */
if (cCategories && rgcatid == NULL) return E_POINTER;
/* Format the class category type key name. */
- res = StringFromGUID2(rclsid, keyname + 6, 39);
+ res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID);
if (FAILED(res)) return res;
keyname[44] = '\\';
lstrcpyW(keyname + 45, type);
for (; cCategories; --cCategories, ++rgcatid) {
/* Format the category key name. */
- res = StringFromGUID2(rgcatid, keyname, 39);
+ res = StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID);
if (FAILED(res)) continue;
/* Do the unregister. */
{
struct class_categories *categories;
WCHAR *strings;
+ ULONG size;
- categories = HeapAlloc(
- GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(struct class_categories) +
- ((impl_count + req_count) * 39 + 2) * sizeof(WCHAR));
+ size = sizeof(struct class_categories) + ((impl_count + req_count)*CHARS_IN_GUID + 2)*sizeof(WCHAR);
+ categories = HeapAlloc(GetProcessHeap(), 0, size);
if (categories == NULL) return categories;
+ categories->size = size;
+ categories->impl_offset = sizeof(struct class_categories);
+ categories->req_offset = categories->impl_offset + (impl_count*CHARS_IN_GUID + 1)*sizeof(WCHAR);
+
strings = (WCHAR *)(categories + 1);
- categories->impl_strings = strings;
while (impl_count--) {
- StringFromGUID2(impl_catids++, strings, 39);
- strings += 39;
+ StringFromGUID2(impl_catids++, strings, CHARS_IN_GUID);
+ strings += CHARS_IN_GUID;
}
*strings++ = 0;
- categories->req_strings = strings;
while (req_count--) {
- StringFromGUID2(req_catids++, strings, 39);
- strings += 39;
+ StringFromGUID2(req_catids++, strings, CHARS_IN_GUID);
+ strings += CHARS_IN_GUID;
}
*strings++ = 0;
HKEY key,
struct class_categories const* categories)
{
+ const WCHAR *impl_strings, *req_strings;
HKEY subkey;
HRESULT res;
DWORD index;
LPCWSTR string;
+ impl_strings = (WCHAR*)((BYTE*)categories + categories->impl_offset);
+ req_strings = (WCHAR*)((BYTE*)categories + categories->req_offset);
+
/* Check that every given category is implemented by class. */
- if (*categories->impl_strings) {
+ if (*impl_strings) {
res = open_classes_key(key, impl_keyname, KEY_READ, &subkey);
if (res != ERROR_SUCCESS) return S_FALSE;
- for (string = categories->impl_strings; *string; string += 39) {
+ for (string = impl_strings; *string; string += CHARS_IN_GUID) {
HKEY catkey;
res = open_classes_key(subkey, string, 0, &catkey);
if (res != ERROR_SUCCESS) {
res = open_classes_key(key, req_keyname, KEY_READ, &subkey);
if (res == ERROR_SUCCESS) {
for (index = 0; ; ++index) {
- WCHAR keyname[39];
- DWORD size = 39;
+ WCHAR keyname[CHARS_IN_GUID];
+ DWORD size = CHARS_IN_GUID;
res = RegEnumKeyExW(subkey, index, keyname, &size,
NULL, NULL, NULL, NULL);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
- if (size != 38) continue; /* bogus catid in registry */
- for (string = categories->req_strings; *string; string += 39)
+ if (size != CHARS_IN_GUID-1) continue; /* bogus catid in registry */
+ for (string = req_strings; *string; string += CHARS_IN_GUID)
if (!strcmpiW(string, keyname)) break;
if (!*string) {
RegCloseKey(subkey);
for (; cCategories; --cCategories, ++rgci) {
static const WCHAR fmt[] = { '%', 'l', 'X', 0 };
- WCHAR keyname[39];
+ WCHAR keyname[CHARS_IN_GUID];
WCHAR valname[9];
HKEY cat_key;
/* Create (or open) the key for this category. */
- if (!StringFromGUID2(&rgci->catid, keyname, 39)) continue;
+ if (!StringFromGUID2(&rgci->catid, keyname, CHARS_IN_GUID)) continue;
res = create_classes_key(comcat_key, keyname, KEY_READ|KEY_WRITE, &cat_key);
if (res != ERROR_SUCCESS) continue;
/* Set the value for this locale's description. */
wsprintfW(valname, fmt, rgci->lcid);
- RegSetValueExW(cat_key, valname, 0, REG_SZ,
- (CONST BYTE*)(rgci->szDescription),
+ RegSetValueExW(cat_key, valname, 0, REG_SZ, (const BYTE*)rgci->szDescription,
(lstrlenW(rgci->szDescription) + 1) * sizeof(WCHAR));
RegCloseKey(cat_key);
if (res != ERROR_SUCCESS) return E_FAIL;
for (; cCategories; --cCategories, ++rgcatid) {
- WCHAR keyname[39];
+ WCHAR keyname[CHARS_IN_GUID];
/* Delete the key for this category. */
- if (!StringFromGUID2(rgcatid, keyname, 39)) continue;
+ if (!StringFromGUID2(rgcatid, keyname, CHARS_IN_GUID)) continue;
RegDeleteKeyW(comcat_key, keyname);
}
if (ppenumCatInfo == NULL) return E_POINTER;
- *ppenumCatInfo = COMCAT_IEnumCATEGORYINFO_Construct(lcid);
- if (*ppenumCatInfo == NULL) return E_OUTOFMEMORY;
- IEnumCATEGORYINFO_AddRef(*ppenumCatInfo);
- return S_OK;
+ return EnumCATEGORYINFO_Construct(lcid, ppenumCatInfo);
}
/**********************************************************************
if (rcatid == NULL || ppszDesc == NULL) return E_INVALIDARG;
/* Open the key for this category. */
- if (!StringFromGUID2(rcatid, keyname + 21, 39)) return E_FAIL;
+ if (!StringFromGUID2(rcatid, keyname + 21, CHARS_IN_GUID)) return E_FAIL;
res = open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &key);
if (res != ERROR_SUCCESS) return CAT_E_CATIDNOEXIST;
LPENUMCLSID *ppenumCLSID)
{
struct class_categories *categories;
+ HRESULT hr;
TRACE("\n");
categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
cRequired, rgcatidReq);
if (categories == NULL) return E_OUTOFMEMORY;
- *ppenumCLSID = COMCAT_CLSID_IEnumGUID_Construct(categories);
- if (*ppenumCLSID == NULL) {
+
+ hr = CLSIDEnumGUID_Construct(categories, ppenumCLSID);
+ if (FAILED(hr))
+ {
HeapFree(GetProcessHeap(), 0, categories);
- return E_OUTOFMEMORY;
+ return hr;
}
- IEnumGUID_AddRef(*ppenumCLSID);
- return S_OK;
+
+ return hr;
}
/**********************************************************************
if ((cImplemented && rgcatidImpl == NULL) ||
(cRequired && rgcatidReq == NULL)) return E_POINTER;
- res = StringFromGUID2(rclsid, keyname + 6, 39);
+ res = StringFromGUID2(rclsid, keyname + 6, CHARS_IN_GUID);
if (FAILED(res)) return res;
categories = COMCAT_PrepareClassCategories(cImplemented, rgcatidImpl,
if (rclsid == NULL || ppenumCATID == NULL)
return E_POINTER;
- *ppenumCATID = COMCAT_CATID_IEnumGUID_Construct(rclsid, postfix);
- if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
- return S_OK;
+ return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
}
/**********************************************************************
if (rclsid == NULL || ppenumCATID == NULL)
return E_POINTER;
- *ppenumCATID = COMCAT_CATID_IEnumGUID_Construct(rclsid, postfix);
- if (*ppenumCATID == NULL) return E_OUTOFMEMORY;
- return S_OK;
+ return CATIDEnumGUID_Construct(rclsid, postfix, ppenumCATID);
}
/**********************************************************************
if (This->key) while (fetched < celt) {
LSTATUS res;
HRESULT hr;
- WCHAR catid[39];
- DWORD cName = 39;
+ WCHAR catid[CHARS_IN_GUID];
+ DWORD cName = CHARS_IN_GUID;
HKEY subkey;
res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
COMCAT_IEnumCATEGORYINFO_Clone
};
-static IEnumCATEGORYINFO *COMCAT_IEnumCATEGORYINFO_Construct(LCID lcid)
+static HRESULT EnumCATEGORYINFO_Construct(LCID lcid, IEnumCATEGORYINFO **ret)
{
+ static const WCHAR keyname[] = {'C','o','m','p','o','n','e','n','t',' ','C','a','t','e','g','o','r','i','e','s',0};
IEnumCATEGORYINFOImpl *This;
+ *ret = NULL;
+
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumCATEGORYINFOImpl));
- if (This) {
- static const WCHAR keyname[] = { 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n',
- 't', ' ', 'C', 'a', 't', 'e', 'g', 'o',
- 'r', 'i', 'e', 's', 0 };
-
- This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl;
- This->lcid = lcid;
- open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
- }
- return &This->IEnumCATEGORYINFO_iface;
+ if (!This) return E_OUTOFMEMORY;
+
+ This->IEnumCATEGORYINFO_iface.lpVtbl = &COMCAT_IEnumCATEGORYINFO_Vtbl;
+ This->ref = 1;
+ This->lcid = lcid;
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumCATEGORYINFO_iface;
+ return S_OK;
}
/**********************************************************************
*/
typedef struct
{
- const IEnumGUIDVtbl *lpVtbl;
+ IEnumGUID IEnumGUID_iface;
LONG ref;
struct class_categories *categories;
HKEY key;
DWORD next_index;
} CLSID_IEnumGUIDImpl;
-static ULONG WINAPI COMCAT_CLSID_IEnumGUID_AddRef(LPENUMGUID iface)
+static inline CLSID_IEnumGUIDImpl *impl_from_IEnumCLSID(IEnumGUID *iface)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
- TRACE("\n");
-
- return InterlockedIncrement(&This->ref);
+ return CONTAINING_RECORD(iface, CLSID_IEnumGUIDImpl, IEnumGUID_iface);
}
-static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_QueryInterface(
- LPENUMGUID iface,
+static HRESULT WINAPI CLSIDEnumGUID_QueryInterface(
+ IEnumGUID *iface,
REFIID riid,
LPVOID *ppvObj)
{
IsEqualGUID(riid, &IID_IEnumGUID))
{
*ppvObj = iface;
- COMCAT_CLSID_IEnumGUID_AddRef(iface);
+ IEnumGUID_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
-static ULONG WINAPI COMCAT_CLSID_IEnumGUID_Release(LPENUMGUID iface)
+static ULONG WINAPI CLSIDEnumGUID_AddRef(IEnumGUID *iface)
+{
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
+ TRACE("\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI CLSIDEnumGUID_Release(IEnumGUID *iface)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
ULONG ref;
TRACE("\n");
return ref;
}
-static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Next(
- LPENUMGUID iface,
+static HRESULT WINAPI CLSIDEnumGUID_Next(
+ IEnumGUID *iface,
ULONG celt,
GUID *rgelt,
ULONG *pceltFetched)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
ULONG fetched = 0;
TRACE("\n");
if (This->key) while (fetched < celt) {
LSTATUS res;
HRESULT hr;
- WCHAR clsid[39];
- DWORD cName = 39;
+ WCHAR clsid[CHARS_IN_GUID];
+ DWORD cName = CHARS_IN_GUID;
HKEY subkey;
res = RegEnumKeyExW(This->key, This->next_index, clsid, &cName,
return fetched == celt ? S_OK : S_FALSE;
}
-static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Skip(
- LPENUMGUID iface,
+static HRESULT WINAPI CLSIDEnumGUID_Skip(
+ IEnumGUID *iface,
ULONG celt)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
TRACE("\n");
return S_OK;
}
-static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Reset(LPENUMGUID iface)
+static HRESULT WINAPI CLSIDEnumGUID_Reset(IEnumGUID *iface)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
TRACE("\n");
return S_OK;
}
-static HRESULT WINAPI COMCAT_CLSID_IEnumGUID_Clone(
- LPENUMGUID iface,
+static HRESULT WINAPI CLSIDEnumGUID_Clone(
+ IEnumGUID *iface,
IEnumGUID **ppenum)
{
- CLSID_IEnumGUIDImpl *This = (CLSID_IEnumGUIDImpl *)iface;
- static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 };
- CLSID_IEnumGUIDImpl *new_this;
- DWORD size;
+ static const WCHAR keynameW[] = {'C','L','S','I','D',0};
+ CLSID_IEnumGUIDImpl *This = impl_from_IEnumCLSID(iface);
+ CLSID_IEnumGUIDImpl *cloned;
- TRACE("\n");
+ TRACE("(%p)->(%p)\n", This, ppenum);
if (ppenum == NULL) return E_POINTER;
- new_this = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl));
- if (new_this == NULL) return E_OUTOFMEMORY;
+ *ppenum = NULL;
- new_this->lpVtbl = This->lpVtbl;
- new_this->ref = 1;
- size = HeapSize(GetProcessHeap(), 0, This->categories);
- new_this->categories =
- HeapAlloc(GetProcessHeap(), 0, size);
- if (new_this->categories == NULL) {
- HeapFree(GetProcessHeap(), 0, new_this);
+ cloned = HeapAlloc(GetProcessHeap(), 0, sizeof(CLSID_IEnumGUIDImpl));
+ if (cloned == NULL) return E_OUTOFMEMORY;
+
+ cloned->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl;
+ cloned->ref = 1;
+
+ cloned->categories = HeapAlloc(GetProcessHeap(), 0, This->categories->size);
+ if (cloned->categories == NULL) {
+ HeapFree(GetProcessHeap(), 0, cloned);
return E_OUTOFMEMORY;
}
- memcpy(new_this->categories, This->categories, size);
- /* FIXME: could we more efficiently use DuplicateHandle? */
- open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &new_this->key);
- new_this->next_index = This->next_index;
+ memcpy(cloned->categories, This->categories, This->categories->size);
+
+ cloned->key = NULL;
+ open_classes_key(HKEY_CLASSES_ROOT, keynameW, KEY_READ, &cloned->key);
+ cloned->next_index = This->next_index;
- *ppenum = (LPENUMGUID)new_this;
+ *ppenum = &cloned->IEnumGUID_iface;
return S_OK;
}
-static const IEnumGUIDVtbl COMCAT_CLSID_IEnumGUID_Vtbl =
+static const IEnumGUIDVtbl CLSIDEnumGUIDVtbl =
{
- COMCAT_CLSID_IEnumGUID_QueryInterface,
- COMCAT_CLSID_IEnumGUID_AddRef,
- COMCAT_CLSID_IEnumGUID_Release,
- COMCAT_CLSID_IEnumGUID_Next,
- COMCAT_CLSID_IEnumGUID_Skip,
- COMCAT_CLSID_IEnumGUID_Reset,
- COMCAT_CLSID_IEnumGUID_Clone
+ CLSIDEnumGUID_QueryInterface,
+ CLSIDEnumGUID_AddRef,
+ CLSIDEnumGUID_Release,
+ CLSIDEnumGUID_Next,
+ CLSIDEnumGUID_Skip,
+ CLSIDEnumGUID_Reset,
+ CLSIDEnumGUID_Clone
};
-static LPENUMGUID COMCAT_CLSID_IEnumGUID_Construct(struct class_categories *categories)
+static HRESULT CLSIDEnumGUID_Construct(struct class_categories *categories, IEnumCLSID **ret)
{
+ static const WCHAR keyname[] = {'C','L','S','I','D',0};
CLSID_IEnumGUIDImpl *This;
+ *ret = NULL;
+
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLSID_IEnumGUIDImpl));
- if (This) {
- static const WCHAR keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 };
+ if (!This) return E_OUTOFMEMORY;
- This->lpVtbl = &COMCAT_CLSID_IEnumGUID_Vtbl;
- This->categories = categories;
- open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
- }
- return (LPENUMGUID)This;
+ This->IEnumGUID_iface.lpVtbl = &CLSIDEnumGUIDVtbl;
+ This->ref = 1;
+ This->categories = categories;
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumGUID_iface;
+
+ return S_OK;
}
/**********************************************************************
*/
typedef struct
{
- const IEnumGUIDVtbl *lpVtbl;
+ IEnumGUID IEnumGUID_iface;
LONG ref;
WCHAR keyname[68];
HKEY key;
DWORD next_index;
} CATID_IEnumGUIDImpl;
-static ULONG WINAPI COMCAT_CATID_IEnumGUID_AddRef(LPENUMGUID iface)
+static inline CATID_IEnumGUIDImpl *impl_from_IEnumCATID(IEnumGUID *iface)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
- TRACE("\n");
-
- return InterlockedIncrement(&This->ref);
+ return CONTAINING_RECORD(iface, CATID_IEnumGUIDImpl, IEnumGUID_iface);
}
-static HRESULT WINAPI COMCAT_CATID_IEnumGUID_QueryInterface(
- LPENUMGUID iface,
+static HRESULT WINAPI CATIDEnumGUID_QueryInterface(
+ IEnumGUID *iface,
REFIID riid,
LPVOID *ppvObj)
{
IsEqualGUID(riid, &IID_IEnumGUID))
{
*ppvObj = iface;
- COMCAT_CATID_IEnumGUID_AddRef(iface);
+ IEnumGUID_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
-static ULONG WINAPI COMCAT_CATID_IEnumGUID_Release(LPENUMGUID iface)
+static ULONG WINAPI CATIDEnumGUID_AddRef(IEnumGUID *iface)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
+ TRACE("\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI CATIDEnumGUID_Release(IEnumGUID *iface)
+{
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
ULONG ref;
TRACE("\n");
return ref;
}
-static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Next(
- LPENUMGUID iface,
+static HRESULT WINAPI CATIDEnumGUID_Next(
+ IEnumGUID *iface,
ULONG celt,
GUID *rgelt,
ULONG *pceltFetched)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
ULONG fetched = 0;
TRACE("\n");
if (This->key) while (fetched < celt) {
LSTATUS res;
HRESULT hr;
- WCHAR catid[39];
- DWORD cName = 39;
+ WCHAR catid[CHARS_IN_GUID];
+ DWORD cName = CHARS_IN_GUID;
res = RegEnumKeyExW(This->key, This->next_index, catid, &cName,
NULL, NULL, NULL, NULL);
return fetched == celt ? S_OK : S_FALSE;
}
-static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Skip(
- LPENUMGUID iface,
+static HRESULT WINAPI CATIDEnumGUID_Skip(
+ IEnumGUID *iface,
ULONG celt)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
TRACE("\n");
return S_OK;
}
-static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Reset(LPENUMGUID iface)
+static HRESULT WINAPI CATIDEnumGUID_Reset(IEnumGUID *iface)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
TRACE("\n");
return S_OK;
}
-static HRESULT WINAPI COMCAT_CATID_IEnumGUID_Clone(
- LPENUMGUID iface,
+static HRESULT WINAPI CATIDEnumGUID_Clone(
+ IEnumGUID *iface,
IEnumGUID **ppenum)
{
- CATID_IEnumGUIDImpl *This = (CATID_IEnumGUIDImpl *)iface;
+ CATID_IEnumGUIDImpl *This = impl_from_IEnumCATID(iface);
CATID_IEnumGUIDImpl *new_this;
TRACE("\n");
new_this = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
if (new_this == NULL) return E_OUTOFMEMORY;
- new_this->lpVtbl = This->lpVtbl;
+ new_this->IEnumGUID_iface.lpVtbl = This->IEnumGUID_iface.lpVtbl;
new_this->ref = 1;
lstrcpyW(new_this->keyname, This->keyname);
/* FIXME: could we more efficiently use DuplicateHandle? */
open_classes_key(HKEY_CLASSES_ROOT, new_this->keyname, KEY_READ, &new_this->key);
new_this->next_index = This->next_index;
- *ppenum = (LPENUMGUID)new_this;
+ *ppenum = &new_this->IEnumGUID_iface;
return S_OK;
}
-static const IEnumGUIDVtbl COMCAT_CATID_IEnumGUID_Vtbl =
+static const IEnumGUIDVtbl CATIDEnumGUIDVtbl =
{
- COMCAT_CATID_IEnumGUID_QueryInterface,
- COMCAT_CATID_IEnumGUID_AddRef,
- COMCAT_CATID_IEnumGUID_Release,
- COMCAT_CATID_IEnumGUID_Next,
- COMCAT_CATID_IEnumGUID_Skip,
- COMCAT_CATID_IEnumGUID_Reset,
- COMCAT_CATID_IEnumGUID_Clone
+ CATIDEnumGUID_QueryInterface,
+ CATIDEnumGUID_AddRef,
+ CATIDEnumGUID_Release,
+ CATIDEnumGUID_Next,
+ CATIDEnumGUID_Skip,
+ CATIDEnumGUID_Reset,
+ CATIDEnumGUID_Clone
};
-static LPENUMGUID COMCAT_CATID_IEnumGUID_Construct(
- REFCLSID rclsid, LPCWSTR postfix)
+static HRESULT CATIDEnumGUID_Construct(REFCLSID rclsid, LPCWSTR postfix, IEnumGUID **ret)
{
+ static const WCHAR prefixW[] = {'C','L','S','I','D','\\',0};
+ WCHAR keyname[100], clsidW[CHARS_IN_GUID];
CATID_IEnumGUIDImpl *This;
+ *ret = NULL;
+
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CATID_IEnumGUIDImpl));
- if (This) {
- WCHAR prefix[] = { 'C', 'L', 'S', 'I', 'D', '\\' };
-
- This->lpVtbl = &COMCAT_CATID_IEnumGUID_Vtbl;
- memcpy(This->keyname, prefix, sizeof(prefix));
- StringFromGUID2(rclsid, This->keyname + 6, 39);
- lstrcpyW(This->keyname + 44, postfix);
- open_classes_key(HKEY_CLASSES_ROOT, This->keyname, KEY_READ, &This->key);
- }
- return (LPENUMGUID)This;
+ if (!This) return E_OUTOFMEMORY;
+
+ StringFromGUID2(rclsid, clsidW, CHARS_IN_GUID);
+
+ This->IEnumGUID_iface.lpVtbl = &CATIDEnumGUIDVtbl;
+ This->ref = 1;
+ strcpyW(keyname, prefixW);
+ strcatW(keyname, clsidW);
+ strcatW(keyname, postfix);
+
+ open_classes_key(HKEY_CLASSES_ROOT, keyname, KEY_READ, &This->key);
+
+ *ret = &This->IEnumGUID_iface;
+ return S_OK;
}
};
static CRITICAL_SECTION csApartment = { &critsect_debug, -1, 0, 0, 0, 0 };
+enum comclass_threadingmodel
+{
+ ThreadingModel_Apartment = 1,
+ ThreadingModel_Free = 2,
+ ThreadingModel_No = 3,
+ ThreadingModel_Both = 4,
+ ThreadingModel_Neutral = 5
+};
+
+enum comclass_miscfields
+{
+ MiscStatus = 1,
+ MiscStatusIcon = 2,
+ MiscStatusContent = 4,
+ MiscStatusThumbnail = 8,
+ MiscStatusDocPrint = 16
+};
+
+struct comclassredirect_data
+{
+ ULONG size;
+ BYTE res;
+ BYTE miscmask;
+ BYTE res1[2];
+ DWORD model;
+ GUID clsid;
+ GUID alias;
+ GUID clsid2;
+ GUID tlbid;
+ ULONG name_len;
+ ULONG name_offset;
+ ULONG progid_len;
+ ULONG progid_offset;
+ ULONG clrdata_len;
+ ULONG clrdata_offset;
+ DWORD miscstatus;
+ DWORD miscstatuscontent;
+ DWORD miscstatusthumbnail;
+ DWORD miscstatusicon;
+ DWORD miscstatusdocprint;
+};
+
+struct ifacepsredirect_data
+{
+ ULONG size;
+ DWORD mask;
+ GUID iid;
+ ULONG nummethods;
+ GUID tlbid;
+ GUID base;
+ ULONG name_len;
+ ULONG name_offset;
+};
+
+struct progidredirect_data
+{
+ ULONG size;
+ DWORD reserved;
+ ULONG clsid_offset;
+};
+
+struct class_reg_data
+{
+ union
+ {
+ struct
+ {
+ struct comclassredirect_data *data;
+ void *section;
+ HANDLE hactctx;
+ } actctx;
+ HKEY hkey;
+ } u;
+ BOOL hkey;
+};
+
struct registered_psclsid
{
struct list entry;
};
static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 };
+static inline enum comclass_miscfields dvaspect_to_miscfields(DWORD aspect)
+{
+ switch (aspect)
+ {
+ case DVASPECT_CONTENT:
+ return MiscStatusContent;
+ case DVASPECT_THUMBNAIL:
+ return MiscStatusThumbnail;
+ case DVASPECT_ICON:
+ return MiscStatusIcon;
+ case DVASPECT_DOCPRINT:
+ return MiscStatusDocPrint;
+ default:
+ return MiscStatus;
+ };
+}
+
+BOOL actctx_get_miscstatus(const CLSID *clsid, DWORD aspect, DWORD *status)
+{
+ ACTCTX_SECTION_KEYED_DATA data;
+
+ data.cbSize = sizeof(data);
+ if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION,
+ clsid, &data))
+ {
+ struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData;
+ enum comclass_miscfields misc = dvaspect_to_miscfields(aspect);
+
+ if (!(comclass->miscmask & misc))
+ {
+ if (!(comclass->miscmask & MiscStatus))
+ {
+ *status = 0;
+ return TRUE;
+ }
+ misc = MiscStatus;
+ }
+
+ switch (misc)
+ {
+ case MiscStatus:
+ *status = comclass->miscstatus;
+ break;
+ case MiscStatusIcon:
+ *status = comclass->miscstatusicon;
+ break;
+ case MiscStatusContent:
+ *status = comclass->miscstatuscontent;
+ break;
+ case MiscStatusThumbnail:
+ *status = comclass->miscstatusthumbnail;
+ break;
+ case MiscStatusDocPrint:
+ *status = comclass->miscstatusdocprint;
+ break;
+ default:
+ ;
+ };
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
/* wrapper for NtCreateKey that creates the key recursively if necessary */
static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr )
{
DllCanUnloadNowFunc DllCanUnloadNow;
DllGetClassObjectFunc DllGetClassObject;
- TRACE("\n");
+ TRACE("%s\n", debugstr_w(library_name));
*ret = COMPOBJ_DllList_Get(library_name);
if (*ret) return S_OK;
*
* Reads a registry value and expands it when necessary
*/
-static DWORD COM_RegReadPath(HKEY hkeyroot, WCHAR * dst, DWORD dstlen)
+static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen)
{
- DWORD ret;
+ DWORD ret;
+
+ if (regdata->hkey)
+ {
DWORD keytype;
WCHAR src[MAX_PATH];
DWORD dwLength = dstlen * sizeof(WCHAR);
- if( (ret = RegQueryValueExW(hkeyroot, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) {
+ if( (ret = RegQueryValueExW(regdata->u.hkey, NULL, NULL, &keytype, (BYTE*)src, &dwLength)) == ERROR_SUCCESS ) {
if (keytype == REG_EXPAND_SZ) {
if (dstlen <= ExpandEnvironmentStringsW(src, dst, dstlen)) ret = ERROR_MORE_DATA;
} else {
}
}
return ret;
+ }
+ else
+ {
+ ULONG_PTR cookie;
+ WCHAR *nameW;
+
+ *dst = 0;
+ nameW = (WCHAR*)((BYTE*)regdata->u.actctx.section + regdata->u.actctx.data->name_offset);
+ ActivateActCtx(regdata->u.actctx.hactctx, &cookie);
+ ret = SearchPathW(NULL, nameW, NULL, dstlen, dst, NULL);
+ DeactivateActCtx(0, cookie);
+ return !*dst;
+ }
}
struct host_object_params
{
- HKEY hkeydll;
+ struct class_reg_data regdata;
CLSID clsid; /* clsid of object to marshal */
IID iid; /* interface to marshal */
HANDLE event; /* event signalling when ready for multi-threaded case */
TRACE("clsid %s, iid %s\n", debugstr_guid(¶ms->clsid), debugstr_guid(¶ms->iid));
- if (COM_RegReadPath(params->hkeydll, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+ if (COM_RegReadPath(¶ms->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
{
/* failure: CLSID is not found in registry */
WARN("class %s not registered inproc\n", debugstr_guid(¶ms->clsid));
* caller of this function */
static HRESULT apartment_hostobject_in_hostapt(
struct apartment *apt, BOOL multi_threaded, BOOL main_apartment,
- HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
+ const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, void **ppv)
{
struct host_object_params params;
HWND apartment_hwnd = NULL;
}
}
- params.hkeydll = hkeydll;
+ params.regdata = *regdata;
params.clsid = *rclsid;
params.iid = *riid;
hr = CreateStreamOnHGlobal(NULL, TRUE, ¶ms.stream);
return hr;
}
+#ifndef __REACTOS__
+static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context )
+{
+ WNDCLASSW wclass;
+
+ /* Dispatching to the correct thread in an apartment is done through
+ * window messages rather than RPC transports. When an interface is
+ * marshalled into another apartment in the same process, a window of the
+ * following class is created. The *caller* of CoMarshalInterface (i.e., the
+ * application) is responsible for pumping the message loop in that thread.
+ * The WM_USER messages which point to the RPCs are then dispatched to
+ * apartment_wndproc by the user's code from the apartment in which the
+ * interface was unmarshalled.
+ */
+ memset(&wclass, 0, sizeof(wclass));
+ wclass.lpfnWndProc = apartment_wndproc;
+ wclass.hInstance = hProxyDll;
+ wclass.lpszClassName = wszAptWinClass;
+ RegisterClassW(&wclass);
+ return TRUE;
+}
+#endif
+
/* create a window for the apartment or return the current one if one has
* already been created */
HRESULT apartment_createwindowifneeded(struct apartment *apt)
COM_CurrentInfo()->apt = MTA;
}
+#ifdef __REACTOS__
+
static void COMPOBJ_InitProcess( void )
{
WNDCLASSW wclass;
UnregisterClassW(wszAptWinClass, hProxyDll);
}
+#endif
+
static void COM_TlsDestroy(void)
{
struct oletls *info = NtCurrentTeb()->ReservedForOle;
return TRUE;
}
-/******************************************************************************
- * CLSIDFromString [OLE32.@]
- * IIDFromString [OLE32.@]
- *
- * Converts a unique identifier from its string representation into
- * the GUID struct.
- *
- * PARAMS
- * idstr [I] The string representation of the GUID.
- * id [O] GUID converted from the string.
- *
- * RETURNS
- * S_OK on success
- * CO_E_CLASSSTRING if idstr is not a valid CLSID
- *
- * SEE ALSO
- * StringFromCLSID
- */
-static HRESULT __CLSIDFromString(LPCWSTR s, LPCLSID id)
+static const BYTE guid_conv_table[256] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
+ 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
+ 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
+};
+
+/* conversion helper for CLSIDFromString/IIDFromString */
+static BOOL guid_from_string(LPCWSTR s, GUID *id)
{
int i;
- BYTE table[256];
if (!s || s[0]!='{') {
memset( id, 0, sizeof (CLSID) );
- if(!s) return S_OK;
- return CO_E_CLASSSTRING;
+ if(!s) return TRUE;
+ return FALSE;
}
TRACE("%s -> %p\n", debugstr_w(s), id);
- /* quick lookup table */
- memset(table, 0, 256);
-
- for (i = 0; i < 10; i++) {
- table['0' + i] = i;
- }
- for (i = 0; i < 6; i++) {
- table['A' + i] = i+10;
- table['a' + i] = i+10;
- }
-
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
id->Data1 = 0;
for (i = 1; i < 9; i++) {
- if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING;
- id->Data1 = (id->Data1 << 4) | table[s[i]];
+ if (!is_valid_hex(s[i])) return FALSE;
+ id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]];
}
- if (s[9]!='-') return CO_E_CLASSSTRING;
+ if (s[9]!='-') return FALSE;
id->Data2 = 0;
for (i = 10; i < 14; i++) {
- if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING;
- id->Data2 = (id->Data2 << 4) | table[s[i]];
+ if (!is_valid_hex(s[i])) return FALSE;
+ id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]];
}
- if (s[14]!='-') return CO_E_CLASSSTRING;
+ if (s[14]!='-') return FALSE;
id->Data3 = 0;
for (i = 15; i < 19; i++) {
- if (!is_valid_hex(s[i])) return CO_E_CLASSSTRING;
- id->Data3 = (id->Data3 << 4) | table[s[i]];
+ if (!is_valid_hex(s[i])) return FALSE;
+ id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]];
}
- if (s[19]!='-') return CO_E_CLASSSTRING;
+ if (s[19]!='-') return FALSE;
for (i = 20; i < 37; i+=2) {
if (i == 24) {
- if (s[i]!='-') return CO_E_CLASSSTRING;
+ if (s[i]!='-') return FALSE;
i++;
}
- if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return CO_E_CLASSSTRING;
- id->Data4[(i-20)/2] = table[s[i]] << 4 | table[s[i+1]];
+ if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE;
+ id->Data4[(i-20)/2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]];
}
if (s[37] == '}' && s[38] == '\0')
- return S_OK;
+ return TRUE;
- return CO_E_CLASSSTRING;
+ return FALSE;
}
/*****************************************************************************/
+static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid)
+{
+ static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
+ WCHAR buf2[CHARS_IN_GUID];
+ LONG buf2len = sizeof(buf2);
+ HKEY xhkey;
+ WCHAR *buf;
+
+ memset(clsid, 0, sizeof(*clsid));
+ buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) );
+ if (!buf) return E_OUTOFMEMORY;
+ strcpyW( buf, progid );
+ strcatW( buf, clsidW );
+ if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey))
+ {
+ HeapFree(GetProcessHeap(),0,buf);
+ WARN("couldn't open key for ProgID %s\n", debugstr_w(progid));
+ return CO_E_CLASSSTRING;
+ }
+ HeapFree(GetProcessHeap(),0,buf);
+
+ if (RegQueryValueW(xhkey,NULL,buf2,&buf2len))
+ {
+ RegCloseKey(xhkey);
+ WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid));
+ return CO_E_CLASSSTRING;
+ }
+ RegCloseKey(xhkey);
+ return guid_from_string(buf2, clsid) ? S_OK : CO_E_CLASSSTRING;
+}
+
+/******************************************************************************
+ * CLSIDFromString [OLE32.@]
+ *
+ * Converts a unique identifier from its string representation into
+ * the GUID struct.
+ *
+ * PARAMS
+ * idstr [I] The string representation of the GUID.
+ * id [O] GUID converted from the string.
+ *
+ * RETURNS
+ * S_OK on success
+ * CO_E_CLASSSTRING if idstr is not a valid CLSID
+ *
+ * SEE ALSO
+ * StringFromCLSID
+ */
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id )
{
- HRESULT ret;
+ HRESULT ret = CO_E_CLASSSTRING;
+ CLSID tmp_id;
if (!id)
return E_INVALIDARG;
- ret = __CLSIDFromString(idstr, id);
- if(ret != S_OK) { /* It appears a ProgID is also valid */
- CLSID tmp_id;
- ret = CLSIDFromProgID(idstr, &tmp_id);
- if(SUCCEEDED(ret))
- *id = tmp_id;
- }
+ if (guid_from_string(idstr, id))
+ return S_OK;
+
+ /* It appears a ProgID is also valid */
+ ret = clsid_from_string_reg(idstr, &tmp_id);
+ if(SUCCEEDED(ret))
+ *id = tmp_id;
+
return ret;
}
+/******************************************************************************
+ * IIDFromString [OLE32.@]
+ *
+ * Converts a interface identifier from its string representation into
+ * the IID struct.
+ *
+ * PARAMS
+ * idstr [I] The string representation of the GUID.
+ * id [O] IID converted from the string.
+ *
+ * RETURNS
+ * S_OK on success
+ * CO_E_IIDSTRING if idstr is not a valid IID
+ *
+ * SEE ALSO
+ * StringFromIID
+ */
+HRESULT WINAPI IIDFromString(LPCOLESTR s, IID *iid)
+{
+ TRACE("%s -> %p\n", debugstr_w(s), iid);
+
+ if (!s)
+ {
+ memset(iid, 0, sizeof(*iid));
+ return S_OK;
+ }
+
+ /* length mismatch is a special case */
+ if (strlenW(s) + 1 != CHARS_IN_GUID)
+ return E_INVALIDARG;
+
+ if (s[0] != '{')
+ return CO_E_IIDSTRING;
+
+ return guid_from_string(s, iid) ? S_OK : CO_E_IIDSTRING;
+}
/******************************************************************************
* StringFromCLSID [OLE32.@]
*/
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr)
{
- HRESULT ret;
- LPMALLOC mllc;
-
- if ((ret = CoGetMalloc(0,&mllc))) return ret;
- if (!(*idstr = IMalloc_Alloc( mllc, CHARS_IN_GUID * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
+ if (!(*idstr = CoTaskMemAlloc(CHARS_IN_GUID * sizeof(WCHAR)))) return E_OUTOFMEMORY;
StringFromGUID2( id, *idstr, CHARS_IN_GUID );
return S_OK;
}
* E_OUTOFMEMORY
* REGDB_E_CLASSNOTREG if the given clsid has no associated ProgID
*/
-HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID)
+HRESULT WINAPI DECLSPEC_HOTPATCH ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID)
{
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
+ ACTCTX_SECTION_KEYED_DATA data;
HKEY hkey;
HRESULT ret;
LONG progidlen = 0;
if (!ppszProgID)
- {
- ERR("ppszProgId isn't optional\n");
return E_INVALIDARG;
- }
*ppszProgID = NULL;
+
+ data.cbSize = sizeof(data);
+ if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION,
+ clsid, &data))
+ {
+ struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData;
+ if (comclass->progid_len)
+ {
+ WCHAR *ptrW;
+
+ *ppszProgID = CoTaskMemAlloc(comclass->progid_len + sizeof(WCHAR));
+ if (!*ppszProgID) return E_OUTOFMEMORY;
+
+ ptrW = (WCHAR*)((BYTE*)comclass + comclass->progid_offset);
+ memcpy(*ppszProgID, ptrW, comclass->progid_len + sizeof(WCHAR));
+ return S_OK;
+ }
+ else
+ return REGDB_E_CLASSNOTREG;
+ }
+
ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
if (FAILED(ret))
return ret;
* Success: S_OK
* Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
*/
-HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
+HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
{
- static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
- WCHAR buf2[CHARS_IN_GUID];
- LONG buf2len = sizeof(buf2);
- HKEY xhkey;
- WCHAR *buf;
+ ACTCTX_SECTION_KEYED_DATA data;
if (!progid || !clsid)
- {
- ERR("neither progid (%p) nor clsid (%p) are optional\n", progid, clsid);
return E_INVALIDARG;
- }
-
- /* initialise clsid in case of failure */
- memset(clsid, 0, sizeof(*clsid));
- buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) );
- strcpyW( buf, progid );
- strcatW( buf, clsidW );
- if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey))
+ data.cbSize = sizeof(data);
+ if (FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION,
+ progid, &data))
{
- HeapFree(GetProcessHeap(),0,buf);
- WARN("couldn't open key for ProgID %s\n", debugstr_w(progid));
- return CO_E_CLASSSTRING;
+ struct progidredirect_data *progiddata = (struct progidredirect_data*)data.lpData;
+ CLSID *alias = (CLSID*)((BYTE*)data.lpSectionBase + progiddata->clsid_offset);
+ *clsid = *alias;
+ return S_OK;
}
- HeapFree(GetProcessHeap(),0,buf);
- if (RegQueryValueW(xhkey,NULL,buf2,&buf2len))
- {
- RegCloseKey(xhkey);
- WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid));
- return CO_E_CLASSSTRING;
- }
- RegCloseKey(xhkey);
- return __CLSIDFromString(buf2,clsid);
+ return clsid_from_string_reg(progid, clsid);
}
/******************************************************************************
HKEY hkey;
APARTMENT *apt = COM_CurrentApt();
struct registered_psclsid *registered_psclsid;
+ ACTCTX_SECTION_KEYED_DATA data;
TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
}
if (!pclsid)
- {
- ERR("pclsid isn't optional\n");
return E_INVALIDARG;
- }
EnterCriticalSection(&apt->cs);
LeaveCriticalSection(&apt->cs);
+ data.cbSize = sizeof(data);
+ if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
+ riid, &data))
+ {
+ struct ifacepsredirect_data *ifaceps = (struct ifacepsredirect_data*)data.lpData;
+ *pclsid = ifaceps->iid;
+ return S_OK;
+ }
+
/* Interface\\{string form of riid}\\ProxyStubClsid32 */
strcpyW(path, wszInterface);
StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID);
return S_OK;
}
-static void get_threading_model(HKEY key, LPWSTR value, DWORD len)
+static enum comclass_threadingmodel get_threading_model(const struct class_reg_data *data)
{
- static const WCHAR wszThreadingModel[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
- DWORD keytype;
- DWORD ret;
- DWORD dwLength = len * sizeof(WCHAR);
+ if (data->hkey)
+ {
+ static const WCHAR wszThreadingModel[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
+ static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
+ static const WCHAR wszFree[] = {'F','r','e','e',0};
+ static const WCHAR wszBoth[] = {'B','o','t','h',0};
+ WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
+ DWORD dwLength = sizeof(threading_model);
+ DWORD keytype;
+ DWORD ret;
+
+ ret = RegQueryValueExW(data->u.hkey, wszThreadingModel, NULL, &keytype, (BYTE*)threading_model, &dwLength);
+ if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ))
+ threading_model[0] = '\0';
- ret = RegQueryValueExW(key, wszThreadingModel, NULL, &keytype, (LPBYTE)value, &dwLength);
- if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ))
- value[0] = '\0';
+ if (!strcmpiW(threading_model, wszApartment)) return ThreadingModel_Apartment;
+ if (!strcmpiW(threading_model, wszFree)) return ThreadingModel_Free;
+ if (!strcmpiW(threading_model, wszBoth)) return ThreadingModel_Both;
+
+ /* there's not specific handling for this case */
+ if (threading_model[0]) return ThreadingModel_Neutral;
+ return ThreadingModel_No;
+ }
+ else
+ return data->u.actctx.data->model;
}
-static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll,
+static HRESULT get_inproc_class_object(APARTMENT *apt, const struct class_reg_data *regdata,
REFCLSID rclsid, REFIID riid,
BOOL hostifnecessary, void **ppv)
{
if (hostifnecessary)
{
- static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
- static const WCHAR wszFree[] = {'F','r','e','e',0};
- static const WCHAR wszBoth[] = {'B','o','t','h',0};
- WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
+ enum comclass_threadingmodel model = get_threading_model(regdata);
- get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model));
- /* "Apartment" */
- if (!strcmpiW(threading_model, wszApartment))
+ if (model == ThreadingModel_Apartment)
{
apartment_threaded = TRUE;
if (apt->multi_threaded)
- return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, hkeydll, rclsid, riid, ppv);
+ return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, regdata, rclsid, riid, ppv);
}
- /* "Free" */
- else if (!strcmpiW(threading_model, wszFree))
+ else if (model == ThreadingModel_Free)
{
apartment_threaded = FALSE;
if (!apt->multi_threaded)
- return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, hkeydll, rclsid, riid, ppv);
+ return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, regdata, rclsid, riid, ppv);
}
/* everything except "Apartment", "Free" and "Both" */
- else if (strcmpiW(threading_model, wszBoth))
+ else if (model != ThreadingModel_Both)
{
apartment_threaded = TRUE;
/* everything else is main-threaded */
- if (threading_model[0])
- FIXME("unrecognised threading model %s for object %s, should be main-threaded?\n",
- debugstr_w(threading_model), debugstr_guid(rclsid));
+ if (model != ThreadingModel_No)
+ FIXME("unrecognised threading model %d for object %s, should be main-threaded?\n", model, debugstr_guid(rclsid));
if (apt->multi_threaded || !apt->main)
- return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, hkeydll, rclsid, riid, ppv);
+ return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, regdata, rclsid, riid, ppv);
}
else
apartment_threaded = FALSE;
else
apartment_threaded = !apt->multi_threaded;
- if (COM_RegReadPath(hkeydll, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+ if (COM_RegReadPath(regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
{
/* failure: CLSID is not found in registry */
WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
* SEE ALSO
* CoCreateInstance()
*/
-HRESULT WINAPI CoGetClassObject(
+HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
REFIID iid, LPVOID *ppv)
{
- LPUNKNOWN regClassObject;
+ struct class_reg_data clsreg;
+ IUnknown *regClassObject;
HRESULT hres = E_UNEXPECTED;
APARTMENT *apt;
BOOL release_apt = FALSE;
debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo);
}
+ if (CLSCTX_INPROC_SERVER & dwClsContext)
+ {
+ if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
+ {
+ if (release_apt) apartment_release(apt);
+ return FTMarshalCF_Create(iid, ppv);
+ }
+ }
+
+ if (CLSCTX_INPROC & dwClsContext)
+ {
+ ACTCTX_SECTION_KEYED_DATA data;
+
+ data.cbSize = sizeof(data);
+ /* search activation context first */
+ if (FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
+ ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION,
+ rclsid, &data))
+ {
+ struct comclassredirect_data *comclass = (struct comclassredirect_data*)data.lpData;
+
+ clsreg.u.actctx.hactctx = data.hActCtx;
+ clsreg.u.actctx.data = data.lpData;
+ clsreg.u.actctx.section = data.lpSectionBase;
+ clsreg.hkey = FALSE;
+
+ hres = get_inproc_class_object(apt, &clsreg, &comclass->clsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
+ ReleaseActCtx(data.hActCtx);
+ if (release_apt) apartment_release(apt);
+ return hres;
+ }
+ }
+
/*
* First, try and see if we can't match the class ID with one of the
* registered classes.
static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
HKEY hkey;
- if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
- {
- if (release_apt) apartment_release(apt);
- return FTMarshalCF_Create(iid, ppv);
- }
-
hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
if (FAILED(hres))
{
if (SUCCEEDED(hres))
{
- hres = get_inproc_class_object(apt, hkey, rclsid, iid,
- !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
+ clsreg.u.hkey = hkey;
+ clsreg.hkey = TRUE;
+
+ hres = get_inproc_class_object(apt, &clsreg, rclsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
RegCloseKey(hkey);
}
if (SUCCEEDED(hres))
{
- hres = get_inproc_class_object(apt, hkey, rclsid, iid,
- !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
+ clsreg.u.hkey = hkey;
+ clsreg.hkey = TRUE;
+
+ hres = get_inproc_class_object(apt, &clsreg, rclsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
RegCloseKey(hkey);
}
* SEE ALSO
* CoGetClassObject()
*/
-HRESULT WINAPI CoCreateInstance(
+HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
return hres;
}
+static void init_multi_qi(DWORD count, MULTI_QI *mqi)
+{
+ ULONG i;
+
+ for (i = 0; i < count; i++)
+ {
+ mqi[i].pItf = NULL;
+ mqi[i].hr = E_NOINTERFACE;
+ }
+}
+
+static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi)
+{
+ ULONG index, fetched = 0;
+
+ for (index = 0; index < count; index++)
+ {
+ mqi[index].hr = IUnknown_QueryInterface(unk, mqi[index].pIID, (void**)&mqi[index].pItf);
+ if (mqi[index].hr == S_OK)
+ fetched++;
+ }
+
+ IUnknown_Release(unk);
+
+ if (fetched == 0)
+ return E_NOINTERFACE;
+
+ return fetched == count ? S_OK : CO_S_NOTALLINTERFACES;
+}
+
/***********************************************************************
* CoCreateInstanceEx [OLE32.@]
*/
-HRESULT WINAPI CoCreateInstanceEx(
+HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
{
IUnknown* pUnk = NULL;
HRESULT hr;
- ULONG index;
- ULONG successCount = 0;
/*
* Sanity check
if (pServerInfo!=NULL)
FIXME("() non-NULL pServerInfo not supported!\n");
- /*
- * Initialize all the "out" parameters.
- */
- for (index = 0; index < cmq; index++)
- {
- pResults[index].pItf = NULL;
- pResults[index].hr = E_NOINTERFACE;
- }
+ init_multi_qi(cmq, pResults);
/*
* Get the object and get its IUnknown pointer.
if (hr != S_OK)
return hr;
- /*
- * Then, query for all the interfaces requested.
- */
- for (index = 0; index < cmq; index++)
+ return return_multi_qi(pUnk, cmq, pResults);
+}
+
+/***********************************************************************
+ * CoGetInstanceFromFile [OLE32.@]
+ */
+HRESULT WINAPI CoGetInstanceFromFile(
+ COSERVERINFO *server_info,
+ CLSID *rclsid,
+ IUnknown *outer,
+ DWORD cls_context,
+ DWORD grfmode,
+ OLECHAR *filename,
+ DWORD count,
+ MULTI_QI *results
+)
+{
+ IPersistFile *pf = NULL;
+ IUnknown* unk = NULL;
+ CLSID clsid;
+ HRESULT hr;
+
+ if (count == 0 || !results)
+ return E_INVALIDARG;
+
+ if (server_info)
+ FIXME("() non-NULL server_info not supported\n");
+
+ init_multi_qi(count, results);
+
+ /* optionaly get CLSID from a file */
+ if (!rclsid)
{
- pResults[index].hr = IUnknown_QueryInterface(pUnk,
- pResults[index].pIID,
- (VOID**)&(pResults[index].pItf));
+ hr = GetClassFile(filename, &clsid);
+ if (FAILED(hr))
+ {
+ ERR("failed to get CLSID from a file\n");
+ return hr;
+ }
- if (pResults[index].hr == S_OK)
- successCount++;
+ rclsid = &clsid;
}
- /*
- * Release our temporary unknown pointer.
- */
- IUnknown_Release(pUnk);
+ hr = CoCreateInstance(rclsid,
+ outer,
+ cls_context,
+ &IID_IUnknown,
+ (void**)&unk);
- if (successCount == 0)
- return E_NOINTERFACE;
+ if (hr != S_OK)
+ return hr;
- if (successCount!=cmq)
- return CO_S_NOTALLINTERFACES;
+ /* init from file */
+ hr = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&pf);
+ if (FAILED(hr))
+ ERR("failed to get IPersistFile\n");
- return S_OK;
+ if (pf)
+ {
+ IPersistFile_Load(pf, filename, grfmode);
+ IPersistFile_Release(pf);
+ }
+
+ return return_multi_qi(unk, count, results);
+}
+
+/***********************************************************************
+ * CoGetInstanceFromIStorage [OLE32.@]
+ */
+HRESULT WINAPI CoGetInstanceFromIStorage(
+ COSERVERINFO *server_info,
+ CLSID *rclsid,
+ IUnknown *outer,
+ DWORD cls_context,
+ IStorage *storage,
+ DWORD count,
+ MULTI_QI *results
+)
+{
+ IPersistStorage *ps = NULL;
+ IUnknown* unk = NULL;
+ STATSTG stat;
+ HRESULT hr;
+
+ if (count == 0 || !results || !storage)
+ return E_INVALIDARG;
+
+ if (server_info)
+ FIXME("() non-NULL server_info not supported\n");
+
+ init_multi_qi(count, results);
+
+ /* optionaly get CLSID from a file */
+ if (!rclsid)
+ {
+ memset(&stat.clsid, 0, sizeof(stat.clsid));
+ hr = IStorage_Stat(storage, &stat, STATFLAG_NONAME);
+ if (FAILED(hr))
+ {
+ ERR("failed to get CLSID from a file\n");
+ return hr;
+ }
+
+ rclsid = &stat.clsid;
+ }
+
+ hr = CoCreateInstance(rclsid,
+ outer,
+ cls_context,
+ &IID_IUnknown,
+ (void**)&unk);
+
+ if (hr != S_OK)
+ return hr;
+
+ /* init from IStorage */
+ hr = IUnknown_QueryInterface(unk, &IID_IPersistStorage, (void**)&ps);
+ if (FAILED(hr))
+ ERR("failed to get IPersistStorage\n");
+
+ if (ps)
+ {
+ IPersistStorage_Load(ps, storage);
+ IPersistStorage_Release(ps);
+ }
+
+ return return_multi_qi(unk, count, results);
}
/***********************************************************************
* SEE ALSO
* CoLoadLibrary, CoFreeAllLibraries, CoFreeLibrary
*/
-void WINAPI CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved)
+void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved)
{
struct apartment *apt = COM_CurrentApt();
if (!apt)
* SEE ALSO
* CoLoadLibrary, CoFreeAllLibraries, CoFreeLibrary
*/
-void WINAPI CoFreeUnusedLibraries(void)
+void WINAPI DECLSPEC_HOTPATCH CoFreeUnusedLibraries(void)
{
CoFreeUnusedLibrariesEx(INFINITE, 0);
}
hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey);
if (SUCCEEDED(hres))
{
+ struct class_reg_data regdata;
WCHAR dllpath[MAX_PATH+1];
- if (COM_RegReadPath(hkey, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
+ regdata.u.hkey = hkey;
+ regdata.hkey = TRUE;
+
+ if (COM_RegReadPath(®data, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
{
static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
if (!strcmpiW(dllpath, wszOle32))
extern LSTATUS create_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
extern LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HIDDEN;
+extern BOOL actctx_get_miscstatus(const CLSID*, DWORD, DWORD*) DECLSPEC_HIDDEN;
+
static inline void *heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-#define BLOCK_TAB_SIZE 5 /* represent the first size table and it's increment block size */
+#define BLOCK_TAB_SIZE 5 /* represent the first size table and its increment block size */
/* CompositeMoniker data structure */
typedef struct CompositeMonikerImpl{
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
+ /* destroy the object if there are no more references to it */
if (ref == 0){
/* release all the components before destroying this object */
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
+ /* destroy the object if there are no more references to it */
if (ref == 0) {
for(i=0;i<This->tabSize;i++)
if (pmkFirst==NULL && pmkRest!=NULL){
*ppmkComposite=pmkRest;
+ IMoniker_AddRef(pmkRest);
return S_OK;
}
else if (pmkFirst!=NULL && pmkRest==NULL){
*ppmkComposite=pmkFirst;
+ IMoniker_AddRef(pmkFirst);
return S_OK;
}
else if (pmkFirst==NULL && pmkRest==NULL)
/* see the official DCOM specification
* (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */
+#pragma makedep proxy
+#pragma makedep register
+
import "unknwn.idl";
[
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
+ /* destroy the object if there are no more references to it */
if (ref == 0) FileMonikerImpl_Destroy(This);
return ref;
FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
- LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
- IBindCtx *pbind;
+ LPOLESTR pathThis = NULL, pathOther = NULL,*stringTable1,*stringTable2,commonPath = NULL;
+ IBindCtx *bindctx;
DWORD mkSys;
ULONG nb1,nb2,i,sameIdx;
- BOOL machimeNameCase=FALSE;
+ BOOL machineNameCase = FALSE;
+ HRESULT ret;
if (ppmkPrefix==NULL)
return E_POINTER;
/* check if we have the same type of moniker */
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
+ if (mkSys != MKSYS_FILEMONIKER)
+ return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix);
- if(mkSys==MKSYS_FILEMONIKER){
- HRESULT ret;
-
- ret = CreateBindCtx(0,&pbind);
- if (FAILED(ret))
- return ret;
-
- /* create a string based on common part of the two paths */
-
- ret = IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
- if (FAILED(ret))
- return ret;
- ret = IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
- if (FAILED(ret))
- return ret;
-
- nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1);
- if (FAILED(nb1))
- return nb1;
- nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2);
- if (FAILED(nb2))
- {
- free_stringtable(stringTable1);
- return nb2;
- }
-
- if (nb1==0 || nb2==0)
- {
- free_stringtable(stringTable1);
- free_stringtable(stringTable2);
- return MK_E_NOPREFIX;
- }
-
- commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
- if (!commonPath)
- return E_OUTOFMEMORY;
+ ret = CreateBindCtx(0, &bindctx);
+ if (FAILED(ret))
+ return ret;
- *commonPath=0;
+ /* create a string based on common part of the two paths */
+ ret = IMoniker_GetDisplayName(iface, bindctx, NULL, &pathThis);
+ if (FAILED(ret))
+ goto failed;
- for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
- (stringTable2[sameIdx]!=NULL) &&
- (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
+ ret = IMoniker_GetDisplayName(pmkOther, bindctx, NULL, &pathOther);
+ if (FAILED(ret))
+ goto failed;
- if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
+ nb1 = FileMonikerImpl_DecomposePath(pathThis, &stringTable1);
+ if (FAILED(nb1)) {
+ ret = nb1;
+ goto failed;
+ }
- machimeNameCase=TRUE;
+ nb2 = FileMonikerImpl_DecomposePath(pathOther, &stringTable2);
+ if (FAILED(nb2)) {
+ ret = nb2;
+ goto failed;
+ }
- for(i=2;i<sameIdx;i++)
+ if (nb1 == 0 || nb2 == 0) {
+ ret = MK_E_NOPREFIX;
+ goto failed;
+ }
- if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
- machimeNameCase=FALSE;
- break;
- }
- }
+ commonPath = CoTaskMemAlloc(sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
+ if (!commonPath) {
+ ret = E_OUTOFMEMORY;
+ goto failed;
+ }
- if (machimeNameCase && *stringTable1[sameIdx-1]=='\\')
- sameIdx--;
+ *commonPath = 0;
+ for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
+ (stringTable2[sameIdx]!=NULL) &&
+ (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
- if (machimeNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
- ret = MK_E_NOPREFIX;
- else
- {
- for(i=0;i<sameIdx;i++)
- strcatW(commonPath,stringTable1[i]);
+ if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
+ machineNameCase = TRUE;
- free_stringtable(stringTable1);
- free_stringtable(stringTable2);
- ret = CreateFileMoniker(commonPath,ppmkPrefix);
+ for(i=2;i<sameIdx;i++)
+ if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
+ machineNameCase = FALSE;
+ break;
}
- HeapFree(GetProcessHeap(),0,commonPath);
- return ret;
}
+
+ if (machineNameCase && *stringTable1[sameIdx-1]=='\\')
+ sameIdx--;
+
+ if (machineNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
+ ret = MK_E_NOPREFIX;
else
- return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
+ {
+ for (i = 0; i < sameIdx; i++)
+ strcatW(commonPath,stringTable1[i]);
+ ret = CreateFileMoniker(commonPath, ppmkPrefix);
+ }
+
+failed:
+ IBindCtx_Release(bindctx);
+ CoTaskMemFree(pathThis);
+ CoTaskMemFree(pathOther);
+ CoTaskMemFree(commonPath);
+ free_stringtable(stringTable1);
+ free_stringtable(stringTable2);
+
+ return ret;
}
/******************************************************************************
CoTaskMemFree(strgtable);
}
- if (word)
- CoTaskMemFree(word);
+ CoTaskMemFree(word);
return ret;
}
LPOLESTR *tabStr=0;
static const WCHAR twoPoint[]={'.','.',0};
static const WCHAR bkSlash[]={'\\',0};
- BYTE addBkSlash;
+ BOOL addBkSlash;
TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
if (nb > 0 ){
- addBkSlash=1;
+ addBkSlash = TRUE;
if (lstrcmpW(tabStr[0],twoPoint)!=0)
- addBkSlash=0;
+ addBkSlash = FALSE;
else
for(i=0;i<nb;i++){
if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
- addBkSlash=0;
+ addBkSlash = FALSE;
break;
}
else
if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
*tabStr[i]=0;
sizeStr--;
- addBkSlash=0;
+ addBkSlash = FALSE;
break;
}
}
if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
- addBkSlash=0;
+ addBkSlash = FALSE;
This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));
static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
/* resize the old table */
-static int SetSpyedBlockTableLength ( DWORD NewLength )
+static BOOL SetSpyedBlockTableLength ( DWORD NewLength )
{
LPVOID *NewSpyedBlocks;
}
/* add a location to the table */
-static int AddMemoryLocation(LPVOID * pMem)
+static BOOL AddMemoryLocation(LPVOID * pMem)
{
LPVOID * Current;
/* allocate the table if not already allocated */
- if (!Malloc32.SpyedBlockTableLength) {
- if (!SetSpyedBlockTableLength(0x1000)) return 0;
- }
+ if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000))
+ return FALSE;
/* find a free location */
Current = Malloc32.SpyedBlocks;
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
/* no more space in table, grow it */
DWORD old_length = Malloc32.SpyedBlockTableLength;
- if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
+ if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000))
+ return FALSE;
Current = Malloc32.SpyedBlocks + old_length;
}
};
*Current = pMem;
Malloc32.SpyedAllocationsLeft++;
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
- return 1;
+ return TRUE;
}
-static int RemoveMemoryLocation(LPCVOID pMem)
+static BOOL RemoveMemoryLocation(LPCVOID pMem)
{
LPVOID * Current;
/* allocate the table if not already allocated */
- if (!Malloc32.SpyedBlockTableLength) {
- if (!SetSpyedBlockTableLength(0x1000)) return 0;
- }
+ if (!Malloc32.SpyedBlockTableLength && !SetSpyedBlockTableLength(0x1000))
+ return FALSE;
Current = Malloc32.SpyedBlocks;
/* find the location */
while (*Current != pMem) {
Current++;
- if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) return 0; /* not found */
+ if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength)
+ return FALSE; /* not found */
}
/* location found */
Malloc32.SpyedAllocationsLeft--;
/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
*Current = NULL;
- return 1;
+ return TRUE;
}
/******************************************************************************
*/
static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
- BOOL fSpyed = 0;
+ BOOL fSpyed = FALSE;
TRACE("(%p)\n",pv);
static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
DWORD cb;
- BOOL fSpyed = 0;
+ BOOL fSpyed = FALSE;
TRACE("(%p)\n",pv);
*/
static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
- BOOL fSpyed = 0;
+ BOOL fSpyed = FALSE;
int didAlloc;
TRACE("(%p)\n",pv);
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#pragma makedep client
+
#include "wine/irot.idl"
ref = InterlockedDecrement(&This->ref);
- /* destroy the object if there's no more reference on it */
+ /* destroy the object if there are no more references to it */
if (ref == 0) ItemMonikerImpl_Destroy(This);
return ref;
HRESULT hr;
CLSID clsid;
- if ((hr = CoGetPSClsid(riid, &clsid)))
+ hr = CoGetPSClsid(riid, &clsid);
+ if (hr != S_OK)
return hr;
return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER | WINE_CLSCTX_DONT_HOST,
NULL, &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
/********************** StdMarshal implementation ****************************/
typedef struct _StdMarshalImpl
{
- const IMarshalVtbl *lpvtbl;
- LONG ref;
-
- IID iid;
- DWORD dwDestContext;
- LPVOID pvDestContext;
- DWORD mshlflags;
+ IMarshal IMarshal_iface;
+ LONG ref;
+ DWORD dest_context;
+ void *dest_context_data;
} StdMarshalImpl;
+static inline StdMarshalImpl *impl_from_StdMarshal(IMarshal *iface)
+{
+ return CONTAINING_RECORD(iface, StdMarshalImpl, IMarshal_iface);
+}
+
static HRESULT WINAPI
StdMarshalImpl_QueryInterface(IMarshal *iface, REFIID riid, void **ppv)
{
}
static ULONG WINAPI
-StdMarshalImpl_AddRef(LPMARSHAL iface)
+StdMarshalImpl_AddRef(IMarshal *iface)
{
- StdMarshalImpl *This = (StdMarshalImpl *)iface;
+ StdMarshalImpl *This = impl_from_StdMarshal(iface);
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI
-StdMarshalImpl_Release(LPMARSHAL iface)
+StdMarshalImpl_Release(IMarshal *iface)
{
- StdMarshalImpl *This = (StdMarshalImpl *)iface;
+ StdMarshalImpl *This = impl_from_StdMarshal(iface);
ULONG ref = InterlockedDecrement(&This->ref);
if (!ref) HeapFree(GetProcessHeap(),0,This);
static HRESULT WINAPI
StdMarshalImpl_GetUnmarshalClass(
- LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
+ IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
*pCid = CLSID_DfMarshal;
static HRESULT WINAPI
StdMarshalImpl_GetMarshalSizeMax(
- LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext,
+ IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{
*pSize = sizeof(STDOBJREF);
static HRESULT WINAPI
StdMarshalImpl_MarshalInterface(
- LPMARSHAL iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context,
+ IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context,
void* dest_context_data, DWORD mshlflags)
{
STDOBJREF stdobjref;
}
static HRESULT WINAPI
-StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
+StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
{
- StdMarshalImpl *This = (StdMarshalImpl *)iface;
+ StdMarshalImpl *This = impl_from_StdMarshal(iface);
struct stub_manager *stubmgr = NULL;
STDOBJREF stdobjref;
ULONG res;
wine_dbgstr_longlong(stdobjref.oxid));
if (hres == S_OK)
- hres = unmarshal_object(&stdobjref, apt, This->dwDestContext,
- This->pvDestContext, riid,
+ hres = unmarshal_object(&stdobjref, apt, This->dest_context,
+ This->dest_context_data, riid,
stubmgr ? &stubmgr->oxid_info : NULL, ppv);
if (stubmgr) stub_manager_int_release(stubmgr);
}
static HRESULT WINAPI
-StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
+StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
{
STDOBJREF stdobjref;
ULONG res;
}
static HRESULT WINAPI
-StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
+StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved)
{
FIXME("(), stub!\n");
return S_OK;
}
-static const IMarshalVtbl VT_StdMarshal =
+static const IMarshalVtbl StdMarshalVtbl =
{
StdMarshalImpl_QueryInterface,
StdMarshalImpl_AddRef,
StdMarshalImpl_DisconnectObject
};
-static HRESULT StdMarshalImpl_Construct(REFIID riid, void** ppvObject)
+static HRESULT StdMarshalImpl_Construct(REFIID riid, DWORD dest_context, void *dest_context_data, void** ppvObject)
{
- StdMarshalImpl * pStdMarshal =
- HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StdMarshalImpl));
+ HRESULT hr;
+
+ StdMarshalImpl *pStdMarshal = HeapAlloc(GetProcessHeap(), 0, sizeof(StdMarshalImpl));
if (!pStdMarshal)
return E_OUTOFMEMORY;
- pStdMarshal->lpvtbl = &VT_StdMarshal;
+
+ pStdMarshal->IMarshal_iface.lpVtbl = &StdMarshalVtbl;
pStdMarshal->ref = 0;
- return IMarshal_QueryInterface((IMarshal*)pStdMarshal, riid, ppvObject);
+ pStdMarshal->dest_context = dest_context;
+ pStdMarshal->dest_context_data = dest_context_data;
+
+ hr = IMarshal_QueryInterface(&pStdMarshal->IMarshal_iface, riid, ppvObject);
+ if (FAILED(hr))
+ HeapFree(GetProcessHeap(), 0, pStdMarshal);
+
+ return hr;
}
/***********************************************************************
DWORD dwDestContext, LPVOID pvDestContext,
DWORD mshlflags, LPMARSHAL *ppMarshal)
{
- StdMarshalImpl *dm;
-
if (pUnk == NULL)
{
FIXME("(%s,NULL,%x,%p,%x,%p), unimplemented yet.\n",
}
TRACE("(%s,%p,%x,%p,%x,%p)\n",
debugstr_guid(riid),pUnk,dwDestContext,pvDestContext,mshlflags,ppMarshal);
- *ppMarshal = HeapAlloc(GetProcessHeap(),0,sizeof(StdMarshalImpl));
- dm = (StdMarshalImpl*) *ppMarshal;
- if (!dm) return E_FAIL;
- dm->lpvtbl = &VT_StdMarshal;
- dm->ref = 1;
-
- dm->iid = *riid;
- dm->dwDestContext = dwDestContext;
- dm->pvDestContext = pvDestContext;
- dm->mshlflags = mshlflags;
- return S_OK;
+
+ return StdMarshalImpl_Construct(&IID_IMarshal, dwDestContext, pvDestContext, (void**)ppMarshal);
}
/***********************************************************************
if (objref.flags & OBJREF_STANDARD)
{
TRACE("Using standard unmarshaling\n");
- hr = StdMarshalImpl_Construct(&IID_IMarshal, (LPVOID*)marshal);
+ hr = StdMarshalImpl_Construct(&IID_IMarshal, 0, NULL, (LPVOID*)marshal);
}
else if (objref.flags & OBJREF_CUSTOM)
{
LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMarshal))
- return StdMarshalImpl_Construct(riid, ppv);
+ return StdMarshalImpl_Construct(riid, 0, NULL, ppv);
FIXME("(%s), not supported.\n",debugstr_guid(riid));
return E_NOINTERFACE;
ref = InterlockedDecrement(&This->ref);
- /* uninitialize ROT structure if there's no more references to it */
+ /* uninitialize ROT structure if there are no more references to it */
if (ref == 0)
{
struct list *cursor, *cursor2;
absFile=pathDec[nbElm-1];
/* failed if the path represents a directory and not an absolute file name*/
- if (!lstrcmpW(absFile, bkslashW))
+ if (!lstrcmpW(absFile, bkslashW)) {
+ CoTaskMemFree(pathDec);
return MK_E_INVALIDEXTENSION;
+ }
/* get the extension of the file */
extension = NULL;
for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
/* nothing */;
- if (!extension || !lstrcmpW(extension, dotW))
+ if (!extension || !lstrcmpW(extension, dotW)) {
+ CoTaskMemFree(pathDec);
return MK_E_INVALIDEXTENSION;
+ }
res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);
ref = InterlockedDecrement(&This->ref);
- /* uninitialize rot structure if there's no more reference to it*/
+ /* uninitialize ROT structure if there are no more references to it */
if (ref == 0)
{
ULONG i;
/******************************************************************************
* These are static/global variables and internal data structures that the
- * OLE module uses to maintain it's state.
+ * OLE module uses to maintain its state.
*/
typedef struct tagTrackerWindowInfo
{
BOOL escPressed;
HWND curTargetHWND; /* window the mouse is hovering over */
- HWND curDragTargetHWND; /* might be a ancestor of curTargetHWND */
+ HWND curDragTargetHWND; /* might be an ancestor of curTargetHWND */
IDropTarget* curDragTarget;
POINTL curMousePos; /* current position of the mouse in screen coordinates */
DWORD dwKeyState; /* current state of the shift and ctrl keys and the mouse buttons */
*/
static void OLEDD_Initialize(void);
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo);
static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo);
static DWORD OLEDD_GetButtonState(void);
*pdwStatus = 0;
+ if (actctx_get_miscstatus(clsid, dwAspect, pdwStatus)) return S_OK;
+
/*
* Open the class id Key
*/
if (SUCCEEDED(hres) && pClientSite)
/*
- * Inform the new object of it's client site.
+ * Inform the new object of its client site.
*/
hres = IOleObject_SetClientSite(pOleObject, pClientSite);
}
case WM_TIMER:
case WM_MOUSEMOVE:
- {
- OLEDD_TrackMouseMove((TrackerWindowInfo*)GetWindowLongPtrA(hwnd, 0));
- break;
- }
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
}
/***
- * OLEDD_TrackMouseMove()
+ * OLEDD_TrackStateChange()
*
* This method is invoked while a drag and drop operation is in effect.
- * it will generate the appropriate callbacks in the drop source
- * and drop target. It will also provide the expected feedback to
- * the user.
*
* params:
* trackerInfo - Pointer to the structure identifying the
* drag & drop operation that is currently
* active.
*/
-static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
+static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
{
HWND hwndNewTarget = 0;
HRESULT hr = S_OK;
pt.y = trackerInfo->curMousePos.y;
hwndNewTarget = WindowFromPoint(pt);
+ trackerInfo->returnValue = IDropSource_QueryContinueDrag(trackerInfo->dropSource,
+ trackerInfo->escPressed,
+ trackerInfo->dwKeyState);
+
/*
* Every time, we re-initialize the effects passed to the
* IDropTarget to the effects allowed by the source.
IDropTarget_DragOver(trackerInfo->curDragTarget,
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
- trackerInfo->pdwEffect);
+ trackerInfo->pdwEffect);
+ *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
}
else
{
trackerInfo->dwKeyState,
trackerInfo->curMousePos,
trackerInfo->pdwEffect);
+ *trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
/* failed DragEnter() means invalid target */
if (hr != S_OK)
SetCursor(hCur);
}
-}
-
-/***
- * OLEDD_TrackStateChange()
- *
- * This method is invoked while a drag and drop operation is in effect.
- * It is used to notify the drop target/drop source callbacks when
- * the state of the keyboard or mouse button change.
- *
- * params:
- * trackerInfo - Pointer to the structure identifying the
- * drag & drop operation that is currently
- * active.
- */
-static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
-{
- /*
- * Ask the drop source what to do with the operation.
- */
- trackerInfo->returnValue = IDropSource_QueryContinueDrag(
- trackerInfo->dropSource,
- trackerInfo->escPressed,
- trackerInfo->dwKeyState);
/*
* All the return valued will stop the operation except the S_OK
*/
case DRAGDROP_S_DROP:
if (*trackerInfo->pdwEffect != DROPEFFECT_NONE)
- IDropTarget_Drop(trackerInfo->curDragTarget,
- trackerInfo->dataObject,
- trackerInfo->dwKeyState,
- trackerInfo->curMousePos,
- trackerInfo->pdwEffect);
+ trackerInfo->returnValue = IDropTarget_Drop(trackerInfo->curDragTarget,
+ trackerInfo->dataObject,
+ trackerInfo->dwKeyState,
+ trackerInfo->curMousePos,
+ trackerInfo->pdwEffect);
else
IDropTarget_DragLeave(trackerInfo->curDragTarget);
break;
/*
* If the source told us that we should cancel, fool the drop
- * target by telling it that the mouse left it's window.
+ * target by telling it that the mouse left its window.
* Also set the drop effect to "NONE" in case the application
* ignores the result of DoDragDrop.
*/
*/
HRESULT WINAPI OleDoAutoConvert(LPSTORAGE pStg, LPCLSID pClsidNew)
{
- FIXME("(%p,%p) : stub\n",pStg,pClsidNew);
- return E_NOTIMPL;
+ WCHAR *user_type_old, *user_type_new;
+ CLIPFORMAT cf;
+ STATSTG stat;
+ CLSID clsid;
+ HRESULT hr;
+
+ TRACE("(%p, %p)\n", pStg, pClsidNew);
+
+ *pClsidNew = CLSID_NULL;
+ if(!pStg)
+ return E_INVALIDARG;
+ hr = IStorage_Stat(pStg, &stat, STATFLAG_NONAME);
+ if(FAILED(hr))
+ return hr;
+
+ *pClsidNew = stat.clsid;
+ hr = OleGetAutoConvert(&stat.clsid, &clsid);
+ if(FAILED(hr))
+ return hr;
+
+ hr = IStorage_SetClass(pStg, &clsid);
+ if(FAILED(hr))
+ return hr;
+
+ hr = ReadFmtUserTypeStg(pStg, &cf, &user_type_old);
+ if(FAILED(hr)) {
+ cf = 0;
+ user_type_new = NULL;
+ }
+
+ hr = OleRegGetUserType(&clsid, USERCLASSTYPE_FULL, &user_type_new);
+ if(FAILED(hr))
+ user_type_new = NULL;
+
+ hr = WriteFmtUserTypeStg(pStg, cf, user_type_new);
+ CoTaskMemFree(user_type_new);
+ if(FAILED(hr))
+ {
+ CoTaskMemFree(user_type_old);
+ IStorage_SetClass(pStg, &stat.clsid);
+ return hr;
+ }
+
+ hr = SetConvertStg(pStg, TRUE);
+ if(FAILED(hr))
+ {
+ WriteFmtUserTypeStg(pStg, cf, user_type_old);
+ IStorage_SetClass(pStg, &stat.clsid);
+ }
+ else
+ *pClsidNew = clsid;
+ CoTaskMemFree(user_type_old);
+ return hr;
}
/******************************************************************************
case VT_UI2:
case VT_UI4:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_LPSTR:
case VT_LPWSTR:
case VT_FILETIME:
hr = PROPVARIANT_ValidateType(pvar->vt);
if (FAILED(hr))
+ {
+ memset(pvar, 0, sizeof(*pvar));
return hr;
+ }
switch(pvar->vt)
{
case VT_UI2:
case VT_UI4:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_FILETIME:
break;
case VT_STREAM:
}
}
else
+ {
WARN("Invalid/unsupported type %d\n", pvar->vt);
+ hr = STG_E_INVALIDPARAMETER;
+ }
}
- ZeroMemory(pvar, sizeof(*pvar));
-
- return S_OK;
+ memset(pvar, 0, sizeof(*pvar));
+ return hr;
}
/***********************************************************************
case VT_ERROR:
case VT_I8:
case VT_UI8:
+ case VT_INT:
+ case VT_UINT:
case VT_R8:
case VT_CY:
case VT_DATE:
case VT_STREAMED_OBJECT:
case VT_STORAGE:
case VT_STORED_OBJECT:
- IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream);
+ if (pvarDest->u.pStream)
+ IStream_AddRef(pvarDest->u.pStream);
break;
case VT_CLSID:
pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID));
*pvarDest->u.puuid = *pvarSrc->u.puuid;
break;
case VT_LPSTR:
- len = strlen(pvarSrc->u.pszVal);
- pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR));
- CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR));
+ if (pvarSrc->u.pszVal)
+ {
+ len = strlen(pvarSrc->u.pszVal);
+ pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR));
+ CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR));
+ }
break;
case VT_LPWSTR:
- len = lstrlenW(pvarSrc->u.pwszVal);
- pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
- CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR));
+ if (pvarSrc->u.pwszVal)
+ {
+ len = lstrlenW(pvarSrc->u.pwszVal);
+ pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
+ CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR));
+ }
break;
case VT_BLOB:
case VT_BLOB_OBJECT:
return E_INVALIDARG;
}
len = pvarSrc->u.capropvar.cElems;
- pvarDest->u.capropvar.pElems = CoTaskMemAlloc(len * elemSize);
+ pvarDest->u.capropvar.pElems = len ? CoTaskMemAlloc(len * elemSize) : NULL;
if (pvarSrc->vt == (VT_VECTOR | VT_VARIANT))
{
for (i = 0; i < len; i++)
@ stdcall CoGetCurrentLogicalThreadId(ptr)
@ stdcall CoGetCurrentProcess()
@ stdcall CoGetDefaultContext(long ptr ptr)
-@ stub CoGetInstanceFromFile #@ stdcall (ptr ptr ptr long wstr long ptr) return 0,ERR_NOTIMPLEMENTED
-@ stub CoGetInstanceFromIStorage #@ stdcall (ptr ptr ptr long ptr long ptr) return 0,ERR_NOTIMPLEMENTED
+@ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr)
+@ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr)
@ stdcall CoGetInterfaceAndReleaseStream(ptr ptr ptr)
@ stdcall CoGetMalloc(long ptr)
@ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
@ stdcall CoResumeClassObjects()
@ stdcall CoRevertToSelf()
@ stdcall CoRevokeClassObject(long)
-@ stdcall CoRevokeInitializeSpy(double)
+@ stdcall CoRevokeInitializeSpy(int64)
@ stdcall CoRevokeMallocSpy()
@ stdcall CoSetProxyBlanket(ptr long long ptr long long ptr long)
@ stdcall CoSetState(ptr)
@ stdcall HWND_UserMarshal(ptr ptr ptr)
@ stdcall HWND_UserSize(ptr long ptr)
@ stdcall HWND_UserUnmarshal(ptr ptr ptr)
-@ stdcall IIDFromString(wstr ptr) CLSIDFromString
+@ stdcall IIDFromString(wstr ptr)
@ stub I_RemoteMain
@ stdcall IsAccelerator(long long ptr long)
@ stdcall IsEqualGUID(ptr ptr)
including objidl.h at some point. This will cause all sorts of errors
so the easiest thing to do is just comment out our entire header. */
+#pragma makedep proxy
+#pragma makedep register
+
cpp_quote("#if 0 /* ole32_objidl.idl hack */")
#include "objidl.idl"
cpp_quote("#endif /* ole32_objidl.idl hack */")
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#pragma makedep proxy
+#pragma makedep register
+
#include "oleidl.idl"
[
including unknwn.h at some point. This will cause all sorts of errors
so the easiest thing to do is just comment out our entire header. */
+#pragma makedep proxy
+#pragma makedep register
+
cpp_quote("#if 0 /* oleaut32_unknwn.idl hack */")
#include "unknwn.idl"
cpp_quote("#endif /* oleaut32_unknwn.idl hack */")
goto end;
}
/* wackiness alert: if the format ID is FMTID_DocSummaryInformation, there
- * follow not one, but two sections. The first is the standard properties
- * for the document summary information, and the second is user-defined
+ * follows not one, but two sections. The first contains the standard properties
+ * for the document summary information, and the second consists of user-defined
* properties. This is the only case in which multiple sections are
* allowed.
* Reading the second stream isn't implemented yet.
PropVariantInit(pvar);
}
- return 0;
+ return FALSE;
}
SERIALIZEDPROPERTYVALUE* WINAPI StgConvertVariantToProperty(const PROPVARIANT *pvar,
DirRef transactedParentEntry;
/* True if this entry is being used. */
- int inuse;
+ BOOL inuse;
/* True if data is up to date. */
- int read;
+ BOOL read;
/* True if this entry has been modified. */
- int dirty;
+ BOOL dirty;
/* True if this entry's stream has been modified. */
- int stream_dirty;
+ BOOL stream_dirty;
/* True if this entry has been deleted in the transacted storage, but the
* delete has not yet been committed. */
- int deleted;
+ BOOL deleted;
/* If this entry's stream has been modified, a reference to where the stream
* is stored in the snapshot file. */
* The root storage contains some element, therefore, start the research
* for the appropriate location.
*/
- BOOL found = 0;
+ BOOL found = FALSE;
DirRef current, next, previous, currentEntryId;
/*
next = currentEntry.rightChild;
current = currentEntryId;
- while (found == 0)
+ while (!found)
{
LONG diff = entryNameCmp( newEntry.name, currentEntry.name);
StorageBaseImpl_WriteDirEntry(This,
current,
¤tEntry);
- found = 1;
+ found = TRUE;
}
}
else if (diff > 0)
StorageBaseImpl_WriteDirEntry(This,
current,
¤tEntry);
- found = 1;
+ found = TRUE;
}
}
else
else
This->base.lockingrole = SWMR_None;
- This->base.reverted = 0;
+ This->base.reverted = FALSE;
/*
* Initialize the big block cache.
StorageBaseImpl_DeleteAll(&This->base);
- This->base.reverted = 1;
+ This->base.reverted = TRUE;
}
static void StorageImpl_Destroy(StorageBaseImpl* iface)
This->entries_size = new_size;
}
- This->entries[result].inuse = 1;
+ This->entries[result].inuse = TRUE;
This->firstFreeEntry = result+1;
entry->newTransactedParentEntry = entry->transactedParentEntry = parentEntryRef;
- entry->read = 0;
+ entry->read = FALSE;
}
return stubEntryRef;
if (SUCCEEDED(hr))
{
memcpy(&This->entries[entry].data, &data, sizeof(DirEntry));
- This->entries[entry].read = 1;
+ This->entries[entry].read = TRUE;
}
}
}
if (SUCCEEDED(hr))
- This->entries[entry].stream_dirty = 1;
+ This->entries[entry].stream_dirty = TRUE;
if (This->entries[entry].transactedParentEntry != DIRENTRY_NULL)
{
delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[entry].transactedParentEntry);
if (delete_ref != DIRENTRY_NULL)
- This->entries[delete_ref].deleted = 1;
+ This->entries[delete_ref].deleted = TRUE;
This->entries[entry].transactedParentEntry = This->entries[entry].newTransactedParentEntry = DIRENTRY_NULL;
}
{
StorageBaseImpl_StreamSetSize(This->scratch, entry->stream_entry, zero);
StorageBaseImpl_DestroyDirEntry(This->scratch, entry->stream_entry);
- entry->stream_dirty = 0;
+ entry->stream_dirty = FALSE;
}
- entry->dirty = 0;
+ entry->dirty = FALSE;
entry->transactedParentEntry = entry->newTransactedParentEntry;
}
}
{
TRACE("Storage invalidated (stg=%p)\n", This);
- This->reverted = 1;
+ This->reverted = TRUE;
StorageBaseImpl_DeleteAll(This);
}
new_entry = &This->entries[new_ref];
new_entry->newTransactedParentEntry = new_entry->transactedParentEntry = DIRENTRY_NULL;
- new_entry->read = 1;
- new_entry->dirty = 1;
+ new_entry->read = TRUE;
+ new_entry->dirty = TRUE;
memcpy(&new_entry->data, newData, sizeof(DirEntry));
*index = new_ref;
if (index != This->base.storageDirEntry)
{
- This->entries[index].dirty = 1;
+ This->entries[index].dirty = TRUE;
if (data->size.QuadPart == 0 &&
This->entries[index].transactedParentEntry != DIRENTRY_NULL)
delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry);
if (delete_ref != DIRENTRY_NULL)
- This->entries[delete_ref].deleted = 1;
+ This->entries[delete_ref].deleted = TRUE;
This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL;
}
}
else
{
- This->entries[index].deleted = 1;
+ This->entries[index].deleted = TRUE;
}
return S_OK;
This->entries[index].stream_entry, zero);
StorageBaseImpl_DestroyDirEntry(This->scratch,
This->entries[index].stream_entry);
- This->entries[index].stream_dirty = 0;
+ This->entries[index].stream_dirty = FALSE;
}
else if (This->entries[index].transactedParentEntry != DIRENTRY_NULL)
{
delete_ref = TransactedSnapshotImpl_CreateStubEntry(This, This->entries[index].transactedParentEntry);
if (delete_ref != DIRENTRY_NULL)
- This->entries[delete_ref].deleted = 1;
+ This->entries[delete_ref].deleted = TRUE;
This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL;
}
{
TRACE("Storage invalidated (stg=%p)\n", This);
- This->base.reverted = 1;
+ This->base.reverted = TRUE;
This->parentStorage = NULL;
newStorage->base.baseVtbl = &StorageInternalImpl_BaseVtbl;
newStorage->base.openFlags = (openFlags & ~STGM_CREATE);
- newStorage->base.reverted = 0;
+ newStorage->base.reverted = FALSE;
newStorage->base.ref = 1;
*/
newStorage->base.storageDirEntry = storageDirEntry;
- newStorage->base.create = 0;
+ newStorage->base.create = FALSE;
return newStorage;
}
{
if (!StorageImpl_WriteBigBlock(This->parentStorage, result->sector, result->data))
return STG_E_WRITEFAULT;
- result->dirty = 0;
+ result->dirty = FALSE;
}
- result->read = 0;
+ result->read = FALSE;
result->index = index;
result->sector = *sector;
}
newStream->indexCacheLen = 0;
newStream->indexCacheSize = 0;
newStream->cachedBlocks[0].index = 0xffffffff;
- newStream->cachedBlocks[0].dirty = 0;
+ newStream->cachedBlocks[0].dirty = FALSE;
newStream->cachedBlocks[1].index = 0xffffffff;
- newStream->cachedBlocks[1].dirty = 0;
+ newStream->cachedBlocks[1].dirty = FALSE;
newStream->blockToEvict = 0;
if (FAILED(BlockChainStream_UpdateIndexCache(newStream)))
if (This->cachedBlocks[i].dirty)
{
if (StorageImpl_WriteBigBlock(This->parentStorage, This->cachedBlocks[i].sector, This->cachedBlocks[i].data))
- This->cachedBlocks[i].dirty = 0;
+ This->cachedBlocks[i].dirty = FALSE;
else
return STG_E_WRITEFAULT;
}
if (FAILED(StorageImpl_ReadBigBlock(This->parentStorage, cachedBlock->sector, cachedBlock->data, &read)) && !read)
return STG_E_READFAULT;
- cachedBlock->read = 1;
+ cachedBlock->read = TRUE;
}
memcpy(bufferWalker, cachedBlock->data+offsetInBlock, bytesToReadInBuffer);
memcpy(cachedBlock->data+offsetInBlock, bufferWalker, bytesToWrite);
bytesWrittenAt = bytesToWrite;
- cachedBlock->read = 1;
- cachedBlock->dirty = 1;
+ cachedBlock->read = TRUE;
+ cachedBlock->dirty = TRUE;
}
blockNoInSequence++;
if (This->cachedBlocks[i].index >= numBlocks)
{
This->cachedBlocks[i].index = 0xffffffff;
- This->cachedBlocks[i].dirty = 0;
+ This->cachedBlocks[i].dirty = FALSE;
}
}
HANDLE hFile = 0;
DWORD shareMode;
DWORD accessMode;
+ LPWSTR temp_name = NULL;
TRACE("(%s, %p, %x, %p, %d, %p)\n",
debugstr_w(pwcsName), pstgPriority, grfMode,
snbExclude, reserved, ppstgOpen);
+ if (pstgPriority)
+ {
+ /* FIXME: Copy ILockBytes instead? But currently for STGM_PRIORITY it'll be read-only. */
+ hr = StorageBaseImpl_GetFilename((StorageBaseImpl*)pstgPriority, &temp_name);
+ if (FAILED(hr)) goto end;
+ pwcsName = temp_name;
+ TRACE("using filename %s\n", debugstr_w(temp_name));
+ }
+
if (pwcsName == 0)
{
hr = STG_E_INVALIDNAME;
*ppstgOpen = &newStorage->IStorage_iface;
end:
+ CoTaskMemFree(temp_name);
+ if (pstgPriority) IStorage_Release(pstgPriority);
TRACE("<-- %08x, IStorage %p\n", hr, ppstgOpen ? *ppstgOpen : NULL);
return hr;
}
len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
wstr = CoTaskMemAlloc( (len + 1)*sizeof (WCHAR) );
if( wstr )
+ {
MultiByteToWideChar( CP_ACP, 0, str, count, wstr, len );
+ wstr[len] = 0;
+ }
CoTaskMemFree( str );
*string = wstr;
HRESULT WINAPI WriteFmtUserTypeStg(
LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR lpszUserType)
{
+ STATSTG stat;
HRESULT r;
WCHAR szwClipName[0x40];
- CLSID clsid = CLSID_NULL;
+ CLSID clsid;
LPWSTR wstrProgID = NULL;
DWORD n;
TRACE("(%p,%x,%s)\n",pstg,cf,debugstr_w(lpszUserType));
/* get the clipboard format name */
- n = GetClipboardFormatNameW( cf, szwClipName, sizeof(szwClipName)/sizeof(szwClipName[0]) );
- szwClipName[n]=0;
+ if( cf )
+ {
+ n = GetClipboardFormatNameW( cf, szwClipName,
+ sizeof(szwClipName)/sizeof(szwClipName[0]) );
+ szwClipName[n]=0;
+ }
TRACE("Clipboard name is %s\n", debugstr_w(szwClipName));
- /* FIXME: There's room to save a CLSID and its ProgID, but
- the CLSID is not looked up in the registry and in all the
- tests I wrote it was CLSID_NULL. Where does it come from?
- */
+ r = IStorage_Stat(pstg, &stat, STATFLAG_NONAME);
+ if(SUCCEEDED(r))
+ clsid = stat.clsid;
+ else
+ clsid = CLSID_NULL;
- /* get the real program ID. This may fail, but that's fine */
ProgIDFromCLSID(&clsid, &wstrProgID);
TRACE("progid is %s\n",debugstr_w(wstrProgID));
- r = STORAGE_WriteCompObj( pstg, &clsid,
- lpszUserType, szwClipName, wstrProgID );
+ r = STORAGE_WriteCompObj( pstg, &clsid, lpszUserType,
+ cf ? szwClipName : NULL, wstrProgID );
CoTaskMemFree(wstrProgID);
*/
HRESULT WINAPI SetConvertStg(IStorage *storage, BOOL convert)
{
+ static const WCHAR stream_1oleW[] = {1,'O','l','e',0};
DWORD flags = convert ? OleStream_Convert : 0;
+ IStream *stream;
+ DWORD header[2];
HRESULT hr;
TRACE("(%p, %d)\n", storage, convert);
- hr = STORAGE_CreateOleStream(storage, flags);
- if (hr == STG_E_FILEALREADYEXISTS)
+ hr = IStorage_OpenStream(storage, stream_1oleW, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream);
+ if (FAILED(hr))
{
- static const WCHAR stream_1oleW[] = {1,'O','l','e',0};
- IStream *stream;
- DWORD header[2];
+ if (hr != STG_E_FILENOTFOUND)
+ return hr;
- hr = IStorage_OpenStream(storage, stream_1oleW, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream);
- if (FAILED(hr)) return hr;
+ return STORAGE_CreateOleStream(storage, flags);
+ }
- hr = IStream_Read(stream, header, sizeof(header), NULL);
+ hr = IStream_Read(stream, header, sizeof(header), NULL);
+ if (FAILED(hr))
+ {
+ IStream_Release(stream);
+ return hr;
+ }
+
+ /* update flag if differs */
+ if ((header[1] ^ flags) & OleStream_Convert)
+ {
+ LARGE_INTEGER pos = {{0}};
+
+ if (header[1] & OleStream_Convert)
+ flags = header[1] & ~OleStream_Convert;
+ else
+ flags = header[1] | OleStream_Convert;
+
+ pos.QuadPart = sizeof(DWORD);
+ hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
{
IStream_Release(stream);
return hr;
}
- /* update flag if differs */
- if ((header[1] ^ flags) & OleStream_Convert)
- {
- LARGE_INTEGER pos;
-
- if (header[1] & OleStream_Convert)
- flags = header[1] & ~OleStream_Convert;
- else
- flags = header[1] | OleStream_Convert;
-
- pos.QuadPart = sizeof(DWORD);
- hr = IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- {
- IStream_Release(stream);
- return hr;
- }
-
- hr = IStream_Write(stream, &flags, sizeof(flags), NULL);
- }
- IStream_Release(stream);
+ hr = IStream_Write(stream, &flags, sizeof(flags), NULL);
}
+ IStream_Release(stream);
return hr;
}
/*
* TRUE if this object has been invalidated
*/
- int reverted;
+ BOOL reverted;
/*
* Index of the directory entry of this storage
*/
DWORD stateBits;
- BOOL create; /* Was the storage created or opened.
- The behaviour of STGM_SIMPLE depends on this */
+ BOOL create; /* Was the storage created or opened.
+ The behaviour of STGM_SIMPLE depends on this */
/*
* If this storage was opened in transacted mode, the object that implements
* the transacted snapshot or cache.
{
ULONG index;
ULONG sector;
- int read;
- int dirty;
+ BOOL read;
+ BOOL dirty;
BYTE data[MAX_BIG_BLOCK_SIZE];
} BlockChainBlock;
* threads have a reference to it */
void apartment_disconnectobject(struct apartment *apt, void *object)
{
- int found = FALSE;
+ BOOL found = FALSE;
struct stub_manager *stubmgr;
EnterCriticalSection(&apt->cs);
TRACE("removed %u refs from %p (oid %s), rc is now %u\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
if (last_extern_ref && m->extern_conn)
- IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, TRUE /* FIXME: Use last_unlock releases? */);
+ IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, last_unlock_releases);
if (rc == 0)
- stub_manager_int_release(m);
+ if (!(m->extern_conn && last_unlock_releases && m->weakrefs))
+ stub_manager_int_release(m);
return rc;
}
else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
refs = 1;
- stub_manager_ext_release(m, refs, tableweak, FALSE);
+ stub_manager_ext_release(m, refs, tableweak, !tableweak);
}
/* is an ifstub table marshaled? */
* virtual methods in C++ and a structure with a table of pointer to functions in C.
* Unfortunately the layout of the virtual table is compiler specific, the layout of
* g++ virtual tables is not the same as that of an egcs virtual table which is not the
- * same as that generated by Visual C+. There are workarounds to make the virtual tables
+ * same as that generated by Visual C++. There are workarounds to make the virtual tables
* compatible via padding but unfortunately the one which is imposed to the WINE emulator
* by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
*
* - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions.
* - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE
* macro is defined in which case we would not be here.
- *
- *
- * Implementing a COM interface.
- *
- * This continues the above example. This example assumes that the implementation is in C.
- *
- * typedef struct IDirect3DImpl {
- * void* lpVtbl;
- * // ...
- *
- * } IDirect3DImpl;
- *
- * static IDirect3DVtbl d3dvt;
- *
- * // implement the IDirect3D methods here
- *
- * int IDirect3D_QueryInterface(IDirect3D* me)
- * {
- * IDirect3DImpl *This = (IDirect3DImpl *)me;
- * // ...
- * }
- *
- * // ...
- *
- * static IDirect3DVtbl d3dvt = {
- * IDirect3D_QueryInterface,
- * IDirect3D_Add,
- * IDirect3D_Add2,
- * IDirect3D_Initialize,
- * IDirect3D_SetWidth
- * };
- *
- * Comments:
- * - We first define what the interface really contains. This is the IDirect3DImpl structure. The
- * first field must of course be the virtual table pointer. Everything else is free.
- * - Then we predeclare our static virtual table variable, we will need its address in some
- * methods to initialize the virtual table pointer of the returned interface objects.
- * - Then we implement the interface methods. To match what has been declared in the header file
- * they must take a pointer to an IDirect3D structure and we must cast it to an IDirect3DImpl so
- * that we can manipulate the fields.
- * - Finally we initialize the virtual table.
*/
#if defined(__cplusplus) && !defined(CINTERFACE)
_Out_writes_to_(cmax, return) LPOLESTR str,
_In_ INT cmax);
+_Check_return_
+HRESULT
+WINAPI
+IIDFromString(
+ _In_ LPCOLESTR lpsz,
+ _Out_ LPIID lpiid);
+
/*****************************************************************************
* COM Server dll - exports
*/
reactos/dll/win32/objsel # Synced to Wine-1.7.1
reactos/dll/win32/odbc32 # Synced to Wine-1.7.17. Depends on port of Linux ODBC.
reactos/dll/win32/odbccp32 # Synced to Wine-1.7.1
-reactos/dll/win32/ole32 # Synced to Wine-1.7.1
+reactos/dll/win32/ole32 # Synced to Wine-1.7.17
reactos/dll/win32/oleacc # Synced to Wine-1.7.1
reactos/dll/win32/oleaut32 # Synced to Wine-1.7.1
reactos/dll/win32/olecli32 # Synced to Wine-1.7.1