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

📄 tclwinreg.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * Results: *	Returns the opened key in the keyPtr and a Windows error code *	as the return value. * * Side effects: *	None. * *---------------------------------------------------------------------- */static DWORDOpenSubKey(    char *hostName,		/* Host to access, or NULL for local. */    HKEY rootKey,		/* Root registry key. */    char *keyName,		/* Subkey name. */    REGSAM mode,		/* Access mode. */    int flags,			/* 0 or REG_CREATE. */    HKEY *keyPtr)		/* Returned HKEY. */{    DWORD result;    /*     * Attempt to open the root key on a remote host if necessary.     */    if (hostName) {	result = RegConnectRegistry(hostName, rootKey, &rootKey);	if (result != ERROR_SUCCESS) {	    return result;	}    }    /*     * Now open the specified key with the requested permissions.  Note     * that this key must be closed by the caller.     */    if (flags & REG_CREATE) {	DWORD create;	result = RegCreateKeyEx(rootKey, keyName, 0, "",		REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create);    } else {	result = RegOpenKeyEx(rootKey, keyName, 0, mode, keyPtr);    }    /*     * Be sure to close the root key since we are done with it now.     */    if (hostName) {	RegCloseKey(rootKey);    }    return result; }/* *---------------------------------------------------------------------- * * ParseKeyName -- * *	This function parses a key name into the host, root, and subkey *	parts.  * * Results: *	The pointers to the start of the host and subkey names are *	returned in the hostNamePtr and keyNamePtr variables.  The *	specified root HKEY is returned in rootKeyPtr.  Returns *	a standard Tcl result. * * * Side effects: *	Modifies the name string by inserting nulls. * *---------------------------------------------------------------------- */static intParseKeyName(    Tcl_Interp *interp,		/* Current interpreter. */    char *name,    char **hostNamePtr,    HKEY *rootKeyPtr,    char **keyNamePtr){    char *rootName;    int result, index;    Tcl_Obj *rootObj, *resultPtr = Tcl_GetObjResult(interp);    /*     * Split the key into host and root portions.     */    *hostNamePtr = *keyNamePtr = rootName = NULL;    if (name[0] == '\\') {	if (name[1] == '\\') {	    *hostNamePtr = name;	    for (rootName = name+2; *rootName != '\0'; rootName++) {		if (*rootName == '\\') {		    *rootName++ = '\0';		    break;		}	    }	}    } else {	rootName = name;    }    if (!rootName) {	Tcl_AppendStringsToObj(resultPtr, "bad key \"", name,		"\": must start with a valid root", NULL);	return TCL_ERROR;    }    /*     * Split the root into root and subkey portions.     */    for (*keyNamePtr = rootName; **keyNamePtr != '\0'; (*keyNamePtr)++) {	if (**keyNamePtr == '\\') {	    **keyNamePtr = '\0';	    (*keyNamePtr)++;	    break;	}    }    /*     * Look for a matching root name.     */    rootObj = Tcl_NewStringObj(rootName, -1);    result = Tcl_GetIndexFromObj(interp, rootObj, rootKeyNames, "root name",	    TCL_EXACT, &index);    Tcl_DecrRefCount(rootObj);    if (result != TCL_OK) {	return TCL_ERROR;    }    *rootKeyPtr = rootKeys[index];    return TCL_OK;}/* *---------------------------------------------------------------------- * * RecursiveDeleteKey -- * *	This function recursively deletes all the keys below a starting *	key.  Although Windows 95 does this automatically, we still need *	to do this for Windows NT. * * Results: *	Returns a Windows error code. * * Side effects: *	Deletes all of the keys and values below the given key. * *---------------------------------------------------------------------- */static DWORDRecursiveDeleteKey(    HKEY startKey,		/* Parent of key to be deleted. */    char *keyName)		/* Name of key to be deleted. */{    DWORD result, subKeyLength;    Tcl_DString subkey;    HKEY hKey;    /*     * Do not allow NULL or empty key name.     */    if (!keyName || lstrlen(keyName) == '\0') {	return ERROR_BADKEY;    }    result = RegOpenKeyEx(startKey, keyName, 0,	    KEY_ENUMERATE_SUB_KEYS | DELETE | KEY_QUERY_VALUE, &hKey);    if (result != ERROR_SUCCESS) {	return result;    }    result = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &subKeyLength,	    NULL, NULL, NULL, NULL, NULL, NULL);    subKeyLength++;    if (result != ERROR_SUCCESS) {	return result;    }    Tcl_DStringInit(&subkey);    Tcl_DStringSetLength(&subkey, subKeyLength);    while (result == ERROR_SUCCESS) {	/*	 * Always get index 0 because key deletion changes ordering.	 */	subKeyLength = Tcl_DStringLength(&subkey);	result=RegEnumKeyEx(hKey, 0, Tcl_DStringValue(&subkey), &subKeyLength,		NULL, NULL, NULL, NULL);	if (result == ERROR_NO_MORE_ITEMS) {	    result = RegDeleteKey(startKey, keyName);	    break;	} else if (result == ERROR_SUCCESS) {	    result = RecursiveDeleteKey(hKey, Tcl_DStringValue(&subkey));	}    }    Tcl_DStringFree(&subkey);    RegCloseKey(hKey);    return result;}/* *---------------------------------------------------------------------- * * SetValue -- * *	This function sets the contents of a registry value.  If *	the key or value does not exist, it will be created.  If it *	does exist, then the data and type will be replaced. * * Results: *	Returns a normal Tcl result. * * Side effects: *	May create new keys or values. * *---------------------------------------------------------------------- */static intSetValue(    Tcl_Interp *interp,		/* Current interpreter. */    Tcl_Obj *keyNameObj,	/* Name of key. */    Tcl_Obj *valueNameObj,	/* Name of value to set. */    Tcl_Obj *dataObj,		/* Data to be written. */    Tcl_Obj *typeObj)		/* Type of data to be written. */{    DWORD type, result;    HKEY key;    int length;    char *valueName;    Tcl_Obj *resultPtr;    if (typeObj == NULL) {	type = REG_SZ;    } else if (Tcl_GetIndexFromObj(interp, typeObj, typeNames, "type",	    0, (int *) &type) != TCL_OK) {	if (Tcl_GetIntFromObj(NULL, typeObj, (int*) &type) != TCL_OK) {	    return TCL_ERROR;	}	Tcl_ResetResult(interp);    }    if (OpenKey(interp, keyNameObj, KEY_ALL_ACCESS, 1, &key) != TCL_OK) {	return TCL_ERROR;    }    valueName = Tcl_GetStringFromObj(valueNameObj, &length);    resultPtr = Tcl_GetObjResult(interp);    if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {	DWORD value;	if (Tcl_GetIntFromObj(interp, dataObj, (int*) &value) != TCL_OK) {	    RegCloseKey(key);	    return TCL_ERROR;	}	value = ConvertDWORD(type, value);	result = RegSetValueEx(key, valueName, 0, type, (BYTE*) &value,		sizeof(DWORD));    } else if (type == REG_MULTI_SZ) {	Tcl_DString data;	int objc, i;	Tcl_Obj **objv;	char *element;	if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) {	    RegCloseKey(key);	    return TCL_ERROR;	}	/*	 * Append the elements as null terminated strings.  Note that	 * we must not assume the length of the string in case there are	 * embedded nulls, which aren't allowed in REG_MULTI_SZ values.	 */	Tcl_DStringInit(&data);	for (i = 0; i < objc; i++) {	    element = Tcl_GetStringFromObj(objv[i], NULL);	    Tcl_DStringAppend(&data, element, -1);	    Tcl_DStringSetLength(&data, Tcl_DStringLength(&data)+1);	}	result = RegSetValueEx(key, valueName, 0, type,		(LPBYTE) Tcl_DStringValue(&data),		(DWORD) (Tcl_DStringLength(&data)+1));	Tcl_DStringFree(&data);    } else {	char *data = Tcl_GetStringFromObj(dataObj, &length);	/*	 * Include the null in the length if we are storing a null terminated	 * string.  Note that we also need to call strlen to find the first	 * null so we don't pass bad data to the registry.	 */	if (type == REG_SZ || type == REG_EXPAND_SZ) {	    length = strlen(data) + 1;	}	result = RegSetValueEx(key, valueName, 0, type, (LPBYTE)data, length);    }    RegCloseKey(key);    if (result != ERROR_SUCCESS) {	Tcl_AppendToObj(resultPtr, "unable to set value: ", -1);	AppendSystemError(interp, result);	return TCL_ERROR;    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * AppendSystemError -- * *	This routine formats a Windows system error message and places *	it into the interpreter result. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */static voidAppendSystemError(    Tcl_Interp *interp,		/* Current interpreter. */    DWORD error)		/* Result code from error. */{    int length;    char *msgbuf, id[10];    Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);    sprintf(id, "%d", error);    length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM	    | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msgbuf,	    0, NULL);    if (length == 0) {	if (error == ERROR_CALL_NOT_IMPLEMENTED) {	    msgbuf = "function not supported under Win32s";	} else {	    msgbuf = id;	}    } else {	/*	 * Trim the trailing CR/LF from the system message.	 */	if (msgbuf[length-1] == '\n') {	    msgbuf[--length] = 0;	}	if (msgbuf[length-1] == '\r') {	    msgbuf[--length] = 0;	}    }    Tcl_SetErrorCode(interp, "WINDOWS", id, msgbuf, (char *) NULL);    Tcl_AppendToObj(resultPtr, msgbuf, -1);    if (length != 0) {	LocalFree(msgbuf);    }}/* *---------------------------------------------------------------------- * * ConvertDWORD -- * *	This function determines whether a DWORD needs to be byte *	swapped, and returns the appropriately swapped value. * * Results: *	Returns a converted DWORD. * * Side effects: *	None. * *---------------------------------------------------------------------- */static DWORDConvertDWORD(    DWORD type,			/* Either REG_DWORD or REG_DWORD_BIG_ENDIAN */    DWORD value)		/* The value to be converted. */{    DWORD order = 1;    DWORD localType;    /*     * Check to see if the low bit is in the first byte.     */    localType = (*((char*)(&order)) == 1) ? REG_DWORD : REG_DWORD_BIG_ENDIAN;    return (type != localType) ? SWAPLONG(value) : value;}

⌨️ 快捷键说明

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