Attachment "winReg_v2.diff" to
ticket [3362446fff]
added by
mistachkin
2011-07-11 17:19:05.
--- win/tclWinReg.c
+++ win/tclWinReg.c
@@ -32,10 +32,18 @@
#ifndef KEY_WOW64_32KEY
#define KEY_WOW64_32KEY (0x0200)
#endif
/*
+ * The maximum length of a sub-key name.
+ */
+
+#ifndef MAX_KEY_LENGTH
+#define MAX_KEY_LENGTH 256
+#endif
+
+/*
* 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.
*/
@@ -553,10 +561,11 @@
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 */
TCHAR *buffer; /* Buffer to hold the subkey name */
+ DWORD maxBufSize; /* Maximum size of the buffer */
DWORD bufSize; /* Size of the buffer */
DWORD index; /* Position of the current subkey */
char *name; /* Subkey name */
Tcl_Obj *resultPtr; /* List of subkeys being accumulated */
int result = TCL_OK; /* Return value from this command */
@@ -590,30 +599,38 @@
Tcl_GetString(keyNameObj), "\": ", NULL);
AppendSystemError(interp, result);
RegCloseKey(key);
return TCL_ERROR;
}
- buffer = ckalloc((maxSubKeyLen+1) * sizeof(TCHAR));
+ maxBufSize = maxSubKeyLen + 1;
+ buffer = ckalloc(maxBufSize * sizeof(TCHAR));
/*
* Enumerate the subkeys.
*/
resultPtr = Tcl_NewObj();
for (index = 0; index < subKeyCount; ++index) {
- bufSize = maxSubKeyLen+1;
+ bufSize = maxBufSize;
result = RegEnumKeyEx(key, index, buffer, &bufSize,
NULL, NULL, NULL, NULL);
+ if (result == ERROR_MORE_DATA && maxBufSize < MAX_KEY_LENGTH) {
+ maxBufSize = MAX_KEY_LENGTH + 1;
+ buffer = ckrealloc(buffer, maxBufSize * sizeof(TCHAR));
+ bufSize = maxBufSize;
+ 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;
break;
}
- Tcl_WinTCharToUtf(buffer, bufSize * sizeof(WCHAR), &ds);
+ Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds);
name = Tcl_DStringValue(&ds);
if (pattern && !Tcl_StringMatch(name, pattern)) {
Tcl_DStringFree(&ds);
continue;
}
@@ -624,10 +641,12 @@
break;
}
}
if (result == TCL_OK) {
Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ Tcl_DecrRefCount(resultPtr); /* BUGFIX: Don't leak on failure. */
}
ckfree(buffer);
RegCloseKey(key);
return result;
@@ -896,11 +915,11 @@
maxSize++;
resultPtr = Tcl_NewObj();
Tcl_DStringInit(&buffer);
Tcl_DStringSetLength(&buffer,
- (int) (maxSize*sizeof(WCHAR)));
+ (int) (maxSize*sizeof(TCHAR)));
index = 0;
result = TCL_OK;
if (patternObj) {
pattern = Tcl_GetString(patternObj);
@@ -1207,11 +1226,11 @@
return result;
}
Tcl_DStringInit(&subkey);
Tcl_DStringSetLength(&subkey,
- (int) (maxSize * sizeof(WCHAR)));
+ (int) (maxSize * sizeof(TCHAR)));
mode = saveMode;
while (result == ERROR_SUCCESS) {
/*
* Always get index 0 because key deletion changes ordering.