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

📄 tclwinreg.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * tclWinReg.c -- * *	This file contains the implementation of the "registry" Tcl *	built-in command.  This command is built as a dynamically *	loadable extension in a separate DLL. * * Copyright (c) 1997 by Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinReg.c,v 1.20 2003/01/16 19:02:00 mdejong Exp $ */#include <tclPort.h>#include <stdlib.h>/* * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the * Registry_Init declaration is in the source file itself, which is only * accessed when we are building a library. */#undef TCL_STORAGE_CLASS#define TCL_STORAGE_CLASS DLLEXPORT/* * The following macros convert between different endian ints. */#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))/* * The following flag is used in OpenKeys to indicate that the specified * key should be created if it doesn't currently exist. */#define REG_CREATE 1/* * The following tables contain the mapping from registry root names * to the system predefined keys. */static CONST char *rootKeyNames[] = {    "HKEY_LOCAL_MACHINE", "HKEY_USERS", "HKEY_CLASSES_ROOT",    "HKEY_CURRENT_USER", "HKEY_CURRENT_CONFIG",    "HKEY_PERFORMANCE_DATA", "HKEY_DYN_DATA", NULL};static HKEY rootKeys[] = {    HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,    HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA};/* * The following table maps from registry types to strings.  Note that * the indices for this array are the same as the constants for the * known registry types so we don't need a separate table to hold the * mapping. */static CONST char *typeNames[] = {    "none", "sz", "expand_sz", "binary", "dword",    "dword_big_endian", "link", "multi_sz", "resource_list", NULL};static DWORD lastType = REG_RESOURCE_LIST;/* * The following structures allow us to select between the Unicode and ASCII * interfaces at run time based on whether Unicode APIs are available.  The * Unicode APIs are preferable because they will handle characters outside * of the current code page. */typedef struct RegWinProcs {    int useWide;    LONG (WINAPI *regConnectRegistryProc)(CONST TCHAR *, HKEY, PHKEY);    LONG (WINAPI *regCreateKeyExProc)(HKEY, CONST TCHAR *, DWORD, TCHAR *,	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *, DWORD *);     LONG (WINAPI *regDeleteKeyProc)(HKEY, CONST TCHAR *);    LONG (WINAPI *regDeleteValueProc)(HKEY, CONST TCHAR *);    LONG (WINAPI *regEnumKeyProc)(HKEY, DWORD, TCHAR *, DWORD);    LONG (WINAPI *regEnumKeyExProc)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    TCHAR *, DWORD *, FILETIME *);    LONG (WINAPI *regEnumValueProc)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    DWORD *, BYTE *, DWORD *);    LONG (WINAPI *regOpenKeyExProc)(HKEY, CONST TCHAR *, DWORD, REGSAM,	    HKEY *);    LONG (WINAPI *regQueryInfoKeyProc)(HKEY, TCHAR *, DWORD *, DWORD *,	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,	    FILETIME *);    LONG (WINAPI *regQueryValueExProc)(HKEY, CONST TCHAR *, DWORD *, DWORD *,	    BYTE *, DWORD *);    LONG (WINAPI *regSetValueExProc)(HKEY, CONST TCHAR *, DWORD, DWORD,	    CONST BYTE*, DWORD);} RegWinProcs;static RegWinProcs *regWinProcs;static RegWinProcs asciiProcs = {    0,    (LONG (WINAPI *)(CONST TCHAR *, HKEY, PHKEY)) RegConnectRegistryA,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,	    DWORD *)) RegCreateKeyExA,     (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyA,    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueA,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyA,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    TCHAR *, DWORD *, FILETIME *)) RegEnumKeyExA,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    DWORD *, BYTE *, DWORD *)) RegEnumValueA,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM,	    HKEY *)) RegOpenKeyExA,    (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *,	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,	    FILETIME *)) RegQueryInfoKeyA,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *,	    BYTE *, DWORD *)) RegQueryValueExA,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD,	    CONST BYTE*, DWORD)) RegSetValueExA,};static RegWinProcs unicodeProcs = {    1,    (LONG (WINAPI *)(CONST TCHAR *, HKEY, PHKEY)) RegConnectRegistryW,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, TCHAR *,	    DWORD, REGSAM, SECURITY_ATTRIBUTES *, HKEY *,	    DWORD *)) RegCreateKeyExW,     (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteKeyW,    (LONG (WINAPI *)(HKEY, CONST TCHAR *)) RegDeleteValueW,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD)) RegEnumKeyW,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    TCHAR *, DWORD *, FILETIME *)) RegEnumKeyExW,    (LONG (WINAPI *)(HKEY, DWORD, TCHAR *, DWORD *, DWORD *,	    DWORD *, BYTE *, DWORD *)) RegEnumValueW,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, REGSAM,	    HKEY *)) RegOpenKeyExW,    (LONG (WINAPI *)(HKEY, TCHAR *, DWORD *, DWORD *,	    DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *, DWORD *,	    FILETIME *)) RegQueryInfoKeyW,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD *, DWORD *,	    BYTE *, DWORD *)) RegQueryValueExW,    (LONG (WINAPI *)(HKEY, CONST TCHAR *, DWORD, DWORD,	    CONST BYTE*, DWORD)) RegSetValueExW,};/* * Declarations for functions defined in this file. */static void		AppendSystemError(Tcl_Interp *interp, DWORD error);static int		BroadcastValue(Tcl_Interp *interp, int objc,			    Tcl_Obj * CONST objv[]);static DWORD		ConvertDWORD(DWORD type, DWORD value);static int		DeleteKey(Tcl_Interp *interp, Tcl_Obj *keyNameObj);static int		DeleteValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *valueNameObj);static int		GetKeyNames(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *patternObj);static int		GetType(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *valueNameObj);static int		GetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *valueNameObj);static int		GetValueNames(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *patternObj);static int		OpenKey(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    REGSAM mode, int flags, HKEY *keyPtr);static DWORD		OpenSubKey(char *hostName, HKEY rootKey,			    char *keyName, REGSAM mode, int flags,			    HKEY *keyPtr);static int		ParseKeyName(Tcl_Interp *interp, char *name,			    char **hostNamePtr, HKEY *rootKeyPtr,			    char **keyNamePtr);static DWORD		RecursiveDeleteKey(HKEY hStartKey,			    CONST TCHAR * pKeyName);static int		RegistryObjCmd(ClientData clientData,			    Tcl_Interp *interp, int objc,			    Tcl_Obj * CONST objv[]);static int		SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,			    Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,			    Tcl_Obj *typeObj);EXTERN int Registry_Init(Tcl_Interp *interp);/* *---------------------------------------------------------------------- * * Registry_Init -- * *	This procedure initializes the registry command. * * Results: *	A standard Tcl result. * * Side effects: *	None. * *---------------------------------------------------------------------- */intRegistry_Init(    Tcl_Interp *interp){    if (!Tcl_InitStubs(interp, "8.0", 0)) {	return TCL_ERROR;    }    /*     * Determine if the unicode interfaces are available and select the     * appropriate registry function table.     */    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {	regWinProcs = &unicodeProcs;    } else {	regWinProcs = &asciiProcs;    }    Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, NULL, NULL);    return Tcl_PkgProvide(interp, "registry", "1.1");}/* *---------------------------------------------------------------------- * * RegistryObjCmd -- * *	This function implements the Tcl "registry" command. * * Results: *	A standard Tcl result. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intRegistryObjCmd(    ClientData clientData,	/* Not used. */    Tcl_Interp *interp,		/* Current interpreter. */    int objc,			/* Number of arguments. */    Tcl_Obj * CONST objv[])	/* Argument values. */{    int index;    char *errString;    static CONST char *subcommands[] = {	"broadcast", "delete", "get", "keys", "set", "type", "values",	(char *) NULL    };    enum SubCmdIdx {	BroadcastIdx, DeleteIdx, GetIdx, KeysIdx, SetIdx, TypeIdx, ValuesIdx    };    if (objc < 2) {	Tcl_WrongNumArgs(interp, objc, objv, "option ?arg arg ...?");	return TCL_ERROR;    }    if (Tcl_GetIndexFromObj(interp, objv[1], subcommands, "option", 0, &index)	    != TCL_OK) {	return TCL_ERROR;    }    switch (index) {	case BroadcastIdx:		/* broadcast */	    return BroadcastValue(interp, objc, objv);	    break;	case DeleteIdx:			/* delete */	    if (objc == 3) {		return DeleteKey(interp, objv[2]);	    } else if (objc == 4) {		return DeleteValue(interp, objv[2], objv[3]);	    }	    errString = "keyName ?valueName?";	    break;	case GetIdx:			/* get */	    if (objc == 4) {		return GetValue(interp, objv[2], objv[3]);	    }	    errString = "keyName valueName";	    break;	case KeysIdx:			/* keys */	    if (objc == 3) {		return GetKeyNames(interp, objv[2], NULL);	    } else if (objc == 4) {		return GetKeyNames(interp, objv[2], objv[3]);	    }	    errString = "keyName ?pattern?";	    break;	case SetIdx:			/* set */	    if (objc == 3) {		HKEY key;		/*		 * Create the key and then close it immediately.		 */		if (OpenKey(interp, objv[2], KEY_ALL_ACCESS, 1, &key)			!= TCL_OK) {		    return TCL_ERROR;		}		RegCloseKey(key);		return TCL_OK;	    } else if (objc == 5 || objc == 6) {		Tcl_Obj *typeObj = (objc == 5) ? NULL : objv[5];		return SetValue(interp, objv[2], objv[3], objv[4], typeObj);	    }	    errString = "keyName ?valueName data ?type??";	    break;	case TypeIdx:			/* type */	    if (objc == 4) {		return GetType(interp, objv[2], objv[3]);	    }	    errString = "keyName valueName";	    break;	case ValuesIdx:			/* values */	    if (objc == 3) { 		return GetValueNames(interp, objv[2], NULL);	    } else if (objc == 4) { 		return GetValueNames(interp, objv[2], objv[3]);	    }	    errString = "keyName ?pattern?";	    break;    }    Tcl_WrongNumArgs(interp, 2, objv, errString);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * DeleteKey -- * *	This function deletes a registry key. * * Results: *	A standard Tcl result. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intDeleteKey(    Tcl_Interp *interp,		/* Current interpreter. */    Tcl_Obj *keyNameObj)	/* Name of key to delete. */{    char *tail, *buffer, *hostName, *keyName;    CONST char *nativeTail;    HKEY rootKey, subkey;    DWORD result;    int length;    Tcl_Obj *resultPtr;    Tcl_DString buf;    /*     * Find the parent of the key being deleted and open it.     */    keyName = Tcl_GetStringFromObj(keyNameObj, &length);    buffer = ckalloc((unsigned int) length + 1);    strcpy(buffer, keyName);    if (ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName)	    != TCL_OK) {	ckfree(buffer);	return TCL_ERROR;    }    resultPtr = Tcl_GetObjResult(interp);    if (*keyName == '\0') {	Tcl_AppendToObj(resultPtr, "bad key: cannot delete root keys", -1);	ckfree(buffer);	return TCL_ERROR;    }    tail = strrchr(keyName, '\\');    if (tail) {	*tail++ = '\0';    } else {	tail = keyName;	keyName = NULL;    }    result = OpenSubKey(hostName, rootKey, keyName,	    KEY_ENUMERATE_SUB_KEYS | DELETE, 0, &subkey);    if (result != ERROR_SUCCESS) {	ckfree(buffer);	if (result == ERROR_FILE_NOT_FOUND) {	    return TCL_OK;	} else {	    Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);	    AppendSystemError(interp, result);	    return TCL_ERROR;	}    }    /*     * Now we recursively delete the key and everything below it.     */    nativeTail = Tcl_WinUtfToTChar(tail, -1, &buf);    result = RecursiveDeleteKey(subkey, nativeTail);    Tcl_DStringFree(&buf);    if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {	Tcl_AppendToObj(resultPtr, "unable to delete key: ", -1);	AppendSystemError(interp, result);	result = TCL_ERROR;    } else {	result = TCL_OK;    }    RegCloseKey(subkey);    ckfree(buffer);    return result;}/* *---------------------------------------------------------------------- * * DeleteValue -- * *	This function deletes a value from a registry key. * * Results: *	A standard Tcl result. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intDeleteValue(    Tcl_Interp *interp,		/* Current interpreter. */    Tcl_Obj *keyNameObj,	/* Name of key. */    Tcl_Obj *valueNameObj)	/* Name of value to delete. */{    HKEY key;    char *valueName;    int length;    DWORD result;    Tcl_Obj *resultPtr;    Tcl_DString ds;    /*     * Attempt to open the key for deletion.     */    if (OpenKey(interp, keyNameObj, KEY_SET_VALUE, 0, &key)	    != TCL_OK) {	return TCL_ERROR;    }    resultPtr = Tcl_GetObjResult(interp);    valueName = Tcl_GetStringFromObj(valueNameObj, &length);    Tcl_WinUtfToTChar(valueName, length, &ds);    result = (*regWinProcs->regDeleteValueProc)(key, Tcl_DStringValue(&ds));    Tcl_DStringFree(&ds);    if (result != ERROR_SUCCESS) {	Tcl_AppendStringsToObj(resultPtr, "unable to delete value \"",		Tcl_GetString(valueNameObj), "\" from key \"",		Tcl_GetString(keyNameObj), "\": ", NULL);	AppendSystemError(interp, result);	result = TCL_ERROR;    } else {	result = TCL_OK;    }    RegCloseKey(key);    return result;}/* *---------------------------------------------------------------------- * * GetKeyNames -- * *	This function enumerates the subkeys of a given key.  If the *	optional pattern is supplied, then only keys that match the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -