⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 registry.c

📁 Virtual Floppy Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -