summaryrefslogtreecommitdiffstats
path: root/win/tclWinReg.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2012-06-21 18:38:23 (GMT)
committerdgp <dgp@users.sourceforge.net>2012-06-21 18:38:23 (GMT)
commitf81f14146b45e2134cf88261271a8440bb1a3405 (patch)
tree25eaeba0ea65f4e47e80ba0331b68de985719347 /win/tclWinReg.c
parent3c7c7211e92d675398a7bbda6dcc19d9edc3fc0d (diff)
parent687013812cd6ca56d2bfc1c0b75d98a6f8a2d264 (diff)
downloadtcl-f81f14146b45e2134cf88261271a8440bb1a3405.zip
tcl-f81f14146b45e2134cf88261271a8440bb1a3405.tar.gz
tcl-f81f14146b45e2134cf88261271a8440bb1a3405.tar.bz2
merge 8.5
Diffstat (limited to 'win/tclWinReg.c')
-rw-r--r--win/tclWinReg.c113
1 files changed, 33 insertions, 80 deletions
diff --git a/win/tclWinReg.c b/win/tclWinReg.c
index 13216f3..343a22f 100644
--- a/win/tclWinReg.c
+++ b/win/tclWinReg.c
@@ -13,6 +13,7 @@
*/
#include "tclInt.h"
+#include "tclPort.h"
#ifdef _MSC_VER
# pragma comment (lib, "advapi32.lib")
#endif
@@ -28,6 +29,14 @@
#define TCL_STORAGE_CLASS DLLEXPORT
/*
+ * The maximum length of a sub-key name.
+ */
+
+#ifndef MAX_KEY_LENGTH
+#define MAX_KEY_LENGTH 256
+#endif
+
+/*
* The following macros convert between different endian ints.
*/
@@ -94,9 +103,6 @@ typedef struct RegWinProcs {
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,
@@ -121,9 +127,6 @@ static RegWinProcs asciiProcs = {
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,
@@ -146,9 +149,6 @@ static RegWinProcs unicodeProcs = {
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,
@@ -236,7 +236,7 @@ Registry_Init(
cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd,
(ClientData)interp, DeleteCmd);
Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, (ClientData)cmd);
- return Tcl_PkgProvide(interp, "registry", "1.2.1");
+ return Tcl_PkgProvide(interp, "registry", "1.2.2");
}
/*
@@ -589,9 +589,7 @@ GetKeyNames(
{
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*2]; /* Buffer to hold the subkey name */
DWORD bufSize; /* Size of the buffer */
DWORD index; /* Position of the current subkey */
char *name; /* Subkey name */
@@ -613,43 +611,24 @@ GetKeyNames(
return TCL_ERROR;
}
- /*
- * 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;
+ for (index = 0;; ++index) {
+ bufSize = MAX_KEY_LENGTH;
result = (*regWinProcs->regEnumKeyExProc)
(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_NewObj());
+ Tcl_AppendResult(interp,
+ "unable to enumerate subkeys of \"",
+ Tcl_GetString(keyNameObj), "\": ", NULL);
+ AppendSystemError(interp, result);
+ result = TCL_ERROR;
+ }
break;
}
if (regWinProcs->useWide) {
@@ -675,7 +654,6 @@ GetKeyNames(
Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */
}
- ckfree(buffer);
RegCloseKey(key);
return result;
}
@@ -801,8 +779,8 @@ 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 / (regWinProcs->useWide ? 2 : 1) - 1;
valueName = Tcl_GetStringFromObj(valueNameObj, &nameLen);
nativeValue = Tcl_WinUtfToTChar(valueName, nameLen, &buf);
@@ -817,7 +795,7 @@ GetValue(
*/
length *= 2;
- Tcl_DStringSetLength(&data, (int) length);
+ Tcl_DStringSetLength(&data, (int) length * (regWinProcs->useWide ? 2 : 1));
result = (*regWinProcs->regQueryValueExProc)(key, (char *) nativeValue,
NULL, &type, (BYTE *) Tcl_DStringValue(&data), &length);
}
@@ -911,7 +889,7 @@ GetValueNames(
{
HKEY key;
Tcl_Obj *resultPtr;
- DWORD index, size, maxSize, result;
+ DWORD index, size, result;
Tcl_DString buffer, ds;
char *pattern, *name;
@@ -924,27 +902,10 @@ 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));
+ (int) ((regWinProcs->useWide) ? MAX_KEY_LENGTH*2 : MAX_KEY_LENGTH));
index = 0;
result = TCL_OK;
@@ -960,7 +921,7 @@ GetValueNames(
* each iteration because RegEnumValue smashes the old value.
*/
- size = maxSize;
+ size = MAX_KEY_LENGTH;
while ((*regWinProcs->regEnumValueProc)(key, index,
Tcl_DStringValue(&buffer), &size, NULL, NULL, NULL, NULL)
== ERROR_SUCCESS) {
@@ -983,12 +944,10 @@ GetValueNames(
Tcl_DStringFree(&ds);
index++;
- size = maxSize;
+ size = MAX_KEY_LENGTH;
}
Tcl_SetObjResult(interp, resultPtr);
Tcl_DStringFree(&buffer);
-
- done:
RegCloseKey(key);
return result;
}
@@ -1226,7 +1185,7 @@ RecursiveDeleteKey(
CONST char *keyName) /* Name of key to be deleted in external
* encoding, not UTF. */
{
- DWORD result, size, maxSize;
+ DWORD result, size;
Tcl_DString subkey;
HKEY hKey;
@@ -1243,23 +1202,17 @@ RecursiveDeleteKey(
if (result != ERROR_SUCCESS) {
return result;
}
- result = (*regWinProcs->regQueryInfoKeyProc)(hKey, NULL, NULL, NULL, NULL,
- &maxSize, NULL, NULL, NULL, NULL, NULL, NULL);
- maxSize++;
- if (result != ERROR_SUCCESS) {
- return result;
- }
Tcl_DStringInit(&subkey);
Tcl_DStringSetLength(&subkey,
- (int) ((regWinProcs->useWide) ? maxSize * 2 : maxSize));
+ (int) ((regWinProcs->useWide) ? MAX_KEY_LENGTH * 2 : MAX_KEY_LENGTH));
while (result == ERROR_SUCCESS) {
/*
* Always get index 0 because key deletion changes ordering.
*/
- size = maxSize;
+ size = MAX_KEY_LENGTH;
result=(*regWinProcs->regEnumKeyExProc)(hKey, 0,
Tcl_DStringValue(&subkey), &size, NULL, NULL, NULL, NULL);
if (result == ERROR_NO_MORE_ITEMS) {