📄 registry.c
字号:
DWORD created;
DWORD size;
LONG ret;
//
// Create a new filetype subkey
//
{
int i = 0;
for (;;) {
sprintf(filetype, "%s%s.%d", type_prefix, ext, i++);
ret = RegCreateKeyEx(
HKEY_CLASSES_ROOT, filetype, 0, "", 0, KEY_WRITE, NULL, &hNewKey, &created);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"AddAssociation : RegCreateKeyEx(\"[HKCR\\%s]\")\n",
filetype);
return ret;
}
if (created == REG_CREATED_NEW_KEY) {
break;
}
else {
RegCloseKey(hNewKey);
}
}
}
//
// Open the extension subkey
//
ret = RegCreateKeyEx(
HKEY_CLASSES_ROOT, ext, 0, "", 0, KEY_ALL_ACCESS, NULL, &hExtKey, &created);
if (ret != ERROR_SUCCESS) {
RegCloseKey(hNewKey);
_RPTF1(_CRT_WARN,
"AddAssociation : RegCreateKeyEx(\"[HKCR\\%s]\")\n", ext);
return ret;
}
if (created == REG_OPENED_EXISTING_KEY) {
// extension subkey already exists -- get current filetype
size = sizeof(backup);
ret = RegQueryValueEx(hExtKey, NULL, NULL, NULL, (LPBYTE)backup, &size);
if (ret == ERROR_FILE_NOT_FOUND) {
size = 0;
}
else if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"AddAssociation : RegQueryValueEx(\"[HKCR\\%s] @\")\n", ext);
goto cleanup;
}
if (backup[size]) {
backup[size++] = '\0';
}
}
else {
backup[0] = '\0';
}
// If the extension is already assigned a filetype
// then copy from the original filetype subtree to a new tree
if (backup[0]) {
HKEY hOldKey;
ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, backup, 0, KEY_READ, &hOldKey);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"AddAssociation : RegOpenKeyEx(\"[HKCR\\%s]\")\n", backup);
goto cleanup;
}
ret = CopyRegistryTree(hNewKey, hOldKey);
RegCloseKey(hOldKey);
if (ret != ERROR_SUCCESS) {
_RPTF2(_CRT_WARN,
"AddAssociation : CopyRegistryTree(\"%s\", \"%s\")\n",
filetype, backup);
goto cleanup;
}
}
//
// OK, now set new filetype entries
//
// create a mandatory subkey first
if (verb && !*verb) {
verb = "open";
}
// create command line subkey
sprintf(buf, "shell\\%s\\command", verb);
ret = RegCreateKeyEx(hNewKey, buf, 0, "", 0, KEY_WRITE, NULL, &hSub, NULL);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"AddAssociation : RegCreateKeyEx(\"[HKCR\\%s]\")\n",
buf);
goto cleanup;
}
// set command line value
sprintf(buf, "\"%s\" \"%%1\"", program);
ret = RegSetValueEx(hSub, NULL, 0, REG_SZ, (LPBYTE)buf, strlen(buf) + 1);
RegCloseKey(hSub);
if (ret != ERROR_SUCCESS) {
_RPTF3(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s\\shell\\%s\\command] @= %s\")\n",
filetype, verb, buf);
goto cleanup;
}
// default verb
ret = RegOpenKeyEx(hNewKey, "shell", 0, KEY_WRITE, &hSub);
if (ret == ERROR_SUCCESS) {
ret = RegSetValueEx(hSub, NULL, 0, REG_SZ, (LPBYTE)verb, strlen(verb) + 1);
RegCloseKey(hSub);
if (ret != ERROR_SUCCESS) {
_RPTF2(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s\\shell] @=%s\")\n",
filetype, verb);
// this is not fatal
}
}
else {
_RPTF1(_CRT_WARN,
"AddAssociation : RegOpenKeyEx(\"[HKCR\\%s\\shell]\")\n",
filetype);
// this is not fatal
}
// verb description
if (verb_desc && *verb_desc) {
sprintf(buf, "shell\\%s", verb);
ret = RegOpenKeyEx(hNewKey, buf, 0, KEY_WRITE, &hSub);
if (ret == ERROR_SUCCESS) {
ret = RegSetValueEx(hSub, NULL, 0, REG_SZ, (LPBYTE)verb_desc, strlen(verb_desc) + 1);
RegCloseKey(hSub);
if (ret != ERROR_SUCCESS) {
_RPTF3(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s\\shell\\%s] @=%s\")\n",
filetype, verb, verb_desc);
// this is not fatal
}
}
else {
_RPTF2(_CRT_WARN,
"AddAssociation : RegOpenKeyEx(\"[HKCR\\%s\\shell\\%s]\")\n",
filetype, verb);
// this is not fatal
}
}
// filetype description
if (type_desc && *type_desc) {
ret = RegSetValueEx(hNewKey, NULL, 0, REG_SZ, (LPBYTE)type_desc, strlen(type_desc) + 1);
if (ret != ERROR_SUCCESS) {
_RPTF2(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s] @=%s\")\n",
filetype, type_desc);
// this is not fatal
}
}
// default icon
if (program && *program && icon_idx >= 0) {
ret = RegCreateKeyEx(hNewKey, "DefaultIcon", 0, "", 0, KEY_WRITE, NULL, &hSub, NULL);
if (ret == ERROR_SUCCESS) {
sprintf(buf, "%s,%d", program, icon_idx);
ret = RegSetValueEx(hSub, NULL, 0, REG_SZ, (LPBYTE)buf, strlen(buf) + 1);
RegCloseKey(hSub);
if (ret != ERROR_SUCCESS) {
_RPTF2(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s\\DefaultIcon] @=%s\")\n",
filetype, buf);
// this is not fatal
}
}
else {
_RPTF1(_CRT_WARN,
"AddAssociation : RegCreateKeyEx(\"[HKCR\\%s\\DefaultIcon]\")\n",
filetype);
// this is not fatal
}
}
//
// New filetype tree successfully created, so update the extension's filetype
//
if (backup[0]) {
ret = RegSetValueEx(hExtKey, type_prefix, 0, REG_SZ, (LPBYTE)backup, strlen(backup) + 1);
if (ret != ERROR_SUCCESS) {
_RPTF3(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s] %s=%s\")\n",
ext, type_prefix, backup);
goto cleanup;
}
}
ret = RegSetValueEx(hExtKey, NULL, 0, REG_SZ, (LPBYTE)filetype, strlen(filetype) + 1);
if (ret != ERROR_SUCCESS) {
_RPTF2(_CRT_WARN,
"AddAssociation : RegSetValueEx(\"[HKCR\\%s] @=%s\")\n",
ext, filetype);
}
cleanup:
if (hNewKey) {
RegCloseKey(hNewKey);
}
if (hExtKey) {
RegCloseKey(hExtKey);
}
if (ret != ERROR_SUCCESS) {
// failed somethere so delete (probably) incomplete subkeys
DeleteRegistryTree(HKEY_CLASSES_ROOT, filetype);
if (backup[0] == 0) {
RegDeleteKey(HKEY_CLASSES_ROOT, ext);
}
}
return ret;
}
//
// Recursively copy registry subtree
//
DWORD CopyRegistryTree(HKEY hKeyTo, HKEY hKeyFrom)
{
LONG ret;
DWORD keycnt, keymax, clsmax, valcnt, namemax, valmax;
ret = RegQueryInfoKey(
hKeyFrom,
NULL,
NULL,
NULL,
&keycnt,
&keymax,
&clsmax,
&valcnt,
&namemax,
&valmax,
NULL,
NULL);
if (ret != ERROR_SUCCESS) {
_RPTF0(_CRT_WARN,
"CopyRegistryTree : RegQueryInfoKey\n");
return ret;
}
//
// copy subkeys
//
if (keycnt) {
LPTSTR clsname = NULL, keyname = NULL;
// prepare buffers
if ((keyname = (LPTSTR)malloc(++keymax)) == NULL) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : malloc(%lu)\n", keymax);
goto cleanup_subkey;
}
if ((clsname = (LPTSTR)malloc(++clsmax)) == NULL) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : malloc(%lu)\n", clsmax);
goto cleanup_subkey;
}
// process each subkey
while (keycnt--) {
DWORD clslen, keylen;
HKEY hSubTo, hSubFrom;
FILETIME ft;
keylen = keymax;
clslen = clsmax;
// get existing subkey info
ret = RegEnumKeyEx(hKeyFrom, keycnt, keyname, &keylen, NULL, clsname, &clslen, &ft);
if (ret != ERROR_SUCCESS) {
_RPTF0(_CRT_WARN,
"CopyRegistryTree : RegEnumKeyEx\n");
break;
}
// create new subkey
ret = RegCreateKeyEx(hKeyTo, keyname, 0, clsname, 0, KEY_WRITE, NULL, &hSubTo, NULL);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : RegCreateKeyEx(\"%s\")\n", keyname);
break;
}
// open existing subkey
ret = RegOpenKeyEx(hKeyFrom, keyname, 0, KEY_READ, &hSubFrom);
if (ret != ERROR_SUCCESS) {
RegCloseKey(hSubFrom);
_RPTF1(_CRT_WARN,
"CopyRegistryTree : RegOpenKeyEx(\"%s\")\n", keyname);
break;
}
// copy subkey contents
ret = CopyRegistryTree(hSubTo, hSubFrom);
RegCloseKey(hSubFrom);
RegCloseKey(hSubTo);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : CopyRegistryTree(\"%s\")\n", keyname);
break;
}
}
cleanup_subkey:
if (clsname) {
free(clsname);
}
if (keyname) {
free(keyname);
}
}
//
// copy values
//
if (ret == ERROR_SUCCESS && valcnt) {
LPTSTR valname = NULL;
LPBYTE value = NULL;
// prepare buffers
if ((valname = (LPTSTR)malloc(++namemax)) == NULL) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : malloc(%lu)\n", namemax);
goto cleanup_value;
}
if ((value = (LPBYTE)malloc(++valmax)) == NULL) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : malloc(%lu)\n", valmax);
goto cleanup_value;
}
// process each value
while (valcnt--) {
DWORD namelen, vallen, type;
namelen = namemax;
vallen = valmax;
ret = RegEnumValue(hKeyFrom, valcnt, valname, &namelen, NULL, &type, value, &vallen);
if (ret != ERROR_SUCCESS) {
_RPTF0(_CRT_WARN,
"CopyRegistryTree : RegEnumValue\n");
break;
}
ret = RegSetValueEx(hKeyTo, valname, 0, type, value, vallen);
if (ret != ERROR_SUCCESS) {
_RPTF1(_CRT_WARN,
"CopyRegistryTree : RegSetValueEx(%s)\n", valname);
break;
}
}
cleanup_value:
if (valname) {
free(valname);
}
if (value) {
free(value);
}
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -