mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[WSHOM.OCX] Sync with Wine Staging 1.7.37. CORE-9246
svn path=/trunk/; revision=66953
This commit is contained in:
parent
04cbcf8063
commit
dc1f1c687c
5 changed files with 337 additions and 33 deletions
|
@ -1,5 +1,9 @@
|
|||
|
||||
add_definitions(-D__WINESRC__)
|
||||
|
||||
remove_definitions(-D_WIN32_WINNT=0x502)
|
||||
add_definitions(-D_WIN32_WINNT=0x600)
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
|
||||
spec2def(wshom.ocx wshom.ocx.spec)
|
||||
add_idl_headers(wshom_idlheader wshom.idl)
|
||||
|
@ -24,7 +28,7 @@ list(APPEND wshom_rc_deps
|
|||
set_source_files_properties(wshom.rc PROPERTIES OBJECT_DEPENDS "${wshom_rc_deps}")
|
||||
set_module_type(wshom win32ocx)
|
||||
target_link_libraries(wshom uuid wine)
|
||||
add_importlibs(wshom oleaut32 ole32 shell32 msvcrt kernel32 ntdll)
|
||||
add_importlibs(wshom oleaut32 ole32 shell32 advapi32 msvcrt kernel32 ntdll)
|
||||
add_dependencies(wshom stdole2 wshom_idlheader)
|
||||
add_pch(wshom wshom_private.h SOURCE)
|
||||
add_cd_file(TARGET wshom DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -21,9 +21,29 @@
|
|||
#include <shellapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <dispex.h>
|
||||
#include <winreg.h>
|
||||
|
||||
#include <wine/unicode.h>
|
||||
|
||||
/* FIXME: Vista+*/
|
||||
LONG WINAPI RegSetKeyValueW( HKEY hkey, LPCWSTR subkey, LPCWSTR name, DWORD type, const void *data, DWORD len )
|
||||
{
|
||||
HKEY hsubkey = NULL;
|
||||
DWORD ret;
|
||||
|
||||
TRACE("(%p,%s,%s,%d,%p,%d)\n", hkey, debugstr_w(subkey), debugstr_w(name), type, data, len );
|
||||
|
||||
if (subkey && subkey[0]) /* need to create the subkey */
|
||||
{
|
||||
if ((ret = RegCreateKeyW( hkey, subkey, &hsubkey )) != ERROR_SUCCESS) return ret;
|
||||
hkey = hsubkey;
|
||||
}
|
||||
|
||||
ret = RegSetValueExW( hkey, name, 0, type, (const BYTE*)data, len );
|
||||
if (hsubkey) RegCloseKey( hsubkey );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IWshShell3 WshShell3;
|
||||
|
||||
typedef struct
|
||||
|
@ -813,9 +833,11 @@ static HRESULT WINAPI WshShell3_QueryInterface(IWshShell3 *iface, REFIID riid, v
|
|||
|
||||
*ppv = NULL;
|
||||
|
||||
if(IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDispatch) ||
|
||||
IsEqualGUID(riid, &IID_IWshShell3))
|
||||
if (IsEqualGUID(riid, &IID_IDispatch) ||
|
||||
IsEqualGUID(riid, &IID_IWshShell3) ||
|
||||
IsEqualGUID(riid, &IID_IWshShell2) ||
|
||||
IsEqualGUID(riid, &IID_IWshShell) ||
|
||||
IsEqualGUID(riid, &IID_IUnknown))
|
||||
{
|
||||
*ppv = iface;
|
||||
}
|
||||
|
@ -825,7 +847,7 @@ static HRESULT WINAPI WshShell3_QueryInterface(IWshShell3 *iface, REFIID riid, v
|
|||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unknown iface %s\n", debugstr_guid(riid));
|
||||
WARN("unknown iface %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
@ -908,14 +930,22 @@ static HRESULT WINAPI WshShell3_get_Environment(IWshShell3 *iface, VARIANT *type
|
|||
return WshEnvironment_Create(env);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *WaitOnReturn, int *exit_code)
|
||||
static inline BOOL is_optional_argument(const VARIANT *arg)
|
||||
{
|
||||
return V_VT(arg) == VT_ERROR && V_ERROR(arg) == DISP_E_PARAMNOTFOUND;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, VARIANT *wait, DWORD *exit_code)
|
||||
{
|
||||
SHELLEXECUTEINFOW info;
|
||||
int waitforprocess;
|
||||
VARIANT s, w;
|
||||
VARIANT s;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(WaitOnReturn), exit_code);
|
||||
TRACE("(%s %s %s %p)\n", debugstr_w(cmd), debugstr_variant(style), debugstr_variant(wait), exit_code);
|
||||
|
||||
if (!style || !wait || !exit_code)
|
||||
return E_POINTER;
|
||||
|
||||
VariantInit(&s);
|
||||
hr = VariantChangeType(&s, style, 0, VT_I4);
|
||||
|
@ -925,19 +955,21 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style,
|
|||
return hr;
|
||||
}
|
||||
|
||||
VariantInit(&w);
|
||||
hr = VariantChangeType(&w, WaitOnReturn, 0, VT_I4);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("failed to convert wait argument, 0x%08x\n", hr);
|
||||
return hr;
|
||||
if (is_optional_argument(wait))
|
||||
waitforprocess = 0;
|
||||
else {
|
||||
VARIANT w;
|
||||
|
||||
VariantInit(&w);
|
||||
hr = VariantChangeType(&w, wait, 0, VT_I4);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
waitforprocess = V_I4(&w);
|
||||
}
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
|
||||
waitforprocess = V_I4(&w);
|
||||
|
||||
info.fMask = waitforprocess ? SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS : SEE_MASK_DEFAULT;
|
||||
info.lpFile = cmd;
|
||||
info.nShow = V_I4(&s);
|
||||
|
@ -951,16 +983,11 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style,
|
|||
{
|
||||
if (waitforprocess)
|
||||
{
|
||||
if (exit_code)
|
||||
{
|
||||
DWORD code;
|
||||
GetExitCodeProcess(info.hProcess, &code);
|
||||
*exit_code = code;
|
||||
}
|
||||
GetExitCodeProcess(info.hProcess, exit_code);
|
||||
CloseHandle(info.hProcess);
|
||||
}
|
||||
else
|
||||
if (exit_code) *exit_code = 0;
|
||||
*exit_code = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1001,16 +1028,289 @@ static HRESULT WINAPI WshShell3_ExpandEnvironmentStrings(IWshShell3 *iface, BSTR
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR Name, VARIANT* out_Value)
|
||||
static HKEY get_root_key(const WCHAR *path)
|
||||
{
|
||||
FIXME("(%s %p): stub\n", debugstr_w(Name), out_Value);
|
||||
return E_NOTIMPL;
|
||||
static const struct {
|
||||
const WCHAR full[20];
|
||||
const WCHAR abbrev[5];
|
||||
HKEY hkey;
|
||||
} rootkeys[] = {
|
||||
{ {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}, {'H','K','C','U',0}, HKEY_CURRENT_USER },
|
||||
{ {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}, {'H','K','L','M',0}, HKEY_LOCAL_MACHINE },
|
||||
{ {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}, {'H','K','C','R',0}, HKEY_CLASSES_ROOT },
|
||||
{ {'H','K','E','Y','_','U','S','E','R','S',0}, {0}, HKEY_USERS },
|
||||
{ {'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}, {0}, HKEY_CURRENT_CONFIG }
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(rootkeys)/sizeof(rootkeys[0]); i++) {
|
||||
if (!strncmpW(path, rootkeys[i].full, strlenW(rootkeys[i].full)))
|
||||
return rootkeys[i].hkey;
|
||||
if (rootkeys[i].abbrev[0] && !strncmpW(path, rootkeys[i].abbrev, strlenW(rootkeys[i].abbrev)))
|
||||
return rootkeys[i].hkey;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_RegWrite(IWshShell3 *iface, BSTR Name, VARIANT *Value, VARIANT *Type)
|
||||
/* Caller is responsible to free 'subkey' if 'value' is not NULL */
|
||||
static HRESULT split_reg_path(const WCHAR *path, WCHAR **subkey, WCHAR **value)
|
||||
{
|
||||
FIXME("(%s %s %s): stub\n", debugstr_w(Name), debugstr_variant(Value), debugstr_variant(Type));
|
||||
return E_NOTIMPL;
|
||||
*value = NULL;
|
||||
|
||||
/* at least one separator should be present */
|
||||
*subkey = strchrW(path, '\\');
|
||||
if (!*subkey)
|
||||
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
|
||||
/* default value or not */
|
||||
if ((*subkey)[strlenW(*subkey)-1] == '\\') {
|
||||
(*subkey)++;
|
||||
*value = NULL;
|
||||
}
|
||||
else {
|
||||
*value = strrchrW(*subkey, '\\');
|
||||
if (*value - *subkey > 1) {
|
||||
unsigned int len = *value - *subkey - 1;
|
||||
WCHAR *ret;
|
||||
|
||||
ret = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
|
||||
if (!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(ret, *subkey + 1, len*sizeof(WCHAR));
|
||||
ret[len] = 0;
|
||||
*subkey = ret;
|
||||
}
|
||||
(*value)++;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *value)
|
||||
{
|
||||
DWORD type, datalen, ret;
|
||||
WCHAR *subkey, *val;
|
||||
HRESULT hr;
|
||||
HKEY root;
|
||||
|
||||
TRACE("(%s %p)\n", debugstr_w(name), value);
|
||||
|
||||
if (!name || !value)
|
||||
return E_POINTER;
|
||||
|
||||
root = get_root_key(name);
|
||||
if (!root)
|
||||
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
|
||||
hr = split_reg_path(name, &subkey, &val);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
type = REG_NONE;
|
||||
datalen = 0;
|
||||
ret = RegGetValueW(root, subkey, val, RRF_RT_ANY, &type, NULL, &datalen);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
void *data;
|
||||
|
||||
data = HeapAlloc(GetProcessHeap(), 0, datalen);
|
||||
if (!data) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = RegGetValueW(root, subkey, val, RRF_RT_ANY, &type, data, &datalen);
|
||||
if (ret) {
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
V_VT(value) = VT_BSTR;
|
||||
V_BSTR(value) = SysAllocStringLen((WCHAR*)data, datalen - sizeof(WCHAR));
|
||||
if (!V_BSTR(value))
|
||||
hr = E_OUTOFMEMORY;
|
||||
break;
|
||||
case REG_DWORD:
|
||||
V_VT(value) = VT_I4;
|
||||
V_I4(value) = *(DWORD*)data;
|
||||
break;
|
||||
case REG_BINARY:
|
||||
{
|
||||
BYTE *ptr = (BYTE*)data;
|
||||
SAFEARRAYBOUND bound;
|
||||
unsigned int i;
|
||||
SAFEARRAY *sa;
|
||||
VARIANT *v;
|
||||
|
||||
bound.lLbound = 0;
|
||||
bound.cElements = datalen;
|
||||
sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
|
||||
if (!sa)
|
||||
break;
|
||||
|
||||
hr = SafeArrayAccessData(sa, (void**)&v);
|
||||
if (FAILED(hr)) {
|
||||
SafeArrayDestroy(sa);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < datalen; i++) {
|
||||
V_VT(&v[i]) = VT_UI1;
|
||||
V_UI1(&v[i]) = ptr[i];
|
||||
}
|
||||
SafeArrayUnaccessData(sa);
|
||||
|
||||
V_VT(value) = VT_ARRAY|VT_VARIANT;
|
||||
V_ARRAY(value) = sa;
|
||||
break;
|
||||
}
|
||||
case REG_MULTI_SZ:
|
||||
{
|
||||
WCHAR *ptr = (WCHAR*)data;
|
||||
SAFEARRAYBOUND bound;
|
||||
SAFEARRAY *sa;
|
||||
VARIANT *v;
|
||||
|
||||
/* get element count first */
|
||||
bound.lLbound = 0;
|
||||
bound.cElements = 0;
|
||||
while (*ptr) {
|
||||
bound.cElements++;
|
||||
ptr += strlenW(ptr)+1;
|
||||
}
|
||||
|
||||
sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
|
||||
if (!sa)
|
||||
break;
|
||||
|
||||
hr = SafeArrayAccessData(sa, (void**)&v);
|
||||
if (FAILED(hr)) {
|
||||
SafeArrayDestroy(sa);
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = (WCHAR*)data;
|
||||
while (*ptr) {
|
||||
V_VT(v) = VT_BSTR;
|
||||
V_BSTR(v) = SysAllocString(ptr);
|
||||
ptr += strlenW(ptr)+1;
|
||||
v++;
|
||||
}
|
||||
|
||||
SafeArrayUnaccessData(sa);
|
||||
V_VT(value) = VT_ARRAY|VT_VARIANT;
|
||||
V_ARRAY(value) = sa;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("value type %d not supported\n", type);
|
||||
hr = E_FAIL;
|
||||
};
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
if (FAILED(hr))
|
||||
VariantInit(value);
|
||||
}
|
||||
else
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
|
||||
fail:
|
||||
if (val)
|
||||
HeapFree(GetProcessHeap(), 0, subkey);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_RegWrite(IWshShell3 *iface, BSTR name, VARIANT *value, VARIANT *type)
|
||||
{
|
||||
static const WCHAR regexpandszW[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
|
||||
static const WCHAR regszW[] = {'R','E','G','_','S','Z',0};
|
||||
static const WCHAR regdwordW[] = {'R','E','G','_','D','W','O','R','D',0};
|
||||
static const WCHAR regbinaryW[] = {'R','E','G','_','B','I','N','A','R','Y',0};
|
||||
|
||||
DWORD regtype, data_len;
|
||||
WCHAR *subkey, *val;
|
||||
const BYTE *data;
|
||||
HRESULT hr;
|
||||
HKEY root;
|
||||
VARIANT v;
|
||||
LONG ret;
|
||||
|
||||
TRACE("(%s %s %s)\n", debugstr_w(name), debugstr_variant(value), debugstr_variant(type));
|
||||
|
||||
if (!name || !value || !type)
|
||||
return E_POINTER;
|
||||
|
||||
root = get_root_key(name);
|
||||
if (!root)
|
||||
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
|
||||
/* value type */
|
||||
if (is_optional_argument(type))
|
||||
regtype = REG_SZ;
|
||||
else {
|
||||
if (V_VT(type) != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!strcmpW(V_BSTR(type), regszW))
|
||||
regtype = REG_SZ;
|
||||
else if (!strcmpW(V_BSTR(type), regdwordW))
|
||||
regtype = REG_DWORD;
|
||||
else if (!strcmpW(V_BSTR(type), regexpandszW))
|
||||
regtype = REG_EXPAND_SZ;
|
||||
else if (!strcmpW(V_BSTR(type), regbinaryW))
|
||||
regtype = REG_BINARY;
|
||||
else {
|
||||
FIXME("unrecognized value type %s\n", debugstr_w(V_BSTR(type)));
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* it's always a string or a DWORD */
|
||||
VariantInit(&v);
|
||||
switch (regtype)
|
||||
{
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
hr = VariantChangeType(&v, value, 0, VT_BSTR);
|
||||
if (hr == S_OK) {
|
||||
data = (BYTE*)V_BSTR(&v);
|
||||
data_len = SysStringByteLen(V_BSTR(&v)) + sizeof(WCHAR);
|
||||
}
|
||||
break;
|
||||
case REG_DWORD:
|
||||
case REG_BINARY:
|
||||
hr = VariantChangeType(&v, value, 0, VT_I4);
|
||||
data = (BYTE*)&V_I4(&v);
|
||||
data_len = sizeof(DWORD);
|
||||
break;
|
||||
default:
|
||||
FIXME("unexpected regtype %d\n", regtype);
|
||||
return E_FAIL;
|
||||
};
|
||||
|
||||
if (FAILED(hr)) {
|
||||
FIXME("failed to convert value, regtype %d, 0x%08x\n", regtype, hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = split_reg_path(name, &subkey, &val);
|
||||
if (FAILED(hr))
|
||||
goto fail;
|
||||
|
||||
ret = RegSetKeyValueW(root, subkey, val, regtype, data, data_len);
|
||||
if (ret)
|
||||
hr = HRESULT_FROM_WIN32(ret);
|
||||
|
||||
fail:
|
||||
VariantClear(&v);
|
||||
if (val)
|
||||
HeapFree(GetProcessHeap(), 0, subkey);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI WshShell3_RegDelete(IWshShell3 *iface, BSTR Name)
|
||||
|
|
|
@ -528,7 +528,7 @@ library IWshRuntimeLibrary
|
|||
[in] BSTR Command,
|
||||
[in, optional] VARIANT* WindowStyle,
|
||||
[in, optional] VARIANT* WaitOnReturn,
|
||||
[out, retval] int* out_ExitCode);
|
||||
[out, retval] DWORD* out_ExitCode);
|
||||
|
||||
[id(0x03e9)]
|
||||
HRESULT Popup(
|
||||
|
|
|
@ -108,7 +108,7 @@ static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID r
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
|
||||
WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ reactos/dll/win32/wintrust # Synced to Wine-1.7.27
|
|||
reactos/dll/win32/wldap32 # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/wmi # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/wmiutils # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/wshom.ocx # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/wshom.ocx # Synced to WineStaging-1.7.37
|
||||
reactos/dll/win32/wtsapi32 # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/wuapi # Synced to Wine-1.7.27
|
||||
reactos/dll/win32/xinput1_1 # Synced to Wine-1.7.27
|
||||
|
|
Loading…
Reference in a new issue