Commit 4588bb11 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

wshom.ocx: Implement RegWrite().

parent 129862f3
MODULE = wshom.ocx
IMPORTS = uuid oleaut32 ole32 shell32
IMPORTS = uuid oleaut32 ole32 shell32 advapi32
C_SRCS = \
shell.c \
......
......@@ -1035,12 +1035,46 @@ static HKEY get_root_key(const WCHAR *path)
return NULL;
}
/* Caller is responsible to free 'subkey' if 'value' is not NULL */
static HRESULT split_reg_path(const WCHAR *path, WCHAR **subkey, WCHAR **value)
{
*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 *keyname, *val;
HRESULT hr = S_OK;
BSTR subkey = NULL;
WCHAR *subkey, *val;
HRESULT hr;
HKEY root;
TRACE("(%s %p)\n", debugstr_w(name), value);
......@@ -1052,28 +1086,13 @@ static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *v
if (!root)
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
/* at least one separator should be present */
keyname = strchrW(name, '\\');
if (!keyname)
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
/* default value or not */
if (keyname[strlenW(keyname)-1] == '\\') {
keyname++;
val = NULL;
}
else {
val = strrchrW(keyname, '\\');
if (val - keyname > 1) {
subkey = SysAllocStringLen(keyname+1, val-keyname-1);
keyname = subkey;
}
val++;
}
hr = split_reg_path(name, &subkey, &val);
if (FAILED(hr))
return hr;
type = REG_NONE;
datalen = 0;
ret = RegGetValueW(root, keyname, val, RRF_RT_ANY, &type, NULL, &datalen);
ret = RegGetValueW(root, subkey, val, RRF_RT_ANY, &type, NULL, &datalen);
if (ret == ERROR_SUCCESS) {
void *data;
......@@ -1083,7 +1102,7 @@ static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *v
goto fail;
}
ret = RegGetValueW(root, keyname, val, RRF_RT_ANY, &type, data, &datalen);
ret = RegGetValueW(root, subkey, val, RRF_RT_ANY, &type, data, &datalen);
if (ret) {
HeapFree(GetProcessHeap(), 0, data);
hr = HRESULT_FROM_WIN32(ret);
......@@ -1183,14 +1202,97 @@ static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *v
hr = HRESULT_FROM_WIN32(ret);
fail:
SysFreeString(subkey);
if (val)
HeapFree(GetProcessHeap(), 0, subkey);
return hr;
}
static HRESULT WINAPI WshShell3_RegWrite(IWshShell3 *iface, BSTR Name, VARIANT *Value, VARIANT *Type)
static HRESULT WINAPI WshShell3_RegWrite(IWshShell3 *iface, BSTR name, VARIANT *value, VARIANT *type)
{
FIXME("(%s %s %s): stub\n", debugstr_w(Name), debugstr_variant(Value), debugstr_variant(Type));
return E_NOTIMPL;
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)
......
......@@ -240,10 +240,10 @@ static void test_registry(void)
static const WCHAR brokenW[] = {'H','K','E','Y','_','b','r','o','k','e','n','_','k','e','y',0};
static const WCHAR broken2W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','a',0};
WCHAR pathW[MAX_PATH];
DWORD dwvalue, type;
VARIANT value, v;
IWshShell3 *sh3;
VARTYPE vartype;
DWORD dwvalue;
LONG bound;
HRESULT hr;
BSTR name;
......@@ -255,6 +255,7 @@ static void test_registry(void)
&IID_IWshShell3, (void**)&sh3);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* RegRead() */
V_VT(&value) = VT_I2;
hr = IWshShell3_RegRead(sh3, NULL, &value);
ok(hr == E_POINTER, "got 0x%08x\n", hr);
......@@ -389,6 +390,84 @@ static void test_registry(void)
SysFreeString(name);
delete_key(root);
/* RegWrite() */
ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root);
ok(ret == 0, "got %d\n", ret);
hr = IWshShell3_RegWrite(sh3, NULL, NULL, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr);
lstrcpyW(pathW, keypathW);
lstrcatW(pathW, regszW);
name = SysAllocString(pathW);
hr = IWshShell3_RegWrite(sh3, name, NULL, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr);
VariantInit(&value);
hr = IWshShell3_RegWrite(sh3, name, &value, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr);
hr = IWshShell3_RegWrite(sh3, name, &value, &value);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
/* type is optional */
V_VT(&v) = VT_ERROR;
V_ERROR(&v) = DISP_E_PARAMNOTFOUND;
hr = IWshShell3_RegWrite(sh3, name, &value, &v);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* default type is REG_SZ */
V_VT(&value) = VT_I4;
V_I4(&value) = 12;
hr = IWshShell3_RegWrite(sh3, name, &value, &v);
ok(hr == S_OK, "got 0x%08x\n", hr);
type = REG_NONE;
ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
ok(type == REG_SZ, "got %d\n", type);
ret = RegDeleteValueA(root, "regsz");
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
V_VT(&value) = VT_BSTR;
V_BSTR(&value) = SysAllocString(regszW);
hr = IWshShell3_RegWrite(sh3, name, &value, &v);
ok(hr == S_OK, "got 0x%08x\n", hr);
VariantClear(&value);
type = REG_NONE;
ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
ok(type == REG_SZ, "got %d\n", type);
ret = RegDeleteValueA(root, "regsz");
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
V_VT(&value) = VT_R4;
V_R4(&value) = 1.2;
hr = IWshShell3_RegWrite(sh3, name, &value, &v);
ok(hr == S_OK, "got 0x%08x\n", hr);
VariantClear(&value);
type = REG_NONE;
ret = RegGetValueA(root, NULL, "regsz", RRF_RT_ANY, &type, NULL, NULL);
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
ok(type == REG_SZ, "got %d\n", type);
ret = RegDeleteValueA(root, "regsz");
ok(ret == ERROR_SUCCESS, "got %d\n", ret);
V_VT(&value) = VT_R4;
V_R4(&value) = 1.2;
V_VT(&v) = VT_I2;
V_I2(&v) = 1;
hr = IWshShell3_RegWrite(sh3, name, &value, &v);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
VariantClear(&value);
SysFreeString(name);
delete_key(root);
IWshShell3_Release(sh3);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment