wshom.ocx: Implement RegWrite().
This commit is contained in:
parent
129862f369
commit
4588bb1170
|
@ -1,5 +1,5 @@
|
||||||
MODULE = wshom.ocx
|
MODULE = wshom.ocx
|
||||||
IMPORTS = uuid oleaut32 ole32 shell32
|
IMPORTS = uuid oleaut32 ole32 shell32 advapi32
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
shell.c \
|
shell.c \
|
||||||
|
|
|
@ -1035,12 +1035,46 @@ static HKEY get_root_key(const WCHAR *path)
|
||||||
return NULL;
|
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)
|
static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *value)
|
||||||
{
|
{
|
||||||
DWORD type, datalen, ret;
|
DWORD type, datalen, ret;
|
||||||
WCHAR *keyname, *val;
|
WCHAR *subkey, *val;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr;
|
||||||
BSTR subkey = NULL;
|
|
||||||
HKEY root;
|
HKEY root;
|
||||||
|
|
||||||
TRACE("(%s %p)\n", debugstr_w(name), value);
|
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)
|
if (!root)
|
||||||
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||||
|
|
||||||
/* at least one separator should be present */
|
hr = split_reg_path(name, &subkey, &val);
|
||||||
keyname = strchrW(name, '\\');
|
if (FAILED(hr))
|
||||||
if (!keyname)
|
return hr;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = REG_NONE;
|
type = REG_NONE;
|
||||||
datalen = 0;
|
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) {
|
if (ret == ERROR_SUCCESS) {
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
|
@ -1083,7 +1102,7 @@ static HRESULT WINAPI WshShell3_RegRead(IWshShell3 *iface, BSTR name, VARIANT *v
|
||||||
goto fail;
|
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) {
|
if (ret) {
|
||||||
HeapFree(GetProcessHeap(), 0, data);
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
hr = HRESULT_FROM_WIN32(ret);
|
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);
|
hr = HRESULT_FROM_WIN32(ret);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
SysFreeString(subkey);
|
if (val)
|
||||||
|
HeapFree(GetProcessHeap(), 0, subkey);
|
||||||
return hr;
|
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));
|
static const WCHAR regexpandszW[] = {'R','E','G','_','E','X','P','A','N','D','_','S','Z',0};
|
||||||
return E_NOTIMPL;
|
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)
|
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 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};
|
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];
|
WCHAR pathW[MAX_PATH];
|
||||||
|
DWORD dwvalue, type;
|
||||||
VARIANT value, v;
|
VARIANT value, v;
|
||||||
IWshShell3 *sh3;
|
IWshShell3 *sh3;
|
||||||
VARTYPE vartype;
|
VARTYPE vartype;
|
||||||
DWORD dwvalue;
|
|
||||||
LONG bound;
|
LONG bound;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
BSTR name;
|
BSTR name;
|
||||||
|
@ -255,6 +255,7 @@ static void test_registry(void)
|
||||||
&IID_IWshShell3, (void**)&sh3);
|
&IID_IWshShell3, (void**)&sh3);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* RegRead() */
|
||||||
V_VT(&value) = VT_I2;
|
V_VT(&value) = VT_I2;
|
||||||
hr = IWshShell3_RegRead(sh3, NULL, &value);
|
hr = IWshShell3_RegRead(sh3, NULL, &value);
|
||||||
ok(hr == E_POINTER, "got 0x%08x\n", hr);
|
ok(hr == E_POINTER, "got 0x%08x\n", hr);
|
||||||
|
@ -388,6 +389,84 @@ static void test_registry(void)
|
||||||
VariantClear(&value);
|
VariantClear(&value);
|
||||||
SysFreeString(name);
|
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);
|
delete_key(root);
|
||||||
IWshShell3_Release(sh3);
|
IWshShell3_Release(sh3);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue