summaryrefslogtreecommitdiffstats
path: root/win/tclWinReg.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-06-16 14:48:35 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-06-16 14:48:35 (GMT)
commitb700360ad9501defb0b1e2d86353ac8d0db8eef4 (patch)
tree8b3bcb3adb8bd2eb44bcf16bb091722274e03e9e /win/tclWinReg.c
parentc755ef08151343eb145710489f8c999edbef15ff (diff)
parent296aebbd6ee092a25741684fa37ee31ef5a3e222 (diff)
downloadtcl-b700360ad9501defb0b1e2d86353ac8d0db8eef4.zip
tcl-b700360ad9501defb0b1e2d86353ac8d0db8eef4.tar.gz
tcl-b700360ad9501defb0b1e2d86353ac8d0db8eef4.tar.bz2
Merge up to the 8.6.0 release.
Diffstat (limited to 'win/tclWinReg.c')
-rw-r--r--win/tclWinReg.c404
1 files changed, 120 insertions, 284 deletions
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 987099c..6ac5caf 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -10,35 +10,42 @@
*
* 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.54 2010/08/30 09:19:38 nijtmans Exp $
- */
-
-/* TODO: This file does not compile in UNICODE mode.
- * See [Freq 2965056]: Windows build with -DUNICODE
*/
-#undef UNICODE
-#undef _UNICODE
#undef STATIC_BUILD
-#ifndef USE_TCL_STUBS
-# define USE_TCL_STUBS
-#endif
+#undef USE_TCL_STUBS
+#define USE_TCL_STUBS
+
#include "tclInt.h"
#ifdef _MSC_VER
# pragma comment (lib, "advapi32.lib")
#endif
#include <stdlib.h>
+#ifndef UNICODE
+# undef Tcl_WinTCharToUtf
+# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c)
+# undef Tcl_WinUtfToTChar
+# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
+#endif /* !UNICODE */
+
/*
* Ensure that we can say which registry is being accessed.
*/
#ifndef KEY_WOW64_64KEY
-#define KEY_WOW64_64KEY (0x0100)
+# define KEY_WOW64_64KEY (0x0100)
#endif
#ifndef KEY_WOW64_32KEY
-#define KEY_WOW64_32KEY (0x0200)
+# define KEY_WOW64_32KEY (0x0200)
+#endif
+
+/*
+ * The maximum length of a sub-key name.
+ */
+
+#ifndef MAX_KEY_LENGTH
+# define MAX_KEY_LENGTH 256
#endif
/*
@@ -75,7 +82,7 @@ static const char *const rootKeyNames[] = {
"HKEY_PERFORMANCE_DATA", "HKEY_DYN_DATA", NULL
};
-static HKEY rootKeys[] = {
+static const HKEY rootKeys[] = {
HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,
HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA
};
@@ -96,90 +103,6 @@ static const char *const typeNames[] = {
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.
*/
@@ -240,25 +163,16 @@ int
Registry_Init(
Tcl_Interp *interp)
{
- int useWide;
Tcl_Command cmd;
- if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
- /*
- * Determine if the unicode interfaces are available and select the
- * appropriate registry function table.
- */
-
- useWide = (TclWinGetPlatformId() != VER_PLATFORM_WIN32_WINDOWS);
- regWinProcs = useWide ? &unicodeProcs : &asciiProcs;
-
cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd,
interp, DeleteCmd);
Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, cmd);
- return Tcl_PkgProvide(interp, "registry", "1.3");
+ return Tcl_PkgProvide(interp, "registry", "1.3.0");
}
/*
@@ -498,7 +412,7 @@ DeleteKey(
REGSAM mode) /* Mode flags to pass. */
{
char *tail, *buffer, *hostName, *keyName;
- const char *nativeTail;
+ const TCHAR *nativeTail;
HKEY rootKey, subkey;
DWORD result;
int length;
@@ -510,7 +424,7 @@ DeleteKey(
*/
keyName = Tcl_GetStringFromObj(keyNameObj, &length);
- buffer = ckalloc((unsigned) length + 1);
+ buffer = ckalloc(length + 1);
strcpy(buffer, keyName);
if (ParseKeyName(interp, buffer, &hostName, &rootKey,
@@ -522,6 +436,7 @@ DeleteKey(
if (*keyName == '\0') {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("bad key: cannot delete root keys", -1));
+ Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", NULL);
ckfree(buffer);
return TCL_ERROR;
}
@@ -609,12 +524,12 @@ DeleteValue(
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
Tcl_WinUtfToTChar(valueName, length, &ds);
- result = regWinProcs->regDeleteValueProc(key, Tcl_DStringValue(&ds));
+ result = RegDeleteValue(key, (const TCHAR *)Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to delete value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to delete value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
result = TCL_ERROR;
} else {
@@ -652,9 +567,8 @@ GetKeyNames(
{
const char *pattern; /* Pattern being matched against subkeys */
HKEY key; /* Handle to the key being examined */
- DWORD subKeyCount; /* Number of subkeys to list */
- DWORD maxSubKeyLen; /* Maximum string length of any subkey */
- char *buffer; /* Buffer to hold the subkey name */
+ TCHAR buffer[MAX_KEY_LENGTH];
+ /* Buffer to hold the subkey name */
DWORD bufSize; /* Size of the buffer */
DWORD index; /* Position of the current subkey */
char *name; /* Subkey name */
@@ -678,48 +592,27 @@ GetKeyNames(
}
/*
- * Determine how big a buffer is needed for enumerating subkeys, and how
- * many subkeys there are.
- */
-
- result = regWinProcs->regQueryInfoKeyProc(key, NULL, NULL, NULL,
- &subKeyCount, &maxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
- if (result != ERROR_SUCCESS) {
- Tcl_SetObjResult(interp, Tcl_NewObj());
- Tcl_AppendResult(interp, "unable to query key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
- AppendSystemError(interp, result);
- RegCloseKey(key);
- return TCL_ERROR;
- }
- if (regWinProcs->useWide) {
- buffer = ckalloc((maxSubKeyLen+1) * sizeof(WCHAR));
- } else {
- buffer = ckalloc(maxSubKeyLen+1);
- }
-
- /*
* Enumerate the subkeys.
*/
resultPtr = Tcl_NewObj();
- for (index = 0; index < subKeyCount; ++index) {
- bufSize = maxSubKeyLen+1;
- result = regWinProcs->regEnumKeyExProc(key, index, buffer, &bufSize,
+ for (index = 0;; ++index) {
+ bufSize = MAX_KEY_LENGTH;
+ result = RegEnumKeyEx(key, index, buffer, &bufSize,
NULL, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
- Tcl_SetObjResult(interp, Tcl_NewObj());
- Tcl_AppendResult(interp, "unable to enumerate subkeys of \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
- AppendSystemError(interp, result);
- result = TCL_ERROR;
+ if (result == ERROR_NO_MORE_ITEMS) {
+ result = TCL_OK;
+ } else {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to enumerate subkeys of \"%s\": ",
+ Tcl_GetString(keyNameObj)));
+ AppendSystemError(interp, result);
+ result = TCL_ERROR;
+ }
break;
}
- if (regWinProcs->useWide) {
- Tcl_WinTCharToUtf((TCHAR *) buffer, bufSize * sizeof(WCHAR), &ds);
- } else {
- Tcl_WinTCharToUtf((TCHAR *) buffer, bufSize, &ds);
- }
+ Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds);
name = Tcl_DStringValue(&ds);
if (pattern && !Tcl_StringMatch(name, pattern)) {
Tcl_DStringFree(&ds);
@@ -734,9 +627,10 @@ GetKeyNames(
}
if (result == TCL_OK) {
Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */
}
- ckfree(buffer);
RegCloseKey(key);
return result;
}
@@ -768,7 +662,8 @@ GetType(
HKEY key;
DWORD result, type;
Tcl_DString ds;
- const char *valueName, *nativeValue;
+ const char *valueName;
+ const TCHAR *nativeValue;
int length;
/*
@@ -786,15 +681,15 @@ GetType(
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
nativeValue = Tcl_WinUtfToTChar(valueName, length, &ds);
- result = regWinProcs->regQueryValueExProc(key, nativeValue, NULL, &type,
+ result = RegQueryValueEx(key, nativeValue, NULL, &type,
NULL, NULL);
Tcl_DStringFree(&ds);
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get type of value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to get type of value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
return TCL_ERROR;
}
@@ -837,7 +732,8 @@ GetValue(
REGSAM mode) /* Mode flags to pass. */
{
HKEY key;
- const char *valueName, *nativeValue;
+ const char *valueName;
+ const TCHAR *nativeValue;
DWORD result, length, type;
Tcl_DString data, buf;
int nameLen;
@@ -862,13 +758,13 @@ GetValue(
*/
Tcl_DStringInit(&data);
- length = TCL_DSTRING_STATIC_SIZE - 1;
- Tcl_DStringSetLength(&data, (int) length);
+ Tcl_DStringSetLength(&data, TCL_DSTRING_STATIC_SIZE - 1);
+ length = TCL_DSTRING_STATIC_SIZE/sizeof(TCHAR) - 1;
valueName = Tcl_GetStringFromObj(valueNameObj, &nameLen);
nativeValue = Tcl_WinUtfToTChar(valueName, nameLen, &buf);
- result = regWinProcs->regQueryValueExProc(key, nativeValue, NULL, &type,
+ result = RegQueryValueEx(key, nativeValue, NULL, &type,
(BYTE *) Tcl_DStringValue(&data), &length);
while (result == ERROR_MORE_DATA) {
/*
@@ -877,17 +773,17 @@ GetValue(
* HKEY_PERFORMANCE_DATA
*/
- length *= 2;
- Tcl_DStringSetLength(&data, (int) length);
- result = regWinProcs->regQueryValueExProc(key, (char *) nativeValue,
+ length = Tcl_DStringLength(&data) * (2 / sizeof(TCHAR));
+ Tcl_DStringSetLength(&data, (int) length * sizeof(TCHAR));
+ result = RegQueryValueEx(key, nativeValue,
NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length);
}
Tcl_DStringFree(&buf);
RegCloseKey(key);
if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to get value \"",
- Tcl_GetString(valueNameObj), "\" from key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to get value \"%s\" from key \"%s\": ",
+ Tcl_GetString(valueNameObj), Tcl_GetString(keyNameObj)));
AppendSystemError(interp, result);
Tcl_DStringFree(&data);
return TCL_ERROR;
@@ -914,20 +810,17 @@ GetValue(
* we get bogus data.
*/
- while ((p < end)
- && (regWinProcs->useWide ? *((Tcl_UniChar *) p) : *p) != 0) {
+ while ((p < end) && *((Tcl_UniChar *) p) != 0) {
+ Tcl_UniChar *up;
+
Tcl_WinTCharToUtf((TCHAR *) p, -1, &buf);
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(Tcl_DStringValue(&buf),
Tcl_DStringLength(&buf)));
- if (regWinProcs->useWide) {
- Tcl_UniChar *up = (Tcl_UniChar *) p;
+ up = (Tcl_UniChar *) p;
- while (*up++ != 0) {}
- p = (char *) up;
- } else {
- while (*p++ != '\0') {}
- }
+ while (*up++ != 0) {/* empty body */}
+ p = (char *) up;
Tcl_DStringFree(&buf);
}
Tcl_SetObjResult(interp, resultPtr);
@@ -974,7 +867,7 @@ GetValueNames(
{
HKEY key;
Tcl_Obj *resultPtr;
- DWORD index, size, maxSize, result;
+ DWORD index, size, result;
Tcl_DString buffer, ds;
const char *pattern, *name;
@@ -987,27 +880,9 @@ GetValueNames(
return TCL_ERROR;
}
- /*
- * Query the key to determine the appropriate buffer size to hold the
- * largest value name plus the terminating null.
- */
-
- result = regWinProcs->regQueryInfoKeyProc(key, NULL, NULL, NULL, NULL,
- NULL, NULL, &index, &maxSize, NULL, NULL, NULL);
- if (result != ERROR_SUCCESS) {
- Tcl_AppendResult(interp, "unable to query key \"",
- Tcl_GetString(keyNameObj), "\": ", NULL);
- AppendSystemError(interp, result);
- RegCloseKey(key);
- result = TCL_ERROR;
- goto done;
- }
- maxSize++;
-
resultPtr = Tcl_NewObj();
Tcl_DStringInit(&buffer);
- Tcl_DStringSetLength(&buffer,
- (int) (regWinProcs->useWide ? maxSize*2 : maxSize));
+ Tcl_DStringSetLength(&buffer, (int) (MAX_KEY_LENGTH * sizeof(TCHAR)));
index = 0;
result = TCL_OK;
@@ -1023,12 +898,10 @@ GetValueNames(
* each iteration because RegEnumValue smashes the old value.
*/
- size = maxSize;
- while (regWinProcs->regEnumValueProc(key,index, Tcl_DStringValue(&buffer),
+ size = MAX_KEY_LENGTH;
+ while (RegEnumValue(key,index, (TCHAR *)Tcl_DStringValue(&buffer),
&size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
- if (regWinProcs->useWide) {
- size *= 2;
- }
+ size *= sizeof(TCHAR);
Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&buffer), (int) size,
&ds);
@@ -1044,12 +917,10 @@ GetValueNames(
Tcl_DStringFree(&ds);
index++;
- size = maxSize;
+ size = MAX_KEY_LENGTH;
}
Tcl_SetObjResult(interp, resultPtr);
Tcl_DStringFree(&buffer);
-
- done:
RegCloseKey(key);
return result;
}
@@ -1085,7 +956,7 @@ OpenKey(
DWORD result;
keyName = Tcl_GetStringFromObj(keyNameObj, &length);
- buffer = ckalloc((unsigned) length + 1);
+ buffer = ckalloc(length + 1);
strcpy(buffer, keyName);
result = ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName);
@@ -1141,7 +1012,7 @@ OpenSubKey(
if (hostName) {
hostName = (char *) Tcl_WinUtfToTChar(hostName, -1, &buf);
- result = regWinProcs->regConnectRegistryProc(hostName, rootKey,
+ result = RegConnectRegistry((TCHAR *)hostName, rootKey,
&rootKey);
Tcl_DStringFree(&buf);
if (result != ERROR_SUCCESS) {
@@ -1158,7 +1029,7 @@ OpenSubKey(
if (flags & REG_CREATE) {
DWORD create;
- result = regWinProcs->regCreateKeyExProc(rootKey, keyName, 0, NULL,
+ result = RegCreateKeyEx(rootKey, (TCHAR *)keyName, 0, NULL,
REG_OPTION_NON_VOLATILE, mode, NULL, keyPtr, &create);
} else if (rootKey == HKEY_PERFORMANCE_DATA) {
/*
@@ -1169,7 +1040,7 @@ OpenSubKey(
*keyPtr = HKEY_PERFORMANCE_DATA;
result = ERROR_SUCCESS;
} else {
- result = regWinProcs->regOpenKeyExProc(rootKey, keyName, 0, mode,
+ result = RegOpenKeyEx(rootKey, (TCHAR *)keyName, 0, mode,
keyPtr);
}
Tcl_DStringFree(&buf);
@@ -1233,8 +1104,9 @@ ParseKeyName(
rootName = name;
}
if (!rootName) {
- Tcl_AppendResult(interp, "bad key \"", name,
- "\": must start with a valid root", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad key \"%s\": must start with a valid root", name));
+ Tcl_SetErrorCode(interp, "WIN_REG", "NO_ROOT_KEY", NULL);
return TCL_ERROR;
}
@@ -1286,11 +1158,11 @@ ParseKeyName(
static DWORD
RecursiveDeleteKey(
HKEY startKey, /* Parent of key to be deleted. */
- const char *keyName, /* Name of key to be deleted in external
+ const TCHAR *keyName, /* Name of key to be deleted in external
* encoding, not UTF. */
REGSAM mode) /* Mode flags to pass. */
{
- DWORD result, size, maxSize;
+ DWORD result, size;
Tcl_DString subkey;
HKEY hKey;
REGSAM saveMode = mode;
@@ -1306,20 +1178,13 @@ RecursiveDeleteKey(
}
mode |= KEY_ENUMERATE_SUB_KEYS | DELETE | KEY_QUERY_VALUE;
- result = regWinProcs->regOpenKeyExProc(startKey, keyName, 0, mode, &hKey);
- if (result != ERROR_SUCCESS) {
- return result;
- }
- result = regWinProcs->regQueryInfoKeyProc(hKey, NULL, NULL, NULL, NULL,
- &maxSize, NULL, NULL, NULL, NULL, NULL, NULL);
- maxSize++;
+ result = RegOpenKeyEx(startKey, keyName, 0, mode, &hKey);
if (result != ERROR_SUCCESS) {
return result;
}
Tcl_DStringInit(&subkey);
- Tcl_DStringSetLength(&subkey,
- (int) ((regWinProcs->useWide) ? maxSize * 2 : maxSize));
+ Tcl_DStringSetLength(&subkey, (int) (MAX_KEY_LENGTH * sizeof(TCHAR)));
mode = saveMode;
while (result == ERROR_SUCCESS) {
@@ -1327,9 +1192,9 @@ RecursiveDeleteKey(
* Always get index 0 because key deletion changes ordering.
*/
- size = maxSize;
- result = regWinProcs->regEnumKeyExProc(hKey, 0,
- Tcl_DStringValue(&subkey), &size, NULL, NULL, NULL, NULL);
+ size = MAX_KEY_LENGTH;
+ result = RegEnumKeyEx(hKey, 0, (TCHAR *)Tcl_DStringValue(&subkey),
+ &size, NULL, NULL, NULL, NULL);
if (result == ERROR_NO_MORE_ITEMS) {
/*
* RegDeleteKeyEx doesn't exist on non-64bit XP platforms, so we
@@ -1341,26 +1206,21 @@ RecursiveDeleteKey(
HINSTANCE dllH;
checkExProc = 1;
- dllH = LoadLibrary("advapi32.dll");
+ dllH = LoadLibrary(TEXT("advapi32.dll"));
if (dllH) {
- if (regWinProcs->useWide) {
- regDeleteKeyExProc = (FARPROC)
- GetProcAddress(dllH, "RegDeleteKeyExW");
- } else {
- regDeleteKeyExProc = (FARPROC)
- GetProcAddress(dllH, "RegDeleteKeyExA");
- }
+ regDeleteKeyExProc = (FARPROC)
+ GetProcAddress(dllH, "RegDeleteKeyExW");
}
}
if (mode && regDeleteKeyExProc) {
result = regDeleteKeyExProc(startKey, keyName, mode, 0);
} else {
- result = regWinProcs->regDeleteKeyProc(startKey, keyName);
+ result = RegDeleteKey(startKey, keyName);
}
break;
} else if (result == ERROR_SUCCESS) {
- result = RecursiveDeleteKey(hKey, Tcl_DStringValue(&subkey),
- mode);
+ result = RecursiveDeleteKey(hKey,
+ (const TCHAR *) Tcl_DStringValue(&subkey), mode);
}
}
Tcl_DStringFree(&subkey);
@@ -1416,7 +1276,7 @@ SetValue(
}
valueName = Tcl_GetStringFromObj(valueNameObj, &length);
- valueName = Tcl_WinUtfToTChar(valueName, length, &nameBuf);
+ valueName = (char *) Tcl_WinUtfToTChar(valueName, length, &nameBuf);
if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
int value;
@@ -1427,8 +1287,8 @@ SetValue(
return TCL_ERROR;
}
- value = ConvertDWORD((DWORD)type, (DWORD)value);
- result = regWinProcs->regSetValueExProc(key, valueName, 0,
+ value = ConvertDWORD((DWORD) type, (DWORD) value);
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
@@ -1449,21 +1309,20 @@ SetValue(
Tcl_DStringInit(&data);
for (i = 0; i < objc; i++) {
- Tcl_DStringAppend(&data, Tcl_GetString(objv[i]), -1);
+ const char *bytes = Tcl_GetStringFromObj(objv[i], &length);
+
+ Tcl_DStringAppend(&data, bytes, length);
/*
- * Add a null character to separate this value from the next. We
- * accomplish this by growing the string by one byte. Since the
- * DString always tacks on an extra null byte, the new byte will
- * already be set to null.
+ * Add a null character to separate this value from the next.
*/
- Tcl_DStringSetLength(&data, Tcl_DStringLength(&data)+1);
+ Tcl_DStringAppend(&data, "", 1); /* NUL-terminated string */
}
Tcl_WinUtfToTChar(Tcl_DStringValue(&data), Tcl_DStringLength(&data)+1,
&buf);
- result = regWinProcs->regSetValueExProc(key, valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) Tcl_DStringValue(&buf),
(DWORD) Tcl_DStringLength(&buf));
Tcl_DStringFree(&data);
@@ -1472,18 +1331,16 @@ SetValue(
Tcl_DString buf;
const char *data = Tcl_GetStringFromObj(dataObj, &length);
- data = Tcl_WinUtfToTChar(data, length, &buf);
+ data = (char *) Tcl_WinUtfToTChar(data, length, &buf);
/*
* Include the null in the length, padding if needed for Unicode.
*/
- if (regWinProcs->useWide) {
- Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
- }
+ Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
length = Tcl_DStringLength(&buf) + 1;
- result = regWinProcs->regSetValueExProc(key, valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, (BYTE *) data, (DWORD) length);
Tcl_DStringFree(&buf);
} else {
@@ -1494,7 +1351,7 @@ SetValue(
*/
data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &length);
- result = regWinProcs->regSetValueExProc(key, valueName, 0,
+ result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, data, (DWORD) length);
}
@@ -1534,7 +1391,7 @@ BroadcastValue(
Tcl_Obj *const objv[]) /* Argument values. */
{
LRESULT result;
- DWORD sendResult;
+ DWORD_PTR sendResult;
UINT timeout = 3000;
int len;
const char *str;
@@ -1560,7 +1417,7 @@ BroadcastValue(
* Use the ignore the result.
*/
- result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE,
+ result = SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE,
(WPARAM) 0, (LPARAM) str, SMTO_ABORTIFHUNG, timeout, &sendResult);
objPtr = Tcl_NewObj();
@@ -1594,7 +1451,7 @@ AppendSystemError(
DWORD error) /* Result code from error. */
{
int length;
- WCHAR *wMsgPtr, **wMsgPtrPtr = &wMsgPtr;
+ TCHAR *tMsgPtr, **tMsgPtrPtr = &tMsgPtr;
const char *msg;
char id[TCL_INTEGER_SPACE], msgBuf[24 + TCL_INTEGER_SPACE];
Tcl_DString ds;
@@ -1603,40 +1460,18 @@ AppendSystemError(
if (Tcl_IsShared(resultPtr)) {
resultPtr = Tcl_DuplicateObj(resultPtr);
}
- length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
+ length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (WCHAR *) wMsgPtrPtr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (TCHAR *) tMsgPtrPtr,
0, NULL);
if (length == 0) {
- char *msgPtr;
-
- length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr,
- 0, NULL);
- if (length > 0) {
- wMsgPtr = (WCHAR *)
- LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, msgPtr, length + 1, wMsgPtr,
- length + 1);
- LocalFree(msgPtr);
- }
- }
- if (length == 0) {
- if (error == ERROR_CALL_NOT_IMPLEMENTED) {
- strcpy(msgBuf, "function not supported under Win32s");
- } else {
- sprintf(msgBuf, "unknown error: %ld", error);
- }
+ sprintf(msgBuf, "unknown error: %ld", error);
msg = msgBuf;
} else {
- Tcl_Encoding encoding;
char *msgPtr;
- encoding = Tcl_GetEncoding(NULL, "unicode");
- Tcl_ExternalToUtfDString(encoding, (char *) wMsgPtr, -1, &ds);
- Tcl_FreeEncoding(encoding);
- LocalFree(wMsgPtr);
+ Tcl_WinTCharToUtf(tMsgPtr, -1, &ds);
+ LocalFree(tMsgPtr);
msgPtr = Tcl_DStringValue(&ds);
length = Tcl_DStringLength(&ds);
@@ -1687,14 +1522,15 @@ ConvertDWORD(
DWORD type, /* Either REG_DWORD or REG_DWORD_BIG_ENDIAN */
DWORD value) /* The value to be converted. */
{
- DWORD order = 1;
+ const 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;
+ localType = (*((const char *) &order) == 1)
+ ? REG_DWORD : REG_DWORD_BIG_ENDIAN;
return (type != localType) ? (DWORD) SWAPLONG(value) : value;
}