mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[OLE32]
* Sync with Wine 1.7.27. CORE-8540 svn path=/trunk/; revision=64491
This commit is contained in:
parent
0f7a9e0894
commit
9fd8bd9a43
8 changed files with 1371 additions and 335 deletions
|
@ -314,7 +314,7 @@ static const WCHAR classes_rootW[] =
|
|||
static HKEY classes_root_hkey;
|
||||
|
||||
/* create the special HKEY_CLASSES_ROOT key */
|
||||
static HKEY create_classes_root_hkey(void)
|
||||
static HKEY create_classes_root_hkey(DWORD access)
|
||||
{
|
||||
HKEY hkey, ret = 0;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
|
@ -327,23 +327,39 @@ static HKEY create_classes_root_hkey(void)
|
|||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &name, classes_rootW );
|
||||
if (create_key( &hkey, MAXIMUM_ALLOWED, &attr )) return 0;
|
||||
if (create_key( &hkey, access, &attr )) return 0;
|
||||
TRACE( "%s -> %p\n", debugstr_w(attr.ObjectName->Buffer), hkey );
|
||||
|
||||
if (!(ret = InterlockedCompareExchangePointer( (void **)&classes_root_hkey, hkey, 0 )))
|
||||
ret = hkey;
|
||||
if (!(access & KEY_WOW64_64KEY))
|
||||
{
|
||||
if (!(ret = InterlockedCompareExchangePointer( (void **)&classes_root_hkey, hkey, 0 )))
|
||||
ret = hkey;
|
||||
else
|
||||
NtClose( hkey ); /* somebody beat us to it */
|
||||
}
|
||||
else
|
||||
NtClose( hkey ); /* somebody beat us to it */
|
||||
ret = hkey;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* map the hkey from special root to normal key if necessary */
|
||||
static inline HKEY get_classes_root_hkey( HKEY hkey )
|
||||
static inline HKEY get_classes_root_hkey( HKEY hkey, REGSAM access )
|
||||
{
|
||||
HKEY ret = hkey;
|
||||
const BOOL is_win64 = sizeof(void*) > sizeof(int);
|
||||
const BOOL force_wow32 = is_win64 && (access & KEY_WOW64_32KEY);
|
||||
|
||||
if (hkey == HKEY_CLASSES_ROOT && !(ret = classes_root_hkey))
|
||||
ret = create_classes_root_hkey();
|
||||
if (hkey == HKEY_CLASSES_ROOT &&
|
||||
((access & KEY_WOW64_64KEY) || !(ret = classes_root_hkey)))
|
||||
ret = create_classes_root_hkey(MAXIMUM_ALLOWED | (access & KEY_WOW64_64KEY));
|
||||
if (force_wow32 && ret && ret == classes_root_hkey)
|
||||
{
|
||||
static const WCHAR wow6432nodeW[] = {'W','o','w','6','4','3','2','N','o','d','e',0};
|
||||
access &= ~KEY_WOW64_32KEY;
|
||||
if (create_classes_key(classes_root_hkey, wow6432nodeW, access, &hkey))
|
||||
return 0;
|
||||
ret = hkey;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -353,7 +369,7 @@ LSTATUS create_classes_key( HKEY hkey, const WCHAR *name, REGSAM access, HKEY *r
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
|
||||
if (!(hkey = get_classes_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
|
||||
if (!(hkey = get_classes_root_hkey( hkey, access ))) return ERROR_INVALID_HANDLE;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = hkey;
|
||||
|
@ -371,7 +387,7 @@ LSTATUS open_classes_key( HKEY hkey, const WCHAR *name, REGSAM access, HKEY *ret
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
|
||||
if (!(hkey = get_classes_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
|
||||
if (!(hkey = get_classes_root_hkey( hkey, access ))) return ERROR_INVALID_HANDLE;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = hkey;
|
||||
|
@ -1174,7 +1190,7 @@ DWORD apartment_release(struct apartment *apt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* The given OXID must be local to this process:
|
||||
/* The given OXID must be local to this process:
|
||||
*
|
||||
* The ref parameter is here mostly to ensure people remember that
|
||||
* they get one, you should normally take a ref for thread safety.
|
||||
|
@ -1639,14 +1655,27 @@ static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context
|
|||
* already been created */
|
||||
HRESULT apartment_createwindowifneeded(struct apartment *apt)
|
||||
{
|
||||
#ifndef __REACTOS__
|
||||
static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT;
|
||||
#endif
|
||||
|
||||
if (apt->multi_threaded)
|
||||
return S_OK;
|
||||
|
||||
if (!apt->win)
|
||||
{
|
||||
#ifndef __REACTOS__
|
||||
HWND hwnd;
|
||||
|
||||
InitOnceExecuteOnce( &class_init_once, register_class, NULL, NULL );
|
||||
|
||||
hwnd = CreateWindowW(wszAptWinClass, NULL, 0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE, 0, hProxyDll, NULL);
|
||||
#else
|
||||
HWND hwnd = CreateWindowW(wszAptWinClass, NULL, 0,
|
||||
0, 0, 0, 0,
|
||||
HWND_MESSAGE, 0, hProxyDll, NULL);
|
||||
#endif
|
||||
if (!hwnd)
|
||||
{
|
||||
ERR("CreateWindow failed with error %d\n", GetLastError());
|
||||
|
@ -2054,7 +2083,11 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
|||
*/
|
||||
HRESULT WINAPI CoCreateGuid(GUID *pguid)
|
||||
{
|
||||
DWORD status = UuidCreate(pguid);
|
||||
DWORD status;
|
||||
|
||||
if(!pguid) return E_INVALIDARG;
|
||||
|
||||
status = UuidCreate(pguid);
|
||||
if (status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY) return S_OK;
|
||||
return HRESULT_FROM_WIN32( status );
|
||||
}
|
||||
|
@ -2474,6 +2507,28 @@ HRESULT WINAPI CLSIDFromProgIDEx(LPCOLESTR progid, LPCLSID clsid)
|
|||
return CLSIDFromProgID(progid, clsid);
|
||||
}
|
||||
|
||||
static HRESULT get_ps_clsid_from_registry(const WCHAR* path, REGSAM access, CLSID *pclsid)
|
||||
{
|
||||
HKEY hkey;
|
||||
WCHAR value[CHARS_IN_GUID];
|
||||
DWORD len;
|
||||
|
||||
access |= KEY_READ;
|
||||
|
||||
if (open_classes_key(HKEY_CLASSES_ROOT, path, access, &hkey))
|
||||
return REGDB_E_IIDNOTREG;
|
||||
|
||||
len = sizeof(value);
|
||||
if (ERROR_SUCCESS != RegQueryValueExW(hkey, NULL, NULL, NULL, (BYTE *)value, &len))
|
||||
return REGDB_E_IIDNOTREG;
|
||||
RegCloseKey(hkey);
|
||||
|
||||
if (CLSIDFromString(value, pclsid) != NOERROR)
|
||||
return REGDB_E_IIDNOTREG;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* CoGetPSClsid [OLE32.@]
|
||||
*
|
||||
|
@ -2483,7 +2538,7 @@ HRESULT WINAPI CLSIDFromProgIDEx(LPCOLESTR progid, LPCLSID clsid)
|
|||
* PARAMS
|
||||
* riid [I] Interface whose proxy/stub CLSID is to be returned.
|
||||
* pclsid [O] Where to store returned proxy/stub CLSID.
|
||||
*
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK
|
||||
* E_OUTOFMEMORY
|
||||
|
@ -2515,12 +2570,12 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0};
|
||||
static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
|
||||
WCHAR path[ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAYSIZE(wszPSC)];
|
||||
WCHAR value[CHARS_IN_GUID];
|
||||
LONG len;
|
||||
HKEY hkey;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
struct registered_psclsid *registered_psclsid;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
HRESULT hr;
|
||||
REGSAM opposite = (sizeof(void*) > sizeof(int)) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
|
||||
BOOL is_wow64;
|
||||
|
||||
TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
|
||||
|
||||
|
@ -2559,31 +2614,17 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID);
|
||||
strcpyW(path + ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
|
||||
|
||||
/* Open the key.. */
|
||||
if (open_classes_key(HKEY_CLASSES_ROOT, path, KEY_READ, &hkey))
|
||||
{
|
||||
hr = get_ps_clsid_from_registry(path, 0, pclsid);
|
||||
if (FAILED(hr) && (opposite == KEY_WOW64_32KEY ||
|
||||
(IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
|
||||
hr = get_ps_clsid_from_registry(path, opposite, pclsid);
|
||||
|
||||
if (hr == S_OK)
|
||||
TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid));
|
||||
else
|
||||
WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
|
||||
return REGDB_E_IIDNOTREG;
|
||||
}
|
||||
|
||||
/* ... Once we have the key, query the registry to get the
|
||||
value of CLSID as a string, and convert it into a
|
||||
proper CLSID structure to be passed back to the app */
|
||||
len = sizeof(value);
|
||||
if (ERROR_SUCCESS != RegQueryValueW(hkey, NULL, value, &len))
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
return REGDB_E_IIDNOTREG;
|
||||
}
|
||||
RegCloseKey(hkey);
|
||||
|
||||
/* We have the CLSID we want back from the registry as a string, so
|
||||
let's convert it into a CLSID structure */
|
||||
if (CLSIDFromString(value, pclsid) != NOERROR)
|
||||
return REGDB_E_IIDNOTREG;
|
||||
|
||||
TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid));
|
||||
return S_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -2595,7 +2636,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
* PARAMS
|
||||
* riid [I] Interface whose proxy/stub CLSID is to be registered.
|
||||
* rclsid [I] CLSID of the proxy/stub.
|
||||
*
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: E_OUTOFMEMORY
|
||||
|
@ -3159,6 +3200,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
|
|||
HRESULT hres;
|
||||
LPCLASSFACTORY lpclf = 0;
|
||||
APARTMENT *apt;
|
||||
CLSID clsid;
|
||||
|
||||
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
|
||||
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
|
||||
|
@ -3166,6 +3208,10 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
|
|||
if (ppv==0)
|
||||
return E_POINTER;
|
||||
|
||||
hres = CoGetTreatAsClass(rclsid, &clsid);
|
||||
if(FAILED(hres))
|
||||
clsid = *rclsid;
|
||||
|
||||
*ppv = 0;
|
||||
|
||||
if (!(apt = COM_CurrentApt()))
|
||||
|
@ -3181,7 +3227,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
|
|||
/*
|
||||
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
|
||||
*/
|
||||
if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable))
|
||||
if (IsEqualIID(&clsid, &CLSID_StdGlobalInterfaceTable))
|
||||
{
|
||||
IGlobalInterfaceTable *git = get_std_git();
|
||||
hres = IGlobalInterfaceTable_QueryInterface(git, iid, ppv);
|
||||
|
@ -3191,13 +3237,13 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if (IsEqualCLSID(rclsid, &CLSID_ManualResetEvent))
|
||||
if (IsEqualCLSID(&clsid, &CLSID_ManualResetEvent))
|
||||
return ManualResetEvent_Construct(pUnkOuter, iid, ppv);
|
||||
|
||||
/*
|
||||
* Get a class factory to construct the object we want.
|
||||
*/
|
||||
hres = CoGetClassObject(rclsid,
|
||||
hres = CoGetClassObject(&clsid,
|
||||
dwClsContext,
|
||||
NULL,
|
||||
&IID_IClassFactory,
|
||||
|
@ -3214,11 +3260,11 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
|
|||
if (FAILED(hres))
|
||||
{
|
||||
if (hres == CLASS_E_NOAGGREGATION && pUnkOuter)
|
||||
FIXME("Class %s does not support aggregation\n", debugstr_guid(rclsid));
|
||||
FIXME("Class %s does not support aggregation\n", debugstr_guid(&clsid));
|
||||
else
|
||||
FIXME("no instance created for interface %s of class %s, hres is 0x%08x\n",
|
||||
debugstr_guid(iid),
|
||||
debugstr_guid(rclsid),hres);
|
||||
debugstr_guid(&clsid),hres);
|
||||
}
|
||||
|
||||
return hres;
|
||||
|
@ -3321,7 +3367,7 @@ HRESULT WINAPI CoGetInstanceFromFile(
|
|||
|
||||
init_multi_qi(count, results);
|
||||
|
||||
/* optionaly get CLSID from a file */
|
||||
/* optionally get CLSID from a file */
|
||||
if (!rclsid)
|
||||
{
|
||||
hr = GetClassFile(filename, &clsid);
|
||||
|
@ -3383,7 +3429,7 @@ HRESULT WINAPI CoGetInstanceFromIStorage(
|
|||
|
||||
init_multi_qi(count, results);
|
||||
|
||||
/* optionaly get CLSID from a file */
|
||||
/* optionally get CLSID from a file */
|
||||
if (!rclsid)
|
||||
{
|
||||
memset(&stat.clsid, 0, sizeof(stat.clsid));
|
||||
|
@ -3577,14 +3623,14 @@ HRESULT WINAPI CoLockObjectExternal(
|
|||
if (!apt) return CO_E_NOTINITIALIZED;
|
||||
|
||||
stubmgr = get_stub_manager_from_object(apt, pUnk);
|
||||
|
||||
|
||||
if (stubmgr)
|
||||
{
|
||||
if (fLock)
|
||||
stub_manager_ext_addref(stubmgr, 1, FALSE);
|
||||
else
|
||||
stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases);
|
||||
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
|
||||
return S_OK;
|
||||
|
@ -3730,7 +3776,8 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
|
|||
res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
|
||||
if (FAILED(res))
|
||||
goto done;
|
||||
if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
|
||||
|
||||
if (IsEqualGUID( clsidOld, clsidNew ))
|
||||
{
|
||||
if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) &&
|
||||
CLSIDFromString(auto_treat_as, &id) == S_OK)
|
||||
|
@ -3743,15 +3790,28 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
|
|||
}
|
||||
else
|
||||
{
|
||||
RegDeleteKeyW(hkey, wszTreatAs);
|
||||
if(RegDeleteKeyW(hkey, wszTreatAs))
|
||||
res = REGDB_E_WRITEREGDB;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (!StringFromGUID2(clsidNew, szClsidNew, ARRAYSIZE(szClsidNew)) &&
|
||||
!RegSetValueW(hkey, wszTreatAs, REG_SZ, szClsidNew, sizeof(szClsidNew)))
|
||||
else
|
||||
{
|
||||
res = REGDB_E_WRITEREGDB;
|
||||
goto done;
|
||||
if(IsEqualGUID(clsidNew, &CLSID_NULL)){
|
||||
RegDeleteKeyW(hkey, wszTreatAs);
|
||||
}else{
|
||||
if(!StringFromGUID2(clsidNew, szClsidNew, ARRAYSIZE(szClsidNew))){
|
||||
WARN("StringFromGUID2 failed\n");
|
||||
res = E_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(RegSetValueW(hkey, wszTreatAs, REG_SZ, szClsidNew, sizeof(szClsidNew)) != ERROR_SUCCESS){
|
||||
WARN("RegSetValue failed\n");
|
||||
res = REGDB_E_WRITEREGDB;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -4037,7 +4097,7 @@ HRESULT WINAPI CoAllowSetForegroundWindow(IUnknown *pUnk, void *pvReserved)
|
|||
FIXME("(%p, %p): stub\n", pUnk, pvReserved);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CoQueryProxyBlanket [OLE32.@]
|
||||
*
|
||||
|
@ -4987,13 +5047,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
|
|||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hProxyDll = hinstDLL;
|
||||
#ifdef __REACTOS__
|
||||
COMPOBJ_InitProcess();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (reserved) break;
|
||||
release_std_git();
|
||||
#ifdef __REACTOS__
|
||||
COMPOBJ_UninitProcess();
|
||||
#else
|
||||
UnregisterClassW( wszAptWinClass, hProxyDll );
|
||||
#endif
|
||||
RPC_UnregisterAllChannelHooks();
|
||||
COMPOBJ_DllList_Free();
|
||||
DeleteCriticalSection(&csRegisteredClassList);
|
||||
|
|
|
@ -29,7 +29,6 @@ typedef struct FileLockBytesImpl
|
|||
{
|
||||
ILockBytes ILockBytes_iface;
|
||||
LONG ref;
|
||||
ULARGE_INTEGER filesize;
|
||||
HANDLE hfile;
|
||||
DWORD flProtect;
|
||||
LPWSTR pwcsName;
|
||||
|
@ -88,8 +87,6 @@ HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsN
|
|||
This->ILockBytes_iface.lpVtbl = &FileLockBytesImpl_Vtbl;
|
||||
This->ref = 1;
|
||||
This->hfile = hFile;
|
||||
This->filesize.u.LowPart = GetFileSize(This->hfile,
|
||||
&This->filesize.u.HighPart);
|
||||
This->flProtect = GetProtectMode(openFlags);
|
||||
|
||||
if(pwcsName) {
|
||||
|
@ -109,8 +106,6 @@ HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsN
|
|||
else
|
||||
This->pwcsName = NULL;
|
||||
|
||||
TRACE("file len %u\n", This->filesize.u.LowPart);
|
||||
|
||||
*pLockBytes = &This->ILockBytes_iface;
|
||||
|
||||
return S_OK;
|
||||
|
@ -228,7 +223,6 @@ static HRESULT WINAPI FileLockBytesImpl_WriteAt(
|
|||
ULONG* pcbWritten) /* [out] */
|
||||
{
|
||||
FileLockBytesImpl* This = impl_from_ILockBytes(iface);
|
||||
ULONG size_needed = ulOffset.u.LowPart + cb;
|
||||
ULONG bytes_left = cb;
|
||||
const BYTE *writePtr = pv;
|
||||
BOOL ret;
|
||||
|
@ -246,27 +240,19 @@ static HRESULT WINAPI FileLockBytesImpl_WriteAt(
|
|||
if (pcbWritten)
|
||||
*pcbWritten = 0;
|
||||
|
||||
if (size_needed > This->filesize.u.LowPart)
|
||||
{
|
||||
ULARGE_INTEGER newSize;
|
||||
newSize.u.HighPart = 0;
|
||||
newSize.u.LowPart = size_needed;
|
||||
ILockBytes_SetSize(iface, newSize);
|
||||
}
|
||||
|
||||
offset.QuadPart = ulOffset.QuadPart;
|
||||
|
||||
ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN);
|
||||
|
||||
if (!ret)
|
||||
return STG_E_READFAULT;
|
||||
return STG_E_WRITEFAULT;
|
||||
|
||||
while (bytes_left)
|
||||
{
|
||||
ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL);
|
||||
|
||||
if (!ret)
|
||||
return STG_E_READFAULT;
|
||||
return STG_E_WRITEFAULT;
|
||||
|
||||
if (pcbWritten)
|
||||
*pcbWritten += cbWritten;
|
||||
|
@ -296,10 +282,7 @@ static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes* iface, ULARGE_INTEGE
|
|||
HRESULT hr = S_OK;
|
||||
LARGE_INTEGER newpos;
|
||||
|
||||
if (This->filesize.u.LowPart == newSize.u.LowPart)
|
||||
return hr;
|
||||
|
||||
TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart);
|
||||
TRACE("new size %u\n", newSize.u.LowPart);
|
||||
|
||||
newpos.QuadPart = newSize.QuadPart;
|
||||
if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN))
|
||||
|
@ -307,22 +290,82 @@ static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes* iface, ULARGE_INTEGE
|
|||
SetEndOfFile(This->hfile);
|
||||
}
|
||||
|
||||
This->filesize = newSize;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT get_lock_error(void)
|
||||
{
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_LOCK_VIOLATION: return STG_E_LOCKVIOLATION; break;
|
||||
case ERROR_ACCESS_DENIED: return STG_E_ACCESSDENIED; break;
|
||||
case ERROR_NOT_SUPPORTED: return STG_E_INVALIDFUNCTION; break;
|
||||
default:
|
||||
FIXME("no mapping for error %d\n", GetLastError());
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
FileLockBytesImpl* This = impl_from_ILockBytes(iface);
|
||||
OVERLAPPED ol;
|
||||
DWORD lock_flags = LOCKFILE_FAIL_IMMEDIATELY;
|
||||
|
||||
TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
|
||||
|
||||
if (dwLockType & LOCK_WRITE)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
if (dwLockType & (LOCK_EXCLUSIVE|LOCK_ONLYONCE))
|
||||
lock_flags |= LOCKFILE_EXCLUSIVE_LOCK;
|
||||
|
||||
ol.hEvent = 0;
|
||||
ol.u.s.Offset = libOffset.u.LowPart;
|
||||
ol.u.s.OffsetHigh = libOffset.u.HighPart;
|
||||
|
||||
if (LockFileEx(This->hfile, lock_flags, 0, cb.u.LowPart, cb.u.HighPart, &ol))
|
||||
return S_OK;
|
||||
return get_lock_error();
|
||||
}
|
||||
|
||||
HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb)
|
||||
{
|
||||
FileLockBytesImpl* This = impl_from_ILockBytes(iface);
|
||||
OVERLAPPED ol;
|
||||
|
||||
if (iface->lpVtbl != &FileLockBytesImpl_Vtbl)
|
||||
return E_NOTIMPL;
|
||||
|
||||
ol.hEvent = 0;
|
||||
ol.u.s.Offset = libOffset.u.LowPart;
|
||||
ol.u.s.OffsetHigh = libOffset.u.HighPart;
|
||||
|
||||
if (LockFileEx(This->hfile, LOCKFILE_EXCLUSIVE_LOCK, 0, cb.u.LowPart, cb.u.HighPart, &ol))
|
||||
return S_OK;
|
||||
return get_lock_error();
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileLockBytesImpl_UnlockRegion(ILockBytes* iface,
|
||||
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
|
||||
{
|
||||
FIXME("stub\n");
|
||||
return E_NOTIMPL;
|
||||
FileLockBytesImpl* This = impl_from_ILockBytes(iface);
|
||||
OVERLAPPED ol;
|
||||
|
||||
TRACE("ofs %u count %u flags %x\n", libOffset.u.LowPart, cb.u.LowPart, dwLockType);
|
||||
|
||||
if (dwLockType & LOCK_WRITE)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
ol.hEvent = 0;
|
||||
ol.u.s.Offset = libOffset.u.LowPart;
|
||||
ol.u.s.OffsetHigh = libOffset.u.HighPart;
|
||||
|
||||
if (UnlockFileEx(This->hfile, 0, cb.u.LowPart, cb.u.HighPart, &ol))
|
||||
return S_OK;
|
||||
return get_lock_error();
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
|
||||
|
@ -341,7 +384,8 @@ static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
|
|||
pstatstg->pwcsName = NULL;
|
||||
|
||||
pstatstg->type = STGTY_LOCKBYTES;
|
||||
pstatstg->cbSize = This->filesize;
|
||||
|
||||
pstatstg->cbSize.u.LowPart = GetFileSize(This->hfile, &pstatstg->cbSize.u.HighPart);
|
||||
/* FIXME: If the implementation is exported, we'll need to set other fields. */
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -588,22 +588,11 @@ FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLef
|
|||
/* get the file name */
|
||||
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
|
||||
|
||||
/* verify if the file contains a storage object */
|
||||
res=StgIsStorageFile(filePath);
|
||||
res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
|
||||
|
||||
if(res==S_OK){
|
||||
if (SUCCEEDED(res))
|
||||
*ppvObject=pstg;
|
||||
|
||||
res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
|
||||
|
||||
if (SUCCEEDED(res)){
|
||||
|
||||
*ppvObject=pstg;
|
||||
|
||||
IStorage_AddRef(pstg);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
CoTaskMemFree(filePath);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2179,7 +2179,9 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
|
|||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
{
|
||||
OLEDD_TrackStateChange((TrackerWindowInfo*)GetWindowLongPtrA(hwnd, 0));
|
||||
TrackerWindowInfo *trackerInfo = (TrackerWindowInfo*)GetWindowLongPtrA(hwnd, 0);
|
||||
if (trackerInfo->trackingDone) break;
|
||||
OLEDD_TrackStateChange(trackerInfo);
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
|
@ -2843,6 +2845,8 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt)
|
|||
case VT_LPWSTR:
|
||||
case VT_FILETIME:
|
||||
case VT_BLOB:
|
||||
case VT_DISPATCH:
|
||||
case VT_UNKNOWN:
|
||||
case VT_STREAM:
|
||||
case VT_STORAGE:
|
||||
case VT_STREAMED_OBJECT:
|
||||
|
@ -2919,6 +2923,8 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
|
|||
case VT_UINT:
|
||||
case VT_FILETIME:
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
case VT_UNKNOWN:
|
||||
case VT_STREAM:
|
||||
case VT_STREAMED_OBJECT:
|
||||
case VT_STORAGE:
|
||||
|
@ -3032,6 +3038,8 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
|
|||
case VT_DATE:
|
||||
case VT_FILETIME:
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
case VT_UNKNOWN:
|
||||
case VT_STREAM:
|
||||
case VT_STREAMED_OBJECT:
|
||||
case VT_STORAGE:
|
||||
|
|
|
@ -151,7 +151,7 @@ static HRESULT WINAPI StgStreamImpl_Read(
|
|||
/*
|
||||
* Advance the pointer for the number of positions read.
|
||||
*/
|
||||
This->currentPosition.u.LowPart += *pcbRead;
|
||||
This->currentPosition.QuadPart += *pcbRead;
|
||||
}
|
||||
|
||||
TRACE("<-- %08x\n", res);
|
||||
|
@ -232,12 +232,12 @@ static HRESULT WINAPI StgStreamImpl_Write(
|
|||
/*
|
||||
* Advance the position pointer for the number of positions written.
|
||||
*/
|
||||
This->currentPosition.u.LowPart += *pcbWritten;
|
||||
This->currentPosition.QuadPart += *pcbWritten;
|
||||
|
||||
if (SUCCEEDED(res))
|
||||
res = StorageBaseImpl_Flush(This->parentStorage);
|
||||
|
||||
TRACE("<-- S_OK, written %u\n", *pcbWritten);
|
||||
TRACE("<-- %08x, written %u\n", res, *pcbWritten);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -42,6 +42,7 @@ static const ULONG OFFSET_SMALLBLOCKSIZEBITS = 0x00000020;
|
|||
static const ULONG OFFSET_DIRSECTORCOUNT = 0x00000028;
|
||||
static const ULONG OFFSET_BBDEPOTCOUNT = 0x0000002C;
|
||||
static const ULONG OFFSET_ROOTSTARTBLOCK = 0x00000030;
|
||||
static const ULONG OFFSET_TRANSACTIONSIG = 0x00000034;
|
||||
static const ULONG OFFSET_SMALLBLOCKLIMIT = 0x00000038;
|
||||
static const ULONG OFFSET_SBDEPOTSTART = 0x0000003C;
|
||||
static const ULONG OFFSET_SBDEPOTCOUNT = 0x00000040;
|
||||
|
@ -61,6 +62,7 @@ static const ULONG OFFSET_PS_MTIMELOW = 0x0000006C;
|
|||
static const ULONG OFFSET_PS_MTIMEHIGH = 0x00000070;
|
||||
static const ULONG OFFSET_PS_STARTBLOCK = 0x00000074;
|
||||
static const ULONG OFFSET_PS_SIZE = 0x00000078;
|
||||
static const ULONG OFFSET_PS_SIZE_HIGH = 0x0000007C;
|
||||
static const WORD DEF_BIG_BLOCK_SIZE_BITS = 0x0009;
|
||||
static const WORD MIN_BIG_BLOCK_SIZE_BITS = 0x0009;
|
||||
static const WORD MAX_BIG_BLOCK_SIZE_BITS = 0x000c;
|
||||
|
@ -147,6 +149,8 @@ struct DirEntry
|
|||
|
||||
HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, LPCWSTR pwcsName, ILockBytes **pLockBytes) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT FileLockBytesImpl_LockRegionSync(ILockBytes* iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb) DECLSPEC_HIDDEN;
|
||||
|
||||
/*************************************************************************
|
||||
* Ole Convert support
|
||||
*/
|
||||
|
@ -237,6 +241,10 @@ struct StorageBaseImplVtbl {
|
|||
HRESULT (*StreamWriteAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,const void*,ULONG*);
|
||||
HRESULT (*StreamSetSize)(StorageBaseImpl*,DirRef,ULARGE_INTEGER);
|
||||
HRESULT (*StreamLink)(StorageBaseImpl*,DirRef,DirRef);
|
||||
HRESULT (*GetTransactionSig)(StorageBaseImpl*,ULONG*,BOOL);
|
||||
HRESULT (*SetTransactionSig)(StorageBaseImpl*,ULONG);
|
||||
HRESULT (*LockTransaction)(StorageBaseImpl*,BOOL);
|
||||
HRESULT (*UnlockTransaction)(StorageBaseImpl*,BOOL);
|
||||
};
|
||||
|
||||
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
|
||||
|
@ -314,6 +322,28 @@ static inline HRESULT StorageBaseImpl_StreamLink(StorageBaseImpl *This,
|
|||
return This->baseVtbl->StreamLink(This, dst, src);
|
||||
}
|
||||
|
||||
static inline HRESULT StorageBaseImpl_GetTransactionSig(StorageBaseImpl *This,
|
||||
ULONG* result, BOOL refresh)
|
||||
{
|
||||
return This->baseVtbl->GetTransactionSig(This, result, refresh);
|
||||
}
|
||||
|
||||
static inline HRESULT StorageBaseImpl_SetTransactionSig(StorageBaseImpl *This,
|
||||
ULONG value)
|
||||
{
|
||||
return This->baseVtbl->SetTransactionSig(This, value);
|
||||
}
|
||||
|
||||
static inline HRESULT StorageBaseImpl_LockTransaction(StorageBaseImpl *This, BOOL write)
|
||||
{
|
||||
return This->baseVtbl->LockTransaction(This, write);
|
||||
}
|
||||
|
||||
static inline HRESULT StorageBaseImpl_UnlockTransaction(StorageBaseImpl *This, BOOL write)
|
||||
{
|
||||
return This->baseVtbl->UnlockTransaction(This, write);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* StorageBaseImpl stream list handlers
|
||||
*/
|
||||
|
@ -350,6 +380,7 @@ struct StorageImpl
|
|||
ULONG extBigBlockDepotLocationsSize;
|
||||
ULONG extBigBlockDepotCount;
|
||||
ULONG bigBlockDepotStart[COUNT_BBDEPOTINHEADER];
|
||||
ULONG transactionSig;
|
||||
|
||||
ULONG extBlockDepotCached[MAX_BIG_BLOCK_SIZE / 4];
|
||||
ULONG indexExtBlockDepotCached;
|
||||
|
@ -373,6 +404,8 @@ struct StorageImpl
|
|||
UINT blockChainToEvict;
|
||||
|
||||
ILockBytes* lockBytes;
|
||||
|
||||
ULONG locked_bytes[8];
|
||||
};
|
||||
|
||||
HRESULT StorageImpl_ReadRawDirEntry(
|
||||
|
@ -459,6 +492,54 @@ StgStreamImpl* StgStreamImpl_Construct(
|
|||
DirRef dirEntry) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* Range lock constants.
|
||||
*
|
||||
* The storage format reserves the region from 0x7fffff00-0x7fffffff for
|
||||
* locking and synchronization. Unfortunately, the spec doesn't say which bytes
|
||||
* within that range are used, and for what. These are guesses based on testing.
|
||||
* In particular, ends of ranges may be wrong.
|
||||
|
||||
0x0 through 0x57: Unknown. Causes read-only exclusive opens to fail.
|
||||
0x58 through 0x6b: Priority mode.
|
||||
0x6c through 0x7f: No snapshot mode.
|
||||
0x80: Commit lock.
|
||||
0x81 through 0x91: Priority mode, again. Not sure why it uses two regions.
|
||||
0x92: Lock-checking lock. Held while opening so ranges can be tested without
|
||||
causing spurious failures if others try to grab or test those ranges at the
|
||||
same time.
|
||||
0x93 through 0xa6: Read mode.
|
||||
0xa7 through 0xba: Write mode.
|
||||
0xbb through 0xce: Deny read.
|
||||
0xcf through 0xe2: Deny write.
|
||||
0xe2 through 0xff: Unknown. Causes read-only exclusive opens to fail.
|
||||
*/
|
||||
|
||||
#define RANGELOCK_UNK1_FIRST 0x7fffff00
|
||||
#define RANGELOCK_UNK1_LAST 0x7fffff57
|
||||
#define RANGELOCK_PRIORITY1_FIRST 0x7fffff58
|
||||
#define RANGELOCK_PRIORITY1_LAST 0x7fffff6b
|
||||
#define RANGELOCK_NOSNAPSHOT_FIRST 0x7fffff6c
|
||||
#define RANGELOCK_NOSNAPSHOT_LAST 0x7fffff7f
|
||||
#define RANGELOCK_COMMIT 0x7fffff80
|
||||
#define RANGELOCK_PRIORITY2_FIRST 0x7fffff81
|
||||
#define RANGELOCK_PRIORITY2_LAST 0x7fffff91
|
||||
#define RANGELOCK_CHECKLOCKS 0x7fffff92
|
||||
#define RANGELOCK_READ_FIRST 0x7fffff93
|
||||
#define RANGELOCK_READ_LAST 0x7fffffa6
|
||||
#define RANGELOCK_WRITE_FIRST 0x7fffffa7
|
||||
#define RANGELOCK_WRITE_LAST 0x7fffffba
|
||||
#define RANGELOCK_DENY_READ_FIRST 0x7fffffbb
|
||||
#define RANGELOCK_DENY_READ_LAST 0x7fffffce
|
||||
#define RANGELOCK_DENY_WRITE_FIRST 0x7fffffcf
|
||||
#define RANGELOCK_DENY_WRITE_LAST 0x7fffffe2
|
||||
#define RANGELOCK_UNK2_FIRST 0x7fffffe3
|
||||
#define RANGELOCK_UNK2_LAST 0x7fffffff
|
||||
#define RANGELOCK_TRANSACTION_FIRST RANGELOCK_COMMIT
|
||||
#define RANGELOCK_TRANSACTION_LAST RANGELOCK_CHECKLOCKS
|
||||
#define RANGELOCK_FIRST RANGELOCK_UNK1_FIRST
|
||||
#define RANGELOCK_LAST RANGELOCK_UNK2_LAST
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Endian conversion macros
|
||||
*/
|
||||
|
|
|
@ -150,7 +150,7 @@ reactos/dll/win32/ntprint # Synced to Wine-1.7.17
|
|||
reactos/dll/win32/objsel # Synced to Wine-1.7.17
|
||||
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.17
|
||||
reactos/dll/win32/ole32 # Synced to Wine-1.7.17
|
||||
reactos/dll/win32/ole32 # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/oleacc # Synced to Wine-1.7.17
|
||||
reactos/dll/win32/oleaut32 # Synced to Wine-1.7.17
|
||||
reactos/dll/win32/olecli32 # Synced to Wine-1.7.17
|
||||
|
|
Loading…
Reference in a new issue