Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -31,10 +31,23 @@ #import "macros.h" #import "autorelease.h" #import "block.h" +/* + * Some versions of MinGW require to be included before + * . Do this here to make sure this is always done in the correct + * order, even if another header includes just . + */ +#ifdef __MINGW32__ +# include <_mingw.h> +# ifdef __MINGW64_VERSION_MAJOR +# include +# include +# endif +#endif + OF_ASSUME_NONNULL_BEGIN /*! @file */ /*! Index: src/OFWindowsRegistryKey.h ================================================================== --- src/OFWindowsRegistryKey.h +++ src/OFWindowsRegistryKey.h @@ -74,76 +74,68 @@ /*! * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` - * documentation + * documentation for `samDesired` * @return The subkey with the specified path, or nil if it does not exist */ - (nullable OFWindowsRegistryKey *) - openSubKeyWithPath: (OFString *)path + openSubkeyAtPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open - * @param options Please refer to the `RegOpenKeyEx()` documentation. Usually 0. + * @param options Please refer to the `RegOpenKeyEx()` documentation for + * `ulOptions`. Usually 0. * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` - * documentation + * documentation for `samDesired` * @return The subkey with the specified path, or nil if it does not exist */ - (nullable OFWindowsRegistryKey *) - openSubKeyWithPath: (OFString *)path + openSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! * @brief Creates a subkey at the specified path or opens it if it already * exists. * * @param path The path of the subkey to create * @param securityAndAccessRights Please refer to the `RegCreateKeyEx()` - * documentation + * documentation for `samDesired` * @return The subkey with the specified path */ -- (OFWindowsRegistryKey *) - createSubKeyWithPath: (OFString *)path - securityAndAccessRights: (REGSAM)securityAndAccessRights; +- (OFWindowsRegistryKey *)createSubkeyAtPath: (OFString *)path + securityAndAccessRights: (REGSAM)securityAndAccessRights; /*! * @brief Creates a subkey at the specified path or opens it if it already * exists. * * @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 + * documentation for `samDesired` * @param securityAttributes Please refer to the `RegCreateKeyEx()` - * documentation. Usually NULL. + * documentation for `lpSecurityAttributes`. Usually + * NULL. * @param disposition Whether the key was created or already existed. Please - * refer to the `RegCreateKeyEx()` documentation. + * refer to the `RegCreateKeyEx()` documentation for + * `lpdwDisposition`. * @return The subkey with the specified path */ - (OFWindowsRegistryKey *) - createSubKeyWithPath: (OFString *)path + createSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (nullable LPSECURITY_ATTRIBUTES)securityAttributes disposition: (nullable LPDWORD)disposition; -/*! - * @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 - * @return The string for the specified value - */ -- (nullable OFString *)stringForValue: (nullable OFString *)value - subkeyPath: (nullable OFString *)subkeyPath; - /*! * @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 @@ -153,8 +145,77 @@ */ - (nullable OFData *)dataForValue: (nullable OFString *)value subkeyPath: (nullable OFString *)subkeyPath flags: (DWORD)flags type: (nullable LPDWORD)type; + +/*! + * @brief Sets the data for the specified value. + * + * @param data The data to set the value to + * @param value The name of the value to set + * @param type The type for the value + */ +- (void)setData: (nullable OFData *)data + forValue: (nullable OFString *)value + type: (DWORD)type; + +/*! + * @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 + * @return The string for the specified value + */ +- (nullable OFString *)stringForValue: (nullable OFString *)value + subkeyPath: (nullable OFString *)subkeyPath; + +/*! + * @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 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 + */ +- (nullable OFString *)stringForValue: (nullable OFString *)value + subkeyPath: (nullable OFString *)subkeyPath + flags: (DWORD)flags + type: (nullable LPDWORD)type; + +/*! + * @brief Sets the string for the specified value. + * + * @param string The string to set the value to + * @param value The name of the value to set + */ +- (void)setString: (nullable OFString *)string + forValue: (nullable OFString *)value; + +/*! + * @brief Sets the string for the specified value. + * + * @param string The string to set the value to + * @param value The name of the value to set + * @param type The type for the value + */ +- (void)setString: (nullable OFString *)string + forValue: (nullable OFString *)value + type: (DWORD)type; + +/*! + * @brief Deletes the specified value. + * + * @param value The value to delete + */ +- (void)deleteValue: (nullable OFString *)value; + +/*! + * @brief Deletes the specified subkey. + * + * @param subkeyPath The path of the subkey to delete + */ +- (void)deleteSubkeyAtPath: (OFString *)subkeyPath; @end OF_ASSUME_NONNULL_END Index: src/OFWindowsRegistryKey.m ================================================================== --- src/OFWindowsRegistryKey.m +++ src/OFWindowsRegistryKey.m @@ -21,13 +21,17 @@ #import "OFData.h" #include #import "OFCreateWindowsRegistryKeyFailedException.h" +#import "OFDeleteWindowsRegistryKeyFailedException.h" +#import "OFDeleteWindowsRegistryValueFailedException.h" +#import "OFGetWindowsRegistryValueFailedException.h" #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" -#import "OFReadWindowsRegistryValueFailedException.h" +#import "OFOutOfRangeException.h" +#import "OFSetWindowsRegistryValueFailedException.h" @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey close: (bool)close; @end @@ -85,21 +89,21 @@ RegCloseKey(_hKey); [super dealloc]; } -- (OFWindowsRegistryKey *)openSubKeyWithPath: (OFString *)path - securityAndAccessRights: (REGSAM)securityAndAccessRights +- (OFWindowsRegistryKey *)openSubkeyAtPath: (OFString *)path + securityAndAccessRights: (REGSAM)securityAndAccessRights { - return [self openSubKeyWithPath: path - options: 0 - securityAndAccessRights: securityAndAccessRights]; + return [self openSubkeyAtPath: path + options: 0 + securityAndAccessRights: securityAndAccessRights]; } -- (OFWindowsRegistryKey *)openSubKeyWithPath: (OFString *)path - options: (DWORD)options - securityAndAccessRights: (REGSAM)securityAndAccessRights +- (OFWindowsRegistryKey *)openSubkeyAtPath: (OFString *)path + options: (DWORD)options + securityAndAccessRights: (REGSAM)securityAndAccessRights { void *pool = objc_autoreleasePoolPush(); LSTATUS status; HKEY subKey; @@ -123,23 +127,22 @@ return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } -- (OFWindowsRegistryKey *) - createSubKeyWithPath: (OFString *)path - securityAndAccessRights: (REGSAM)securityAndAccessRights -{ - return [self createSubKeyWithPath: path - options: 0 - securityAndAccessRights: securityAndAccessRights - securityAttributes: NULL - disposition: NULL]; +- (OFWindowsRegistryKey *)createSubkeyAtPath: (OFString *)path + securityAndAccessRights: (REGSAM)securityAndAccessRights +{ + return [self createSubkeyAtPath: path + options: 0 + securityAndAccessRights: securityAndAccessRights + securityAttributes: NULL + disposition: NULL]; } - (OFWindowsRegistryKey *) - createSubKeyWithPath: (OFString *)path + createSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (LPSECURITY_ATTRIBUTES)securityAttributes disposition: (LPDWORD)disposition { @@ -163,52 +166,10 @@ return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } -- (OFString *)stringForValue: (OFString *)value - subkeyPath: (OFString *)subkeyPath -{ - void *pool = objc_autoreleasePoolPush(); - 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 (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 { @@ -249,15 +210,143 @@ [ret increaseCountBy: length]; buffer = [ret items]; continue; default: - @throw [OFReadWindowsRegistryValueFailedException + @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self value: value subkeyPath: subkeyPath flags: flags status: status]; } } } + +- (void)setData: (OFData *)data + forValue: (OFString *)value + type: (DWORD)type +{ + size_t length = [data count] * [data itemSize]; + LSTATUS status; + + if (length > UINT32_MAX) + @throw [OFOutOfRangeException exception]; + + if ((status = RegSetValueExW(_hKey, [value UTF16String], 0, type, + [data items], (DWORD)length)) != ERROR_SUCCESS) + @throw [OFSetWindowsRegistryValueFailedException + exceptionWithRegistryKey: self + value: value + data: data + type: type + status: status]; +} + +- (OFString *)stringForValue: (OFString *)value + subkeyPath: (OFString *)subkeyPath +{ + return [self stringForValue: value + subkeyPath: subkeyPath + flags: RRF_RT_REG_SZ + type: NULL]; +} + +- (OFString *)stringForValue: (OFString *)value + subkeyPath: (OFString *)subkeyPath + flags: (DWORD)flags + type: (LPDWORD)type +{ + void *pool = objc_autoreleasePoolPush(); + OFData *data = [self dataForValue: value + subkeyPath: subkeyPath + flags: flags + type: type]; + const of_char16_t *UTF16String; + size_t length; + OFString *ret; + + 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]; +} + +- (void)setString: (OFString *)string + forValue: (OFString *)value +{ + [self setString: string + forValue: value + type: REG_SZ]; +} + +- (void)setString: (OFString *)string + forValue: (OFString *)value + type: (DWORD)type +{ + void *pool = objc_autoreleasePoolPush(); + OFData *data; + + data = [OFData dataWithItems: [string UTF16String] + itemSize: sizeof(of_char16_t) + count: [string UTF16StringLength] + 1]; + [self setData: data + forValue: value + type: type]; + + objc_autoreleasePoolPop(pool); +} + +- (void)deleteValue: (OFString *)value +{ + void *pool = objc_autoreleasePoolPush(); + LSTATUS status; + + if ((status = RegDeleteValueW(_hKey, [value UTF16String])) != + ERROR_SUCCESS) + @throw [OFDeleteWindowsRegistryValueFailedException + exceptionWithRegistryKey: self + value: value + status: status]; + + objc_autoreleasePoolPop(pool); +} + +- (void)deleteSubkeyAtPath: (OFString *)subkeyPath +{ + void *pool = objc_autoreleasePoolPush(); + LSTATUS status; + + if ((status = RegDeleteKeyW(_hKey, [subkeyPath UTF16String])) != + ERROR_SUCCESS) + @throw [OFDeleteWindowsRegistryKeyFailedException + exceptionWithRegistryKey: self + subkeyPath: subkeyPath + status: status]; + + objc_autoreleasePoolPop(pool); +} @end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -163,16 +163,21 @@ #import "OFCopyItemFailedException.h" #import "OFCreateDirectoryFailedException.h" #import "OFCreateSymbolicLinkFailedException.h" #ifdef OF_WINDOWS # import "OFCreateWindowsRegistryKeyFailedException.h" +# import "OFDeleteWindowsRegistryKeyFailedException.h" +# import "OFDeleteWindowsRegistryValueFailedException.h" #endif #import "OFEnumerationMutationException.h" #ifdef OF_HAVE_FILES # import "OFGetCurrentDirectoryPathFailedException.h" #endif #import "OFGetOptionFailedException.h" +#ifdef OF_WINDOWS +# import "OFGetWindowsRegistryValueFailedException.h" +#endif #import "OFHashAlreadyCalculatedException.h" #ifdef OF_HAVE_SOCKETS # import "OFHTTPRequestFailedException.h" #endif #import "OFInitializationFailedException.h" @@ -203,19 +208,19 @@ #endif #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFReadOrWriteFailedException.h" -#ifdef OF_WINDOWS -# import "OFReadWindowsRegistryValueFailedException.h" -#endif #import "OFRemoveItemFailedException.h" #import "OFRetrieveItemAttributesFailedException.h" #import "OFSandboxActivationFailedException.h" #import "OFSeekFailedException.h" #import "OFSetItemAttributesFailedException.h" #import "OFSetOptionFailedException.h" +#ifdef OF_WINDOWS +# import "OFSetWindowsRegistryValueFailedException.h" +#endif #import "OFStillLockedException.h" #ifdef OF_HAVE_THREADS # import "OFThreadJoinFailedException.h" # import "OFThreadStartFailedException.h" # import "OFThreadStillRunningException.h" Index: src/exceptions/Makefile ================================================================== --- src/exceptions/Makefile +++ src/exceptions/Makefile @@ -68,13 +68,16 @@ OFConditionWaitFailedException.m \ OFThreadJoinFailedException.m \ OFThreadStartFailedException.m \ OFThreadStillRunningException.m SRCS_WINDOWS = OFCreateWindowsRegistryKeyFailedException.m \ + OFDeleteWindowsRegistryKeyFailedException.m \ + OFDeleteWindowsRegistryValueFailedException.m \ + OFGetWindowsRegistryValueFailedException.m \ OFOpenWindowsRegistryKeyFailedException.m \ - OFReadWindowsRegistryValueFailedException.m + OFSetWindowsRegistryValueFailedException.m INCLUDES = ${SRCS:.m=.h} include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. -I../runtime 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 subkey at path %@: Status code %u!", - _path, _status]; + @"Failed to create subkey at path %@: %@", + _path, of_windows_status_to_string(_status)]; } @end ADDED src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h Index: src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h ================================================================== --- src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h +++ src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" +#import "OFWindowsRegistryKey.h" + +#include + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFDeleteWindowsRegistryKeyFailedException \ + * OFDeleteWindowsRegistryKeyFailedException.h \ + * ObjFW/OFDeleteWindowsRegistryKeyFailedException.h + * + * @brief An exception indicating that deleting a Windows registry key failed. + */ +@interface OFDeleteWindowsRegistryKeyFailedException: OFException +{ + OFWindowsRegistryKey *_registryKey; + OFString *_subkeyPath; + LSTATUS _status; +} + +/*! + * @brief The registry key on which deleting the subkey failed. + */ +@property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; + +/*! + * @brief The path of the subkey which could not be deleted. + */ +@property (readonly, nonatomic) OFString *subkeyPath; + +/*! + * @brief The status returned by RegDeleteKeyEx(). + */ +@property (readonly, nonatomic) LSTATUS status; + +/*! + * @brief Creates a new, autoreleased delete Windows registry key failed + * exception. + * + * @param registryKey The registry key on which deleting the subkey failed + * @param subkeyPath The path of the subkey which could not be deleted + * @param status The status returned by RegDeleteKeyEx() + * @return A new, autoreleased delete Windows registry key failed exception + */ ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + subkeyPath: (OFString *)subkeyPath + status: (LSTATUS)status; + +- (instancetype)init OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated delete Windows registry key failed + * exception. + * + * @param registryKey The registry key on which deleting the subkey failed + * @param subkeyPath The path of the subkey which could not be deleted + * @param status The status returned by RegDeleteKeyEx() + * @return An initialized delete Windows registry key failed exception + */ +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + subkeyPath: (OFString *)subkeyPath + status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END ADDED src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m Index: src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m ================================================================== --- src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m +++ src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFDeleteWindowsRegistryKeyFailedException.h" + +#import "OFData.h" + +@implementation OFDeleteWindowsRegistryKeyFailedException +@synthesize registryKey = _registryKey, subkeyPath = _subkeyPath; +@synthesize status = _status; + ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + subkeyPath: (OFString *)subkeyPath + status: (LSTATUS)status +{ + return [[[self alloc] initWithRegistryKey: registryKey + subkeyPath: subkeyPath + status: status] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + subkeyPath: (OFString *)subkeyPath + status: (LSTATUS)status +{ + self = [super init]; + + @try { + _registryKey = [registryKey retain]; + _subkeyPath = [subkeyPath copy]; + _status = status; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_registryKey release]; + [_subkeyPath release]; + + [super dealloc]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to delete subkey at path %@: %@", + _subkeyPath, of_windows_status_to_string(_status)]; +} +@end ADDED src/exceptions/OFDeleteWindowsRegistryValueFailedException.h Index: src/exceptions/OFDeleteWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFDeleteWindowsRegistryValueFailedException.h +++ src/exceptions/OFDeleteWindowsRegistryValueFailedException.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" +#import "OFWindowsRegistryKey.h" + +#include + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFDeleteWindowsRegistryValueFailedException \ + * OFDeleteWindowsRegistryValueFailedException.h \ + * ObjFW/OFDeleteWindowsRegistryValueFailedException.h + * + * @brief An exception indicating that deleting a Windows registry value failed. + */ +@interface OFDeleteWindowsRegistryValueFailedException: OFException +{ + OFWindowsRegistryKey *_registryKey; + OFString *_Nullable _value; + LSTATUS _status; +} + +/*! + * @brief The registry key on which deleting the value failed. + */ +@property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; + +/*! + * @brief The value which could not be deleted. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; + +/*! + * @brief The status returned by RegDeleteValueEx(). + */ +@property (readonly, nonatomic) LSTATUS status; + +/*! + * @brief Creates a new, autoreleased delete Windows registry value failed + * exception. + * + * @param registryKey The registry key on which deleting the value failed + * @param value The value which could not be deleted + * @param status The status returned by RegDeleteValueEx() + * @return A new, autoreleased delete Windows registry value failed exception + */ ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + status: (LSTATUS)status; + +- (instancetype)init OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated delete Windows registry value failed + * exception. + * + * @param registryKey The registry key on which deleting the value failed + * @param value The value which could not be deleted + * @param status The status returned by RegDeleteValueEx() + * @return An initialized delete Windows registry value failed exception + */ +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END ADDED src/exceptions/OFDeleteWindowsRegistryValueFailedException.m Index: src/exceptions/OFDeleteWindowsRegistryValueFailedException.m ================================================================== --- src/exceptions/OFDeleteWindowsRegistryValueFailedException.m +++ src/exceptions/OFDeleteWindowsRegistryValueFailedException.m @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFDeleteWindowsRegistryValueFailedException.h" + +#import "OFData.h" + +@implementation OFDeleteWindowsRegistryValueFailedException +@synthesize registryKey = _registryKey, value = _value, status = _status; + ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + status: (LSTATUS)status +{ + return [[[self alloc] initWithRegistryKey: registryKey + value: value + status: status] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + status: (LSTATUS)status +{ + self = [super init]; + + @try { + _registryKey = [registryKey retain]; + _value = [value copy]; + _status = status; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_registryKey release]; + [_value release]; + + [super dealloc]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to delete value %@: %@", + _value, of_windows_status_to_string(_status)]; +} +@end Index: src/exceptions/OFException.h ================================================================== --- src/exceptions/OFException.h +++ src/exceptions/OFException.h @@ -14,10 +14,14 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" + +#ifdef OF_WINDOWS +# include +#endif OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @@ -171,10 +175,13 @@ #ifdef __cplusplus extern "C" { #endif extern OFString *of_strerror(int errNo); +#ifdef OF_WINDOWS +extern OFString *of_windows_status_to_string(LSTATUS status); +#endif #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/exceptions/OFException.m ================================================================== --- src/exceptions/OFException.m +++ src/exceptions/OFException.m @@ -204,10 +204,33 @@ # endif #endif return ret; } + +#ifdef OF_WINDOWS +OFString * +of_windows_status_to_string(LSTATUS status) +{ + void *buffer; + OFString *string; + + if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, status, 0, (LPWSTR)&buffer, 0, + NULL) != 0) { + @try { + string = [OFString stringWithUTF16String: buffer]; + } @finally { + LocalFree(buffer); + } + } else + string = [OFString stringWithFormat: @"Status code %u", status]; + + return string; +} +#endif #ifdef HAVE__UNWIND_BACKTRACE static _Unwind_Reason_Code backtrace_callback(struct _Unwind_Context *ctx, void *data) { ADDED src/exceptions/OFGetWindowsRegistryValueFailedException.h Index: src/exceptions/OFGetWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFGetWindowsRegistryValueFailedException.h +++ src/exceptions/OFGetWindowsRegistryValueFailedException.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" +#import "OFWindowsRegistryKey.h" + +#include + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFGetWindowsRegistryValueFailedException \ + * OFGetWindowsRegistryValueFailedException.h \ + * ObjFW/OFGetWindowsRegistryValueFailedException.h + * + * @brief An exception indicating that getting a Windows registry value failed. + */ +@interface OFGetWindowsRegistryValueFailedException: OFException +{ + OFWindowsRegistryKey *_registryKey; + OFString *_Nullable _value, *_Nullable _subkeyPath; + DWORD _flags; + LSTATUS _status; +} + +/*! + * @brief The registry key on which getting the value at the key path failed. + */ +@property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; + +/*! + * @brief The value which could not be retrieved. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; + +/*! + * @brief The subkey path at which getting the value failed. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *subkeyPath; + +/*! + * @brief The flags with which getting the value failed. + */ +@property (readonly, nonatomic) DWORD flags; + +/*! + * @brief The status returned by RegGetValueEx(). + */ +@property (readonly, nonatomic) LSTATUS status; + +/*! + * @brief Creates a new, autoreleased get Windows registry value failed + * exception. + * + * @param registryKey The registry key on which getting the value at the sub + * key path failed + * @param value The value which could not be retrieved + * @param subkeyPath The subkey path at which getting the value failed + * @param flags The flags with which getting the value failed + * @param status The status returned by RegGetValueEx() + * @return A new, autoreleased get Windows registry value failed exception + */ ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + subkeyPath: (nullable OFString *)subkeyPath + flags: (DWORD)flags + status: (LSTATUS)status; + +- (instancetype)init OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated get Windows registry value failed + * exception. + * + * @param registryKey The registry key on which getting the value at the sub + * key path failed + * @param value The value which could not be retrieved + * @param subkeyPath The subkey path at which getting the value failed + * @param flags The flags with which getting the value failed + * @param status The status returned by RegGetValueEx() + * @return An initialized get Windows registry value failed exception + */ +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + subkeyPath: (nullable OFString *)subkeyPath + flags: (DWORD)flags + status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END ADDED src/exceptions/OFGetWindowsRegistryValueFailedException.m Index: src/exceptions/OFGetWindowsRegistryValueFailedException.m ================================================================== --- src/exceptions/OFGetWindowsRegistryValueFailedException.m +++ src/exceptions/OFGetWindowsRegistryValueFailedException.m @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFGetWindowsRegistryValueFailedException.h" + +@implementation OFGetWindowsRegistryValueFailedException +@synthesize registryKey = _registryKey, value = _value; +@synthesize subkeyPath = _subkeyPath, flags = _flags, status = _status; + ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + subkeyPath: (OFString *)subkeyPath + flags: (DWORD)flags + status: (LSTATUS)status +{ + return [[[self alloc] initWithRegistryKey: registryKey + value: value + subkeyPath: subkeyPath + flags: flags + status: status] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + subkeyPath: (OFString *)subkeyPath + flags: (DWORD)flags + status: (LSTATUS)status +{ + self = [super init]; + + @try { + _registryKey = [registryKey retain]; + _value = [value copy]; + _subkeyPath = [subkeyPath copy]; + _flags = flags; + _status = status; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_registryKey release]; + [_value release]; + [_subkeyPath release]; + + [super dealloc]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to get value %@ at subkey path %@: %@", + _value, _subkeyPath, of_windows_status_to_string(_status)]; +} +@end 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 subkey at path %@: Status code %u!", - _path, _status]; + @"Failed to open subkey at path %@: %@", + _path, of_windows_status_to_string(_status)]; } @end DELETED src/exceptions/OFReadWindowsRegistryValueFailedException.h Index: src/exceptions/OFReadWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFReadWindowsRegistryValueFailedException.h +++ src/exceptions/OFReadWindowsRegistryValueFailedException.h @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018, 2019 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#import "OFException.h" -#import "OFWindowsRegistryKey.h" - -#include - -OF_ASSUME_NONNULL_BEGIN - -/*! - * @class OFReadWindowsRegistryValueFailedException \ - * OFReadWindowsRegistryValueFailedException.h \ - * ObjFW/OFReadWindowsRegistryValueFailedException.h - * - * @brief An exception indicating that reading a Windows registry value failed. - */ -@interface OFReadWindowsRegistryValueFailedException: OFException -{ - OFWindowsRegistryKey *_registryKey; - OFString *_Nullable _value, *_Nullable _subkeyPath; - DWORD _flags; - LSTATUS _status; -} - -/*! - * @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 subkey path at which reading the value failed. - */ -@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *subkeyPath; - -/*! - * @brief The flags with which reading the value failed. - */ -@property (readonly, nonatomic) DWORD flags; - -/*! - * @brief The status returned by RegGetValueEx(). - */ -@property (readonly, nonatomic) LSTATUS status; - -/*! - * @brief Creates a new, autoreleased read Windows registry value failed - * 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 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 - flags: (DWORD)flags - status: (LSTATUS)status; - -- (instancetype)init OF_UNAVAILABLE; - -/*! - * @brief Initializes an already allocated read Windows registry value failed - * 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 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 - flags: (DWORD)flags - status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; -@end - -OF_ASSUME_NONNULL_END DELETED src/exceptions/OFReadWindowsRegistryValueFailedException.m Index: src/exceptions/OFReadWindowsRegistryValueFailedException.m ================================================================== --- src/exceptions/OFReadWindowsRegistryValueFailedException.m +++ src/exceptions/OFReadWindowsRegistryValueFailedException.m @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018, 2019 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "OFReadWindowsRegistryValueFailedException.h" - -@implementation OFReadWindowsRegistryValueFailedException -@synthesize registryKey = _registryKey, value = _value; -@synthesize subkeyPath = _subkeyPath, flags = _flags, status = _status; - -+ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey - value: (nullable OFString *)value - subkeyPath: (nullable OFString *)subkeyPath - flags: (DWORD)flags - status: (LSTATUS)status -{ - return [[[self alloc] initWithRegistryKey: registryKey - value: value - subkeyPath: subkeyPath - flags: flags - status: status] autorelease]; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey - value: (nullable OFString *)value - subkeyPath: (nullable OFString *)subkeyPath - flags: (DWORD)flags - status: (LSTATUS)status -{ - self = [super init]; - - @try { - _registryKey = [registryKey retain]; - _value = [value copy]; - _subkeyPath = [subkeyPath copy]; - _flags = flags; - _status = status; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - [_registryKey release]; - [_value release]; - [_subkeyPath release]; - - [super dealloc]; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: - @"Failed to read value %@ at subkey path %@: Status code %u!", - _value, _subkeyPath, _status]; -} -@end ADDED src/exceptions/OFSetWindowsRegistryValueFailedException.h Index: src/exceptions/OFSetWindowsRegistryValueFailedException.h ================================================================== --- src/exceptions/OFSetWindowsRegistryValueFailedException.h +++ src/exceptions/OFSetWindowsRegistryValueFailedException.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" +#import "OFWindowsRegistryKey.h" + +#include + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFSetWindowsRegistryValueFailedException \ + * OFSetWindowsRegistryValueFailedException.h \ + * ObjFW/OFSetWindowsRegistryValueFailedException.h + * + * @brief An exception indicating that setting a Windows registry value failed. + */ +@interface OFSetWindowsRegistryValueFailedException: OFException +{ + OFWindowsRegistryKey *_registryKey; + OFString *_Nullable _value; + OFData *_Nullable _data; + DWORD _type; + LSTATUS _status; +} + +/*! + * @brief The registry key on which setting the value failed. + */ +@property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; + +/*! + * @brief The value which could not be set. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *value; + +/*! + * @brief The data to which the value could not be set. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFData *data; + +/*! + * @brief The type for the value that could not be set. + */ +@property (readonly, nonatomic) DWORD type; + +/*! + * @brief The status returned by RegSetValueEx(). + */ +@property (readonly, nonatomic) LSTATUS status; + +/*! + * @brief Creates a new, autoreleased set Windows registry value failed + * exception. + * + * @param registryKey The registry key on which setting the value failed + * @param value The value which could not be set + * @param data The data to which the value could not be set + * @param type The type for the value that could not be set + * @param status The status returned by RegSetValueEx() + * @return A new, autoreleased set Windows registry value failed exception + */ ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + data: (nullable OFData *)data + type: (DWORD)type + status: (LSTATUS)status; + +- (instancetype)init OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated set Windows registry value failed + * exception. + * + * @param registryKey The registry key on which setting the value failed + * @param value The value which could not be set + * @param data The data to which the value could not be set + * @param type The type for the value that could not be set + * @param status The status returned by RegSetValueEx() + * @return An initialized set Windows registry value failed exception + */ +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (nullable OFString *)value + data: (nullable OFData *)data + type: (DWORD)type + status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END ADDED src/exceptions/OFSetWindowsRegistryValueFailedException.m Index: src/exceptions/OFSetWindowsRegistryValueFailedException.m ================================================================== --- src/exceptions/OFSetWindowsRegistryValueFailedException.m +++ src/exceptions/OFSetWindowsRegistryValueFailedException.m @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFSetWindowsRegistryValueFailedException.h" + +#import "OFData.h" + +@implementation OFSetWindowsRegistryValueFailedException +@synthesize registryKey = _registryKey, value = _value, data = _data; +@synthesize type = _type, status = _status; + ++ (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + data: (OFData *)data + type: (DWORD)type + status: (LSTATUS)status +{ + return [[[self alloc] initWithRegistryKey: registryKey + value: value + data: data + type: type + status: status] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey + value: (OFString *)value + data: (OFData *)data + type: (DWORD)type + status: (LSTATUS)status +{ + self = [super init]; + + @try { + _registryKey = [registryKey retain]; + _value = [value copy]; + _data = [data copy]; + _type = type; + _status = status; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_registryKey release]; + [_value release]; + [_data release]; + + [super dealloc]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Failed to set value %@ of type %u: %@", + _value, _type, of_windows_status_to_string(_status)]; +} +@end Index: src/socket.h ================================================================== --- src/socket.h +++ src/socket.h @@ -36,16 +36,10 @@ #endif #include "platform.h" #ifdef OF_WINDOWS -# ifdef __MINGW32__ -# include <_mingw.h> -# ifdef __MINGW64_VERSION_MAJOR -# include -# endif -# endif # include # include #endif /*! @file */ Index: src/threading.h ================================================================== --- src/threading.h +++ src/threading.h @@ -35,18 +35,10 @@ typedef pthread_mutex_t of_mutex_t; typedef pthread_cond_t of_condition_t; typedef pthread_once_t of_once_t; # define OF_ONCE_INIT PTHREAD_ONCE_INIT #elif defined(OF_WINDOWS) -/* - * winsock2.h needs to be included before windows.h. Not including it here - * would make it impossible to use sockets after threading.h has been - * imported. - */ -# ifdef OF_HAVE_SOCKETS -# include -# endif # include typedef HANDLE of_thread_t; typedef DWORD of_tlskey_t; typedef CRITICAL_SECTION of_mutex_t; typedef struct { Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -39,11 +39,12 @@ ScryptTests.m \ TestsAppDelegate.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ - ${USE_SRCS_THREADS} + ${USE_SRCS_THREADS} \ + ${USE_SRCS_WINDOWS} SRCS_FILES = OFHMACTests.m \ OFINIFileTests.m \ OFMD5HashTests.m \ OFRIPEMD160HashTests.m \ OFSerializationTests.m \ @@ -60,10 +61,11 @@ OFKernelEventObserverTests.m \ OFTCPSocketTests.m \ OFUDPSocketTests.m \ SocketTests.m SRCS_THREADS = OFThreadTests.m +SRCS_WINDOWS = OFWindowsRegistryKeyTests.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test include ../buildsys.mk Index: tests/OFArrayTests.m ================================================================== --- tests/OFArrayTests.m +++ tests/OFArrayTests.m @@ -186,11 +186,11 @@ [[a[1] objectAtIndex: 1] isEqual: c_ary[1]] && [[a[1] objectAtIndex: 2] isEqual: c_ary[2]]) TEST(@"-[containsObject:]", [a[0] containsObject: c_ary[1]] && - ![a[0] containsObject: @"nonexistant"]) + ![a[0] containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [a[0] containsObjectIdenticalTo: c_ary[1]] && ![a[0] containsObjectIdenticalTo: [OFString stringWithString: c_ary[1]]]) Index: tests/OFDictionaryTests.m ================================================================== --- tests/OFDictionaryTests.m +++ tests/OFDictionaryTests.m @@ -188,11 +188,11 @@ [[dictionaryClass dictionary] setValue: @"x" forKey: @"x"]) TEST(@"-[containsObject:]", [mutDict containsObject: values[0]] && - ![mutDict containsObject: @"nonexistant"]) + ![mutDict containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [mutDict containsObjectIdenticalTo: values[0]] && ![mutDict containsObjectIdenticalTo: [OFString stringWithString: values[0]]]) Index: tests/OFListTests.m ================================================================== --- tests/OFListTests.m +++ tests/OFListTests.m @@ -79,11 +79,11 @@ TEST(@"-[count]", [list count] == 3) TEST(@"-[containsObject:]", [list containsObject: strings[1]] && - ![list containsObject: @"nonexistant"]) + ![list containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [list containsObjectIdenticalTo: strings[1]] && ![list containsObjectIdenticalTo: [OFString stringWithString: strings[1]]]) ADDED tests/OFWindowsRegistryKeyTests.m Index: tests/OFWindowsRegistryKeyTests.m ================================================================== --- tests/OFWindowsRegistryKeyTests.m +++ tests/OFWindowsRegistryKeyTests.m @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFWindowsRegistryKey.h" +#import "OFData.h" +#import "OFAutoreleasePool.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFWindowsRegistryKey"; + +@implementation TestsAppDelegate (OFWindowsRegistryKeyTests) +- (void)windowsRegistryKeyTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFData *data = [OFData dataWithItems: "abcdef" + count: 6]; + OFWindowsRegistryKey *softwareKey, *ObjFWKey; + DWORD type; + OFString *string; + + TEST(@"+[OFWindowsRegistryKey classesRootKey]", + [OFWindowsRegistryKey classesRootKey]) + + TEST(@"+[OFWindowsRegistryKey currentConfigKey]", + [OFWindowsRegistryKey currentConfigKey]) + + TEST(@"+[OFWindowsRegistryKey currentUserKey]", + [OFWindowsRegistryKey currentUserKey]) + + TEST(@"+[OFWindowsRegistryKey localMachineKey]", + [OFWindowsRegistryKey localMachineKey]) + + TEST(@"+[OFWindowsRegistryKey usersKey]", + [OFWindowsRegistryKey usersKey]) + + TEST(@"-[openSubkeyAtPath:securityAndAccessRights:]", + (softwareKey = [[OFWindowsRegistryKey currentUserKey] + openSubkeyAtPath: @"Software" + securityAndAccessRights: KEY_ALL_ACCESS]) && + [[OFWindowsRegistryKey currentUserKey] + openSubkeyAtPath: @"nonexistent" + securityAndAccessRights: KEY_ALL_ACCESS] == nil) + + TEST(@"-[createSubkeyAtPath:securityAndAccessRights:]", + (ObjFWKey = [softwareKey createSubkeyAtPath: @"ObjFW" + securityAndAccessRights: KEY_ALL_ACCESS])) + + TEST(@"-[setData:forValue:type:]", + R([ObjFWKey setData: data + forValue: @"data" + type: REG_BINARY])) + + TEST(@"-[dataForValue:subkeyPath:flags:type:]", + [[softwareKey dataForValue: @"data" + subkeyPath: @"ObjFW" + flags: RRF_RT_REG_BINARY + type: &type] isEqual: data] && + type == REG_BINARY) + + TEST(@"-[setString:forValue:type:]", + R([ObjFWKey setString: @"foobar" + forValue: @"string"]) && + R([ObjFWKey setString: @"%PATH%;foo" + forValue: @"expand" + type: REG_EXPAND_SZ])) + + TEST(@"-[stringForValue:subkeyPath:]", + [[softwareKey stringForValue: @"string" + subkeyPath: @"ObjFW"] isEqual: @"foobar"] && + [[softwareKey stringForValue: @"expand" + subkeyPath: @"ObjFW" + flags: RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND + type: &type] isEqual: @"%PATH%;foo"] && + type == REG_EXPAND_SZ && + (string = [ObjFWKey stringForValue: @"expand" + subkeyPath: nil]) && + ![string isEqual: @"%PATH%;foo"] && + [string hasSuffix: @";foo"]) + + TEST(@"-[deleteValue:]", R([ObjFWKey deleteValue: @"data"])) + + TEST(@"-[deleteSubkeyAtPath:]", + R([softwareKey deleteSubkeyAtPath: @"ObjFW"])) + + [pool drain]; +} +@end Index: tests/RuntimeTests.m ================================================================== --- tests/RuntimeTests.m +++ tests/RuntimeTests.m @@ -71,11 +71,11 @@ { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; RuntimeTest *rt = [[[RuntimeTest alloc] init] autorelease]; OFString *t, *foo; - EXPECT_EXCEPTION(@"Calling a non-existant method via super", + EXPECT_EXCEPTION(@"Calling a non-existent method via super", OFNotImplementedException, [rt superTest]) TEST(@"Calling a method via a super with self == nil", [rt nilSuperTest] == nil) Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -256,10 +256,14 @@ @end @interface TestsAppDelegate (OFValueTests) - (void)valueTests; @end + +@interface TestsAppDelegate (OFWindowsRegistryKeyTests) +- (void)windowsRegistryKeyTests; +@end @interface TestsAppDelegate (OFXMLElementBuilderTests) - (void)XMLElementBuilderTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -440,10 +440,13 @@ [self propertyListTests]; [self ASN1DERValueTests]; #if defined(OF_HAVE_PLUGINS) [self pluginTests]; #endif +#ifdef OF_WINDOWS + [self windowsRegistryKeyTests]; +#endif #ifdef OF_HAVE_SOCKETS [self DNSResolverTests]; #endif [self systemInfoTests];