Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -1201,11 +1201,11 @@ #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES path = [[OFWindowsRegistryKey localMachineKey] stringForValue: @"DataBasePath" - subKeyPath: @"SYSTEM\\CurrentControlSet\\Services\\" + subkeyPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters"]; path = [path stringByAppendingPathComponent: @"hosts"]; if (path != nil) [self of_parseHosts: path]; Index: src/OFWindowsRegistryKey.h ================================================================== --- src/OFWindowsRegistryKey.h +++ src/OFWindowsRegistryKey.h @@ -20,10 +20,12 @@ #include OF_ASSUME_NONNULL_BEGIN +@class OFData; + /*! * @class OFWindowsRegistryKey \ * OFWindowsRegistryKey.h ObjFW/OFWindowsRegistryKey.h */ @interface OFWindowsRegistryKey: OFObject @@ -68,62 +70,62 @@ + (instancetype)usersKey; - (instancetype)init OF_UNAVAILABLE; /*! - * @brief Opens the sub key at the specified path. + * @brief Opens the subkey at the specified path. * - * @param path The path of the sub key to open + * @param path The path of the subkey to open * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation - * @return The sub key with the specified path, or nil if it does not exist + * @return The subkey with the specified path, or nil if it does not exist */ - (nullable OFWindowsRegistryKey *) openSubKeyWithPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! - * @brief Opens the sub key at the specified path. + * @brief Opens the subkey at the specified path. * - * @param path The path of the sub key to open + * @param path The path of the subkey to open * @param options Please refer to the `RegOpenKeyEx()` documentation. Usually 0. * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation - * @return The sub key with the specified path, or nil if it does not exist + * @return The subkey with the specified path, or nil if it does not exist */ - (nullable OFWindowsRegistryKey *) openSubKeyWithPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! - * @brief Creates a sub key at the specified path or opens it if it already + * @brief Creates a subkey at the specified path or opens it if it already * exists. * - * @param path The path of the sub key to create + * @param path The path of the subkey to create * @param securityAndAccessRights Please refer to the `RegCreateKeyEx()` * documentation - * @return The sub key with the specified path + * @return The subkey with the specified path */ - (OFWindowsRegistryKey *) createSubKeyWithPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! - * @brief Creates a sub key at the specified path or opens it if it already + * @brief Creates a subkey at the specified path or opens it if it already * exists. * - * @param path The path of the sub key to create + * @param path The path of the subkey to create * @param options Please refer to the `RegCreateKeyEx()` documentation. * Usually 0. * @param securityAndAccessRights Please refer to the `RegCreateKeyEx()` * documentation * @param securityAttributes Please refer to the `RegCreateKeyEx()` * documentation. Usually NULL. * @param disposition Whether the key was created or already existed. Please * refer to the `RegCreateKeyEx()` documentation. - * @return The sub key with the specified path + * @return The subkey with the specified path */ - (OFWindowsRegistryKey *) createSubKeyWithPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights @@ -132,27 +134,27 @@ /*! * @brief Returns the string for the specified value at the specified path. * * @param value The name of the value to return - * @param subKeyPath The path of the key from which to retrieve the value + * @param subkeyPath The path of the key from which to retrieve the value * @return The string for the specified value */ - (nullable OFString *)stringForValue: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath; + subkeyPath: (nullable OFString *)subkeyPath; /*! - * @brief Returns the string for the specified value at the specified path. + * @brief Returns the data for the specified value at the specified path. * * @param value The name of the value to return - * @param subKeyPath The path of the key from which to retrieve the value + * @param subkeyPath The path of the key from which to retrieve the value * @param flags Extra flags for `RegGetValue()`. Usually 0. * @param type A pointer to store the type of the value, or NULL - * @return The string for the specified value + * @return The data for the specified value */ -- (nullable OFString *)stringForValue: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath - flags: (DWORD)flags - type: (nullable LPDWORD)type; +- (nullable OFData *)dataForValue: (nullable OFString *)value + subkeyPath: (nullable OFString *)subkeyPath + flags: (DWORD)flags + type: (nullable LPDWORD)type; @end OF_ASSUME_NONNULL_END Index: src/OFWindowsRegistryKey.m ================================================================== --- src/OFWindowsRegistryKey.m +++ src/OFWindowsRegistryKey.m @@ -16,14 +16,16 @@ */ #include "config.h" #import "OFWindowsRegistryKey.h" +#import "OFData.h" #include #import "OFCreateWindowsRegistryKeyFailedException.h" +#import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFReadWindowsRegistryValueFailedException.h" @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey @@ -162,68 +164,100 @@ close: true] autorelease]; } - (OFString *)stringForValue: (OFString *)value - subKeyPath: (OFString *)subKeyPath -{ - return [self stringForValue: value - subKeyPath: subKeyPath - flags: 0 - type: NULL]; -} - -- (OFString *)stringForValue: (OFString *)value - subKeyPath: (OFString *)subKeyPath - flags: (DWORD)flags - type: (LPDWORD)type + subkeyPath: (OFString *)subkeyPath { void *pool = objc_autoreleasePoolPush(); - of_char16_t stackBuffer[256], *buffer = stackBuffer; - DWORD length = sizeof(stackBuffer); - LSTATUS status; + OFData *data = [self dataForValue: value + subkeyPath: subkeyPath + flags: RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ + type: NULL]; + const of_char16_t *UTF16String; + size_t length; OFString *ret; - if ((status = RegGetValueW(_hKey, [subKeyPath UTF16String], - [value UTF16String], flags | RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ, - type, buffer, &length)) != ERROR_SUCCESS) { - OFObject *tmp; - - if (status == ERROR_FILE_NOT_FOUND) { - objc_autoreleasePoolPop(pool); - return nil; - } - - if (status != ERROR_MORE_DATA) - @throw [OFReadWindowsRegistryValueFailedException - exceptionWithRegistryKey: self - value: value - subKeyPath: subKeyPath - flags: flags - status: status]; - - tmp = [[[OFObject alloc] init] autorelease]; - buffer = [tmp allocMemoryWithSize: length]; - - if ((status = RegGetValueW(_hKey, [subKeyPath UTF16String], - [value UTF16String], flags | RRF_RT_REG_SZ | - RRF_RT_REG_EXPAND_SZ, NULL, buffer, &length)) != - ERROR_SUCCESS) - @throw [OFReadWindowsRegistryValueFailedException - exceptionWithRegistryKey: self - value: value - subKeyPath: subKeyPath - flags: flags - status: status]; - } - - /* - * We do not specify a length, as the length returned by RegGetValue() - * sometimes seems to be larger than the string. - */ - ret = [[OFString alloc] initWithUTF16String: buffer]; + if (data == nil) + return nil; + + UTF16String = [data items]; + length = [data count]; + + if ([data itemSize] != 1 || length % 2 == 1) + @throw [OFInvalidFormatException exception]; + + length /= 2; + + /* + * REG_SZ and REG_EXPAND_SZ contain a \0, but can contain data after it + * that should be ignored. + */ + for (size_t i = 0; i < length; i++) { + if (UTF16String[i] == 0) { + length = i; + break; + } + } + + ret = [[OFString alloc] initWithUTF16String: UTF16String + length: length]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } + +- (OFData *)dataForValue: (OFString *)value + subkeyPath: (OFString *)subkeyPath + flags: (DWORD)flags + type: (LPDWORD)type +{ + void *pool = objc_autoreleasePoolPush(); + char stackBuffer[256], *buffer = stackBuffer; + DWORD length = sizeof(stackBuffer); + OFMutableData *ret = nil; + LSTATUS status; + + for (;;) { + status = RegGetValueW(_hKey, [subkeyPath UTF16String], + [value UTF16String], flags, type, buffer, &length); + + switch (status) { + case ERROR_SUCCESS: + if (buffer == stackBuffer) { + objc_autoreleasePoolPop(pool); + + return [OFData dataWithItems: buffer + count: length]; + } else { + [ret makeImmutable]; + [ret retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; + } + case ERROR_FILE_NOT_FOUND: + objc_autoreleasePoolPop(pool); + + return nil; + case ERROR_MORE_DATA: + objc_autoreleasePoolPop(pool); + pool = objc_autoreleasePoolPush(); + + ret = [OFMutableData dataWithCapacity: length]; + [ret increaseCountBy: length]; + buffer = [ret items]; + + continue; + default: + @throw [OFReadWindowsRegistryValueFailedException + exceptionWithRegistryKey: self + value: value + subkeyPath: subkeyPath + flags: flags + status: status]; + } + } +} @end Index: src/exceptions/OFCreateWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFCreateWindowsRegistryKeyFailedException.h +++ src/exceptions/OFCreateWindowsRegistryKeyFailedException.h @@ -38,32 +38,32 @@ LPSECURITY_ATTRIBUTES _Nullable _securityAttributes; LSTATUS _status; } /*! - * @brief The registry key on which creating the sub key failed. + * @brief The registry key on which creating the subkey failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /*! - * @brief The path for the sub key that could not be created. + * @brief The path for the subkey that could not be created. */ @property (readonly, nonatomic) OFString *path; /*! - * @brief The options for the sub key that could not be created. + * @brief The options for the subkey that could not be created. */ @property (readonly, nonatomic) DWORD options; /*! - * @brief The security and access rights for the sub key that could not be + * @brief The security and access rights for the subkey that could not be * created. */ @property (readonly, nonatomic) REGSAM securityAndAccessRights; /*! - * @brief The security options for the sub key that could not be created. + * @brief The security options for the subkey that could not be created. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) LPSECURITY_ATTRIBUTES securityAttributes; /*! @@ -73,16 +73,16 @@ /*! * @brief Creates a new, autoreleased create Windows registry key failed * exception. * - * @param registryKey The registry key on which creating the sub key failed - * @param path The path for the sub key that could not be created - * @param options The options for the sub key that could not be created + * @param registryKey The registry key on which creating the subkey failed + * @param path The path for the subkey that could not be created + * @param options The options for the subkey that could not be created * @param securityAndAccessRights The security and access rights for the sub * key that could not be created - * @param securityAttributes The security options for the sub key that could + * @param securityAttributes The security options for the subkey that could * not be created * @param status The status returned by RegCreateKeyEx() * @return A new, autoreleased creates Windows registry key failed exception */ + (instancetype) @@ -97,16 +97,16 @@ /*! * @brief Initializes an already allocated create Windows registry key failed * exception. * - * @param registryKey The registry key on which creating the sub key failed - * @param path The path for the sub key that could not be created - * @param options The options for the sub key that could not be created + * @param registryKey The registry key on which creating the subkey failed + * @param path The path for the subkey that could not be created + * @param options The options for the subkey that could not be created * @param securityAndAccessRights The security and access rights for the sub * key that could not be created - * @param securityAttributes The security options for the sub key that could + * @param securityAttributes The security options for the subkey that could * not be created * @param status The status returned by RegCreateKeyEx() * @return An initialized create Windows registry key failed exception */ - (instancetype) Index: src/exceptions/OFCreateWindowsRegistryKeyFailedException.m ================================================================== --- src/exceptions/OFCreateWindowsRegistryKeyFailedException.m +++ src/exceptions/OFCreateWindowsRegistryKeyFailedException.m @@ -79,9 +79,9 @@ } - (OFString *)description { return [OFString stringWithFormat: - @"Failed to create sub key at path %@: Status code %u!", + @"Failed to create subkey at path %@: Status code %u!", _path, _status]; } @end Index: src/exceptions/OFOpenWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFOpenWindowsRegistryKeyFailedException.h +++ src/exceptions/OFOpenWindowsRegistryKeyFailedException.h @@ -38,26 +38,26 @@ LPSECURITY_ATTRIBUTES _Nullable _securityAttributes; LSTATUS _status; } /*! - * @brief The registry key on which opening the sub key failed. + * @brief The registry key on which opening the subkey failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /*! - * @brief The path for the sub key that could not be opened. + * @brief The path for the subkey that could not be opened. */ @property (readonly, nonatomic) OFString *path; /*! - * @brief The options for the sub key that could not be opened. + * @brief The options for the subkey that could not be opened. */ @property (readonly, nonatomic) DWORD options; /*! - * @brief The security and access rights for the sub key that could not be + * @brief The security and access rights for the subkey that could not be * opened. */ @property (readonly, nonatomic) REGSAM securityAndAccessRights; /*! @@ -67,13 +67,13 @@ /*! * @brief Creates a new, autoreleased open Windows registry key failed * exception. * - * @param registryKey The registry key on which opening the sub key failed - * @param path The path for the sub key that could not be opened - * @param options The options for the sub key that could not be opened + * @param registryKey The registry key on which opening the subkey failed + * @param path The path for the subkey that could not be opened + * @param options The options for the subkey that could not be opened * @param securityAndAccessRights The security and access rights for the sub * key that could not be opened * @param status The status returned by RegOpenKeyEx() * @return A new, autoreleased open Windows registry key failed exception */ @@ -88,13 +88,13 @@ /*! * @brief Initializes an already allocated open Windows registry key failed * exception. * - * @param registryKey The registry key on which opening the sub key failed - * @param path The path for the sub key that could not be opened - * @param options The options for the sub key that could not be opened + * @param registryKey The registry key on which opening the subkey failed + * @param path The path for the subkey that could not be opened + * @param options The options for the subkey that could not be opened * @param securityAndAccessRights The security and access rights for the sub * key that could not be opened * @param status The status returned by RegOpenKeyEx() * @return An initialized open Windows registry key failed exception */ Index: src/exceptions/OFOpenWindowsRegistryKeyFailedException.m ================================================================== --- src/exceptions/OFOpenWindowsRegistryKeyFailedException.m +++ src/exceptions/OFOpenWindowsRegistryKeyFailedException.m @@ -75,9 +75,9 @@ } - (OFString *)description { return [OFString stringWithFormat: - @"Failed to open sub key at path %@: Status code %u!", + @"Failed to open subkey at path %@: Status code %u!", _path, _status]; } @end Index: src/exceptions/OFReadWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFReadWindowsRegistryValueFailedException.h +++ src/exceptions/OFReadWindowsRegistryValueFailedException.h @@ -30,30 +30,29 @@ * @brief An exception indicating that reading a Windows registry value failed. */ @interface OFReadWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; - OFString *_Nullable _value, *_Nullable _subKeyPath; + OFString *_Nullable _value, *_Nullable _subkeyPath; DWORD _flags; LSTATUS _status; } /*! - * @brief The registry key on which reading the value at the sub key path - * failed. + * @brief The registry key on which reading the value at the key path failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /*! * @brief The value for which reading failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; /*! - * @brief The sub key path at which reading the value failed. + * @brief The subkey path at which reading the value failed. */ -@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *subKeyPath; +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *subkeyPath; /*! * @brief The flags with which reading the value failed. */ @property (readonly, nonatomic) DWORD flags; @@ -68,18 +67,18 @@ * exception. * * @param registryKey The registry key on which reading the value at the sub * key path failed * @param value The value for which reading failed - * @param subKeyPath The sub key path at which reading the value failed + * @param subkeyPath The subkey path at which reading the value failed * @param flags The flags with which reading the value failed * @param status The status returned by RegGetValueEx() * @return A new, autoreleased read Windows registry value failed exception */ + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath + subkeyPath: (nullable OFString *)subkeyPath flags: (DWORD)flags status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; @@ -88,18 +87,18 @@ * exception. * * @param registryKey The registry key on which reading the value at the sub * key path failed * @param value The value for which reading failed - * @param subKeyPath The sub key path at which reading the value failed + * @param subkeyPath The subkey path at which reading the value failed * @param flags The flags with which reading the value failed * @param status The status returned by RegGetValueEx() * @return An initialized read Windows registry value failed exception */ - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath + subkeyPath: (nullable OFString *)subkeyPath flags: (DWORD)flags status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFReadWindowsRegistryValueFailedException.m ================================================================== --- src/exceptions/OFReadWindowsRegistryValueFailedException.m +++ src/exceptions/OFReadWindowsRegistryValueFailedException.m @@ -19,21 +19,21 @@ #import "OFReadWindowsRegistryValueFailedException.h" @implementation OFReadWindowsRegistryValueFailedException @synthesize registryKey = _registryKey, value = _value; -@synthesize subKeyPath = _subKeyPath, flags = _flags, status = _status; +@synthesize subkeyPath = _subkeyPath, flags = _flags, status = _status; + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath + subkeyPath: (nullable OFString *)subkeyPath flags: (DWORD)flags status: (LSTATUS)status { return [[[self alloc] initWithRegistryKey: registryKey value: value - subKeyPath: subKeyPath + subkeyPath: subkeyPath flags: flags status: status] autorelease]; } - (instancetype)init @@ -41,20 +41,20 @@ OF_INVALID_INIT_METHOD } - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey value: (nullable OFString *)value - subKeyPath: (nullable OFString *)subKeyPath + subkeyPath: (nullable OFString *)subkeyPath flags: (DWORD)flags status: (LSTATUS)status { self = [super init]; @try { _registryKey = [registryKey retain]; _value = [value copy]; - _subKeyPath = [subKeyPath copy]; + _subkeyPath = [subkeyPath copy]; _flags = flags; _status = status; } @catch (id e) { [self release]; @throw e; @@ -65,17 +65,17 @@ - (void)dealloc { [_registryKey release]; [_value release]; - [_subKeyPath release]; + [_subkeyPath release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: - @"Failed to read value %@ at sub key path %@: Status code %u!", - _value, _subKeyPath, _status]; + @"Failed to read value %@ at subkey path %@: Status code %u!", + _value, _subkeyPath, _status]; } @end