diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..6098e1f5 --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +# We'll use defaults from the LLVM style, but with 4 columns indentation. +BasedOnStyle: LLVM +IndentWidth: 2 +--- +Language: Cpp +DeriveLineEnding: false +UseCRLF: true +DerivePointerAlignment: false +PointerAlignment: Left +AlignConsecutiveAssignments: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AlwaysBreakTemplateDeclarations: Yes +AccessModifierOffset: -2 +AlignTrailingComments: true +SpacesBeforeTrailingComments: 2 +NamespaceIndentation: Inner +MaxEmptyLinesToKeep: 1 +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +ColumnLimit: 88 +ForEachMacros: ['Q_FOREACH', 'foreach'] diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..712711a7 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +218607a6ce4d41112bd3995ba319255aec3c5c2e diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..f8697127 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.cpp text eol=crlf +*.h text eol=crlf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..23e14810 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,15 @@ +name: Build UIBase +on: + push: + branches: master + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + runs-on: windows-2022 + steps: + - name: Build UI Base + uses: ModOrganizer2/build-with-mob-action@master + with: + mo2-third-parties: fmt gtest spdlog boost + mo2-dependencies: cmake_common diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 00000000..db7c755e --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,15 @@ +name: Lint UIBase +on: + push: + pull_request: + types: [opened, synchronize, reopened] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run clang-format + uses: jidicula/clang-format-action@v4.11.0 + with: + clang-format-version: "15" + check-path: "." diff --git a/src/delayedfilewriter.cpp b/src/delayedfilewriter.cpp index 6c2a5f75..037ef1df 100644 --- a/src/delayedfilewriter.cpp +++ b/src/delayedfilewriter.cpp @@ -1,58 +1,49 @@ -#include "delayedfilewriter.h" -#include "log.h" - - -using namespace MOBase; - - -DelayedFileWriterBase::DelayedFileWriterBase(int delay) - : m_TimerDelay(delay) - , m_Timer() -{ - QObject::connect(&m_Timer, &QTimer::timeout, this, &DelayedFileWriter::timerExpired); - m_Timer.setSingleShot(true); -} - -DelayedFileWriterBase::~DelayedFileWriterBase() -{ - if (m_Timer.isActive()) { - log::error("delayed file save timer active at shutdown"); - } -} - -void DelayedFileWriterBase::write() -{ - m_Timer.start(m_TimerDelay); -} - -void DelayedFileWriterBase::cancel() -{ - m_Timer.stop(); -} - -void DelayedFileWriterBase::writeImmediately(bool ifOnTimer) -{ - if (!ifOnTimer || m_Timer.isActive()) { - m_Timer.stop(); - doWrite(); - } -} - -void DelayedFileWriterBase::timerExpired() -{ - doWrite(); -} - - - -DelayedFileWriter::DelayedFileWriter(DelayedFileWriter::WriterFunc func - , int delay) - : DelayedFileWriterBase(delay) - , m_Func(func) -{ -} - -void DelayedFileWriter::doWrite() -{ - m_Func(); -} +#include "delayedfilewriter.h" +#include "log.h" + +using namespace MOBase; + +DelayedFileWriterBase::DelayedFileWriterBase(int delay) : m_TimerDelay(delay), m_Timer() +{ + QObject::connect(&m_Timer, &QTimer::timeout, this, &DelayedFileWriter::timerExpired); + m_Timer.setSingleShot(true); +} + +DelayedFileWriterBase::~DelayedFileWriterBase() +{ + if (m_Timer.isActive()) { + log::error("delayed file save timer active at shutdown"); + } +} + +void DelayedFileWriterBase::write() +{ + m_Timer.start(m_TimerDelay); +} + +void DelayedFileWriterBase::cancel() +{ + m_Timer.stop(); +} + +void DelayedFileWriterBase::writeImmediately(bool ifOnTimer) +{ + if (!ifOnTimer || m_Timer.isActive()) { + m_Timer.stop(); + doWrite(); + } +} + +void DelayedFileWriterBase::timerExpired() +{ + doWrite(); +} + +DelayedFileWriter::DelayedFileWriter(DelayedFileWriter::WriterFunc func, int delay) + : DelayedFileWriterBase(delay), m_Func(func) +{} + +void DelayedFileWriter::doWrite() +{ + m_Func(); +} diff --git a/src/delayedfilewriter.h b/src/delayedfilewriter.h index f68f3494..ecdfd8d9 100644 --- a/src/delayedfilewriter.h +++ b/src/delayedfilewriter.h @@ -1,71 +1,74 @@ -#ifndef DELAYEDFILEWRITER_H -#define DELAYEDFILEWRITER_H - - -#include "dllimport.h" -#include -#include -#include - - -namespace MOBase { - -/** - * The purpose of this class is to aggregate changes to a file before writing it out - */ -class QDLLEXPORT DelayedFileWriterBase : public QObject { - - Q_OBJECT - -public: - /** - * @brief constructor - * @param fileName - * @param delay delay (in milliseconds) before we call the actual write function - */ - DelayedFileWriterBase(int delay = 200); - ~DelayedFileWriterBase(); - -public slots: - /** - * @brief write with delay - */ - void write(); - - /** - * @brief cancel a scheduled write (does nothing if no write is scheduled) - */ - void cancel(); - - /** - * @brief write immediately without waiting for the timer to expire - * @param ifOnTimer only write if the timer is running - */ - void writeImmediately(bool ifOnTimer); - -private slots: - void timerExpired(); - -private: - virtual void doWrite() = 0; - -private: - int m_TimerDelay; - QTimer m_Timer; -}; - - -class QDLLEXPORT DelayedFileWriter : public DelayedFileWriterBase { -public: - typedef std::function WriterFunc; -public: - DelayedFileWriter(WriterFunc func, int delay = 200); -private: - void doWrite(); -private: - WriterFunc m_Func; -}; - -} - -#endif // DELAYEDFILEWRITER_H +#ifndef DELAYEDFILEWRITER_H +#define DELAYEDFILEWRITER_H + +#include "dllimport.h" +#include +#include +#include + +namespace MOBase +{ + +/** + * The purpose of this class is to aggregate changes to a file before writing it out + */ +class QDLLEXPORT DelayedFileWriterBase : public QObject +{ + + Q_OBJECT + +public: + /** + * @brief constructor + * @param fileName + * @param delay delay (in milliseconds) before we call the actual write function + */ + DelayedFileWriterBase(int delay = 200); + ~DelayedFileWriterBase(); + +public slots: + /** + * @brief write with delay + */ + void write(); + + /** + * @brief cancel a scheduled write (does nothing if no write is scheduled) + */ + void cancel(); + + /** + * @brief write immediately without waiting for the timer to expire + * @param ifOnTimer only write if the timer is running + */ + void writeImmediately(bool ifOnTimer); + +private slots: + void timerExpired(); + +private: + virtual void doWrite() = 0; + +private: + int m_TimerDelay; + QTimer m_Timer; +}; + +class QDLLEXPORT DelayedFileWriter : public DelayedFileWriterBase +{ +public: + typedef std::function WriterFunc; + +public: + DelayedFileWriter(WriterFunc func, int delay = 200); + +private: + void doWrite(); + +private: + WriterFunc m_Func; +}; + +} // namespace MOBase + +#endif // DELAYEDFILEWRITER_H diff --git a/src/diagnosisreport.cpp b/src/diagnosisreport.cpp index 928533ee..20a96c29 100644 --- a/src/diagnosisreport.cpp +++ b/src/diagnosisreport.cpp @@ -1,24 +1,25 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "diagnosisreport.h" - -namespace MOBase { -} // namespace MOBase +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "diagnosisreport.h" + +namespace MOBase +{ +} // namespace MOBase diff --git a/src/diagnosisreport.h b/src/diagnosisreport.h index a1a39290..4b541ffa 100644 --- a/src/diagnosisreport.h +++ b/src/diagnosisreport.h @@ -1,50 +1,51 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef DIAGNOSISREPORT_H -#define DIAGNOSISREPORT_H - - -#include - -namespace MOBase { - - -/** - * @brief report for a single problem reported by a plugin - */ -struct ProblemReport -{ - QString key; // a plugin-defined unique key for the issue. This is used to refer to the problem - enum { - SEVERITY_REPORT, // the issue should be reported but nothing more - SEVERITY_BREAKPLUGIN, // the issue breaks the plugin (the plugin has to disable itself) - SEVERITY_BREAKGAME // the issue will (likely) break the game. The user will be - // warned about this every time he tries to start - } severity; - bool guidedFix; // if true, the plugin provides a guide to fixing the issue - QString shortDescription; // short description text for the overview - QString longDescription; // -}; - - -} // namespace MOBase - -#endif // DIAGNOSISREPORT_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef DIAGNOSISREPORT_H +#define DIAGNOSISREPORT_H + +#include + +namespace MOBase +{ + +/** + * @brief report for a single problem reported by a plugin + */ +struct ProblemReport +{ + QString key; // a plugin-defined unique key for the issue. This is used to refer to + // the problem + enum + { + SEVERITY_REPORT, // the issue should be reported but nothing more + SEVERITY_BREAKPLUGIN, // the issue breaks the plugin (the plugin has to disable + // itself) + SEVERITY_BREAKGAME // the issue will (likely) break the game. The user will be + // warned about this every time he tries to start + } severity; + bool guidedFix; // if true, the plugin provides a guide to fixing the issue + QString shortDescription; // short description text for the overview + QString longDescription; // +}; + +} // namespace MOBase + +#endif // DIAGNOSISREPORT_H diff --git a/src/dllimport.h b/src/dllimport.h index 2987b6fb..0d0f5677 100644 --- a/src/dllimport.h +++ b/src/dllimport.h @@ -1,39 +1,38 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef DLLIMPORT_H -#define DLLIMPORT_H - - -namespace MOBase { - -#if defined(UIBASE_EXPORT) - #define QDLLEXPORT __declspec(dllexport) -#elif defined(_NODLL) - #define QDLLEXPORT -#else - #undef DLLEXPORT - #define QDLLEXPORT __declspec(dllimport) -#endif - -} // namespace MOBase - -#endif // DLLIMPORT_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef DLLIMPORT_H +#define DLLIMPORT_H + +namespace MOBase +{ + +#if defined(UIBASE_EXPORT) +#define QDLLEXPORT __declspec(dllexport) +#elif defined(_NODLL) +#define QDLLEXPORT +#else +#undef DLLEXPORT +#define QDLLEXPORT __declspec(dllimport) +#endif + +} // namespace MOBase + +#endif // DLLIMPORT_H diff --git a/src/errorcodes.cpp b/src/errorcodes.cpp index e12b8830..3fde3bdf 100644 --- a/src/errorcodes.cpp +++ b/src/errorcodes.cpp @@ -6,2351 +6,2349 @@ namespace MOBase struct CodeName { - DWORD code = 0; + DWORD code = 0; const wchar_t* name = nullptr; }; static const CodeName g_codes[] = { - {1, L"ERROR_INVALID_FUNCTION"}, - {2, L"ERROR_FILE_NOT_FOUND"}, - {3, L"ERROR_PATH_NOT_FOUND"}, - {4, L"ERROR_TOO_MANY_OPEN_FILES"}, - {5, L"ERROR_ACCESS_DENIED"}, - {6, L"ERROR_INVALID_HANDLE"}, - {7, L"ERROR_ARENA_TRASHED"}, - {8, L"ERROR_NOT_ENOUGH_MEMORY"}, - {9, L"ERROR_INVALID_BLOCK"}, - {10, L"ERROR_BAD_ENVIRONMENT"}, - {11, L"ERROR_BAD_FORMAT"}, - {12, L"ERROR_INVALID_ACCESS"}, - {13, L"ERROR_INVALID_DATA"}, - {14, L"ERROR_OUTOFMEMORY"}, - {15, L"ERROR_INVALID_DRIVE"}, - {16, L"ERROR_CURRENT_DIRECTORY"}, - {17, L"ERROR_NOT_SAME_DEVICE"}, - {18, L"ERROR_NO_MORE_FILES"}, - {19, L"ERROR_WRITE_PROTECT"}, - {20, L"ERROR_BAD_UNIT"}, - {21, L"ERROR_NOT_READY"}, - {22, L"ERROR_BAD_COMMAND"}, - {23, L"ERROR_CRC"}, - {24, L"ERROR_BAD_LENGTH"}, - {25, L"ERROR_SEEK"}, - {26, L"ERROR_NOT_DOS_DISK"}, - {27, L"ERROR_SECTOR_NOT_FOUND"}, - {28, L"ERROR_OUT_OF_PAPER"}, - {29, L"ERROR_WRITE_FAULT"}, - {30, L"ERROR_READ_FAULT"}, - {31, L"ERROR_GEN_FAILURE"}, - {32, L"ERROR_SHARING_VIOLATION"}, - {33, L"ERROR_LOCK_VIOLATION"}, - {34, L"ERROR_WRONG_DISK"}, - {36, L"ERROR_SHARING_BUFFER_EXCEEDED"}, - {38, L"ERROR_HANDLE_EOF"}, - {39, L"ERROR_HANDLE_DISK_FULL"}, - {50, L"ERROR_NOT_SUPPORTED"}, - {51, L"ERROR_REM_NOT_LIST"}, - {52, L"ERROR_DUP_NAME"}, - {53, L"ERROR_BAD_NETPATH"}, - {54, L"ERROR_NETWORK_BUSY"}, - {55, L"ERROR_DEV_NOT_EXIST"}, - {56, L"ERROR_TOO_MANY_CMDS"}, - {57, L"ERROR_ADAP_HDW_ERR"}, - {58, L"ERROR_BAD_NET_RESP"}, - {59, L"ERROR_UNEXP_NET_ERR"}, - {60, L"ERROR_BAD_REM_ADAP"}, - {61, L"ERROR_PRINTQ_FULL"}, - {62, L"ERROR_NO_SPOOL_SPACE"}, - {63, L"ERROR_PRINT_CANCELLED"}, - {64, L"ERROR_NETNAME_DELETED"}, - {65, L"ERROR_NETWORK_ACCESS_DENIED"}, - {66, L"ERROR_BAD_DEV_TYPE"}, - {67, L"ERROR_BAD_NET_NAME"}, - {68, L"ERROR_TOO_MANY_NAMES"}, - {69, L"ERROR_TOO_MANY_SESS"}, - {70, L"ERROR_SHARING_PAUSED"}, - {71, L"ERROR_REQ_NOT_ACCEP"}, - {72, L"ERROR_REDIR_PAUSED"}, - {80, L"ERROR_FILE_EXISTS"}, - {82, L"ERROR_CANNOT_MAKE"}, - {83, L"ERROR_FAIL_I24"}, - {84, L"ERROR_OUT_OF_STRUCTURES"}, - {85, L"ERROR_ALREADY_ASSIGNED"}, - {86, L"ERROR_INVALID_PASSWORD"}, - {87, L"ERROR_INVALID_PARAMETER"}, - {88, L"ERROR_NET_WRITE_FAULT"}, - {89, L"ERROR_NO_PROC_SLOTS"}, - {100, L"ERROR_TOO_MANY_SEMAPHORES"}, - {101, L"ERROR_EXCL_SEM_ALREADY_OWNED"}, - {102, L"ERROR_SEM_IS_SET"}, - {103, L"ERROR_TOO_MANY_SEM_REQUESTS"}, - {104, L"ERROR_INVALID_AT_INTERRUPT_TIME"}, - {105, L"ERROR_SEM_OWNER_DIED"}, - {106, L"ERROR_SEM_USER_LIMIT"}, - {107, L"ERROR_DISK_CHANGE"}, - {108, L"ERROR_DRIVE_LOCKED"}, - {109, L"ERROR_BROKEN_PIPE"}, - {110, L"ERROR_OPEN_FAILED"}, - {111, L"ERROR_BUFFER_OVERFLOW"}, - {112, L"ERROR_DISK_FULL"}, - {113, L"ERROR_NO_MORE_SEARCH_HANDLES"}, - {114, L"ERROR_INVALID_TARGET_HANDLE"}, - {117, L"ERROR_INVALID_CATEGORY"}, - {118, L"ERROR_INVALID_VERIFY_SWITCH"}, - {119, L"ERROR_BAD_DRIVER_LEVEL"}, - {120, L"ERROR_CALL_NOT_IMPLEMENTED"}, - {121, L"ERROR_SEM_TIMEOUT"}, - {122, L"ERROR_INSUFFICIENT_BUFFER"}, - {123, L"ERROR_INVALID_NAME"}, - {124, L"ERROR_INVALID_LEVEL"}, - {125, L"ERROR_NO_VOLUME_LABEL"}, - {126, L"ERROR_MOD_NOT_FOUND"}, - {127, L"ERROR_PROC_NOT_FOUND"}, - {128, L"ERROR_WAIT_NO_CHILDREN"}, - {129, L"ERROR_CHILD_NOT_COMPLETE"}, - {130, L"ERROR_DIRECT_ACCESS_HANDLE"}, - {131, L"ERROR_NEGATIVE_SEEK"}, - {132, L"ERROR_SEEK_ON_DEVICE"}, - {133, L"ERROR_IS_JOIN_TARGET"}, - {134, L"ERROR_IS_JOINED"}, - {135, L"ERROR_IS_SUBSTED"}, - {136, L"ERROR_NOT_JOINED"}, - {137, L"ERROR_NOT_SUBSTED"}, - {138, L"ERROR_JOIN_TO_JOIN"}, - {139, L"ERROR_SUBST_TO_SUBST"}, - {140, L"ERROR_JOIN_TO_SUBST"}, - {141, L"ERROR_SUBST_TO_JOIN"}, - {142, L"ERROR_BUSY_DRIVE"}, - {143, L"ERROR_SAME_DRIVE"}, - {144, L"ERROR_DIR_NOT_ROOT"}, - {145, L"ERROR_DIR_NOT_EMPTY"}, - {146, L"ERROR_IS_SUBST_PATH"}, - {147, L"ERROR_IS_JOIN_PATH"}, - {148, L"ERROR_PATH_BUSY"}, - {149, L"ERROR_IS_SUBST_TARGET"}, - {150, L"ERROR_SYSTEM_TRACE"}, - {151, L"ERROR_INVALID_EVENT_COUNT"}, - {152, L"ERROR_TOO_MANY_MUXWAITERS"}, - {153, L"ERROR_INVALID_LIST_FORMAT"}, - {154, L"ERROR_LABEL_TOO_LONG"}, - {155, L"ERROR_TOO_MANY_TCBS"}, - {156, L"ERROR_SIGNAL_REFUSED"}, - {157, L"ERROR_DISCARDED"}, - {158, L"ERROR_NOT_LOCKED"}, - {159, L"ERROR_BAD_THREADID_ADDR"}, - {160, L"ERROR_BAD_ARGUMENTS"}, - {161, L"ERROR_BAD_PATHNAME"}, - {162, L"ERROR_SIGNAL_PENDING"}, - {164, L"ERROR_MAX_THRDS_REACHED"}, - {167, L"ERROR_LOCK_FAILED"}, - {170, L"ERROR_BUSY"}, - {171, L"ERROR_DEVICE_SUPPORT_IN_PROGRESS"}, - {173, L"ERROR_CANCEL_VIOLATION"}, - {174, L"ERROR_ATOMIC_LOCKS_NOT_SUPPORTED"}, - {180, L"ERROR_INVALID_SEGMENT_NUMBER"}, - {182, L"ERROR_INVALID_ORDINAL"}, - {183, L"ERROR_ALREADY_EXISTS"}, - {186, L"ERROR_INVALID_FLAG_NUMBER"}, - {187, L"ERROR_SEM_NOT_FOUND"}, - {188, L"ERROR_INVALID_STARTING_CODESEG"}, - {189, L"ERROR_INVALID_STACKSEG"}, - {190, L"ERROR_INVALID_MODULETYPE"}, - {191, L"ERROR_INVALID_EXE_SIGNATURE"}, - {192, L"ERROR_EXE_MARKED_INVALID"}, - {193, L"ERROR_BAD_EXE_FORMAT"}, - {194, L"ERROR_ITERATED_DATA_EXCEEDS_64k"}, - {195, L"ERROR_INVALID_MINALLOCSIZE"}, - {196, L"ERROR_DYNLINK_FROM_INVALID_RING"}, - {197, L"ERROR_IOPL_NOT_ENABLED"}, - {198, L"ERROR_INVALID_SEGDPL"}, - {199, L"ERROR_AUTODATASEG_EXCEEDS_64k"}, - {200, L"ERROR_RING2SEG_MUST_BE_MOVABLE"}, - {201, L"ERROR_RELOC_CHAIN_XEEDS_SEGLIM"}, - {202, L"ERROR_INFLOOP_IN_RELOC_CHAIN"}, - {203, L"ERROR_ENVVAR_NOT_FOUND"}, - {205, L"ERROR_NO_SIGNAL_SENT"}, - {206, L"ERROR_FILENAME_EXCED_RANGE"}, - {207, L"ERROR_RING2_STACK_IN_USE"}, - {208, L"ERROR_META_EXPANSION_TOO_LONG"}, - {209, L"ERROR_INVALID_SIGNAL_NUMBER"}, - {210, L"ERROR_THREAD_1_INACTIVE"}, - {212, L"ERROR_LOCKED"}, - {214, L"ERROR_TOO_MANY_MODULES"}, - {215, L"ERROR_NESTING_NOT_ALLOWED"}, - {216, L"ERROR_EXE_MACHINE_TYPE_MISMATCH"}, - {217, L"ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY"}, - {218, L"ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY"}, - {220, L"ERROR_FILE_CHECKED_OUT"}, - {221, L"ERROR_CHECKOUT_REQUIRED"}, - {222, L"ERROR_BAD_FILE_TYPE"}, - {223, L"ERROR_FILE_TOO_LARGE"}, - {224, L"ERROR_FORMS_AUTH_REQUIRED"}, - {225, L"ERROR_VIRUS_INFECTED"}, - {226, L"ERROR_VIRUS_DELETED"}, - {229, L"ERROR_PIPE_LOCAL"}, - {230, L"ERROR_BAD_PIPE"}, - {231, L"ERROR_PIPE_BUSY"}, - {232, L"ERROR_NO_DATA"}, - {233, L"ERROR_PIPE_NOT_CONNECTED"}, - {234, L"ERROR_MORE_DATA"}, - {240, L"ERROR_VC_DISCONNECTED"}, - {254, L"ERROR_INVALID_EA_NAME"}, - {255, L"ERROR_EA_LIST_INCONSISTENT"}, - {258, L"WAIT_TIMEOUT"}, - {259, L"ERROR_NO_MORE_ITEMS"}, - {266, L"ERROR_CANNOT_COPY"}, - {267, L"ERROR_DIRECTORY"}, - {275, L"ERROR_EAS_DIDNT_FIT"}, - {276, L"ERROR_EA_FILE_CORRUPT"}, - {277, L"ERROR_EA_TABLE_FULL"}, - {278, L"ERROR_INVALID_EA_HANDLE"}, - {282, L"ERROR_EAS_NOT_SUPPORTED"}, - {288, L"ERROR_NOT_OWNER"}, - {298, L"ERROR_TOO_MANY_POSTS"}, - {299, L"ERROR_PARTIAL_COPY"}, - {300, L"ERROR_OPLOCK_NOT_GRANTED"}, - {301, L"ERROR_INVALID_OPLOCK_PROTOCOL"}, - {302, L"ERROR_DISK_TOO_FRAGMENTED"}, - {303, L"ERROR_DELETE_PENDING"}, - {304, L"ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING"}, - {305, L"ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME"}, - {306, L"ERROR_SECURITY_STREAM_IS_INCONSISTENT"}, - {307, L"ERROR_INVALID_LOCK_RANGE"}, - {308, L"ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT"}, - {309, L"ERROR_NOTIFICATION_GUID_ALREADY_DEFINED"}, - {310, L"ERROR_INVALID_EXCEPTION_HANDLER"}, - {311, L"ERROR_DUPLICATE_PRIVILEGES"}, - {312, L"ERROR_NO_RANGES_PROCESSED"}, - {313, L"ERROR_NOT_ALLOWED_ON_SYSTEM_FILE"}, - {314, L"ERROR_DISK_RESOURCES_EXHAUSTED"}, - {315, L"ERROR_INVALID_TOKEN"}, - {316, L"ERROR_DEVICE_FEATURE_NOT_SUPPORTED"}, - {317, L"ERROR_MR_MID_NOT_FOUND"}, - {318, L"ERROR_SCOPE_NOT_FOUND"}, - {319, L"ERROR_UNDEFINED_SCOPE"}, - {320, L"ERROR_INVALID_CAP"}, - {321, L"ERROR_DEVICE_UNREACHABLE"}, - {322, L"ERROR_DEVICE_NO_RESOURCES"}, - {323, L"ERROR_DATA_CHECKSUM_ERROR"}, - {324, L"ERROR_INTERMIXED_KERNEL_EA_OPERATION"}, - {326, L"ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED"}, - {327, L"ERROR_OFFSET_ALIGNMENT_VIOLATION"}, - {328, L"ERROR_INVALID_FIELD_IN_PARAMETER_LIST"}, - {329, L"ERROR_OPERATION_IN_PROGRESS"}, - {330, L"ERROR_BAD_DEVICE_PATH"}, - {331, L"ERROR_TOO_MANY_DESCRIPTORS"}, - {332, L"ERROR_SCRUB_DATA_DISABLED"}, - {333, L"ERROR_NOT_REDUNDANT_STORAGE"}, - {334, L"ERROR_RESIDENT_FILE_NOT_SUPPORTED"}, - {335, L"ERROR_COMPRESSED_FILE_NOT_SUPPORTED"}, - {336, L"ERROR_DIRECTORY_NOT_SUPPORTED"}, - {337, L"ERROR_NOT_READ_FROM_COPY"}, - {350, L"ERROR_FAIL_NOACTION_REBOOT"}, - {351, L"ERROR_FAIL_SHUTDOWN"}, - {352, L"ERROR_FAIL_RESTART"}, - {353, L"ERROR_MAX_SESSIONS_REACHED"}, - {400, L"ERROR_THREAD_MODE_ALREADY_BACKGROUND"}, - {401, L"ERROR_THREAD_MODE_NOT_BACKGROUND"}, - {402, L"ERROR_PROCESS_MODE_ALREADY_BACKGROUND"}, - {403, L"ERROR_PROCESS_MODE_NOT_BACKGROUND"}, - {487, L"ERROR_INVALID_ADDRESS"}, - {500, L"ERROR_USER_PROFILE_LOAD"}, - {534, L"ERROR_ARITHMETIC_OVERFLOW"}, - {535, L"ERROR_PIPE_CONNECTED"}, - {536, L"ERROR_PIPE_LISTENING"}, - {537, L"ERROR_VERIFIER_STOP"}, - {538, L"ERROR_ABIOS_ERROR"}, - {539, L"ERROR_WX86_WARNING"}, - {540, L"ERROR_WX86_ERROR"}, - {541, L"ERROR_TIMER_NOT_CANCELED"}, - {542, L"ERROR_UNWIND"}, - {543, L"ERROR_BAD_STACK"}, - {544, L"ERROR_INVALID_UNWIND_TARGET"}, - {545, L"ERROR_INVALID_PORT_ATTRIBUTES"}, - {546, L"ERROR_PORT_MESSAGE_TOO_LONG"}, - {547, L"ERROR_INVALID_QUOTA_LOWER"}, - {548, L"ERROR_DEVICE_ALREADY_ATTACHED"}, - {549, L"ERROR_INSTRUCTION_MISALIGNMENT"}, - {550, L"ERROR_PROFILING_NOT_STARTED"}, - {551, L"ERROR_PROFILING_NOT_STOPPED"}, - {552, L"ERROR_COULD_NOT_INTERPRET"}, - {553, L"ERROR_PROFILING_AT_LIMIT"}, - {554, L"ERROR_CANT_WAIT"}, - {555, L"ERROR_CANT_TERMINATE_SELF"}, - {556, L"ERROR_UNEXPECTED_MM_CREATE_ERR"}, - {557, L"ERROR_UNEXPECTED_MM_MAP_ERROR"}, - {558, L"ERROR_UNEXPECTED_MM_EXTEND_ERR"}, - {559, L"ERROR_BAD_FUNCTION_TABLE"}, - {560, L"ERROR_NO_GUID_TRANSLATION"}, - {561, L"ERROR_INVALID_LDT_SIZE"}, - {563, L"ERROR_INVALID_LDT_OFFSET"}, - {564, L"ERROR_INVALID_LDT_DESCRIPTOR"}, - {565, L"ERROR_TOO_MANY_THREADS"}, - {566, L"ERROR_THREAD_NOT_IN_PROCESS"}, - {567, L"ERROR_PAGEFILE_QUOTA_EXCEEDED"}, - {568, L"ERROR_LOGON_SERVER_CONFLICT"}, - {569, L"ERROR_SYNCHRONIZATION_REQUIRED"}, - {570, L"ERROR_NET_OPEN_FAILED"}, - {571, L"ERROR_IO_PRIVILEGE_FAILED"}, - {572, L"ERROR_CONTROL_C_EXIT"}, - {573, L"ERROR_MISSING_SYSTEMFILE"}, - {574, L"ERROR_UNHANDLED_EXCEPTION"}, - {575, L"ERROR_APP_INIT_FAILURE"}, - {576, L"ERROR_PAGEFILE_CREATE_FAILED"}, - {577, L"ERROR_INVALID_IMAGE_HASH"}, - {578, L"ERROR_NO_PAGEFILE"}, - {579, L"ERROR_ILLEGAL_FLOAT_CONTEXT"}, - {580, L"ERROR_NO_EVENT_PAIR"}, - {581, L"ERROR_DOMAIN_CTRLR_CONFIG_ERROR"}, - {582, L"ERROR_ILLEGAL_CHARACTER"}, - {583, L"ERROR_UNDEFINED_CHARACTER"}, - {584, L"ERROR_FLOPPY_VOLUME"}, - {585, L"ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT"}, - {586, L"ERROR_BACKUP_CONTROLLER"}, - {587, L"ERROR_MUTANT_LIMIT_EXCEEDED"}, - {588, L"ERROR_FS_DRIVER_REQUIRED"}, - {589, L"ERROR_CANNOT_LOAD_REGISTRY_FILE"}, - {590, L"ERROR_DEBUG_ATTACH_FAILED"}, - {591, L"ERROR_SYSTEM_PROCESS_TERMINATED"}, - {592, L"ERROR_DATA_NOT_ACCEPTED"}, - {593, L"ERROR_VDM_HARD_ERROR"}, - {594, L"ERROR_DRIVER_CANCEL_TIMEOUT"}, - {595, L"ERROR_REPLY_MESSAGE_MISMATCH"}, - {596, L"ERROR_LOST_WRITEBEHIND_DATA"}, - {597, L"ERROR_CLIENT_SERVER_PARAMETERS_INVALID"}, - {598, L"ERROR_NOT_TINY_STREAM"}, - {599, L"ERROR_STACK_OVERFLOW_READ"}, - {600, L"ERROR_CONVERT_TO_LARGE"}, - {601, L"ERROR_FOUND_OUT_OF_SCOPE"}, - {602, L"ERROR_ALLOCATE_BUCKET"}, - {603, L"ERROR_MARSHALL_OVERFLOW"}, - {604, L"ERROR_INVALID_VARIANT"}, - {605, L"ERROR_BAD_COMPRESSION_BUFFER"}, - {606, L"ERROR_AUDIT_FAILED"}, - {607, L"ERROR_TIMER_RESOLUTION_NOT_SET"}, - {608, L"ERROR_INSUFFICIENT_LOGON_INFO"}, - {609, L"ERROR_BAD_DLL_ENTRYPOINT"}, - {610, L"ERROR_BAD_SERVICE_ENTRYPOINT"}, - {611, L"ERROR_IP_ADDRESS_CONFLICT1"}, - {612, L"ERROR_IP_ADDRESS_CONFLICT2"}, - {613, L"ERROR_REGISTRY_QUOTA_LIMIT"}, - {614, L"ERROR_NO_CALLBACK_ACTIVE"}, - {615, L"ERROR_PWD_TOO_SHORT"}, - {616, L"ERROR_PWD_TOO_RECENT"}, - {617, L"ERROR_PWD_HISTORY_CONFLICT"}, - {618, L"ERROR_UNSUPPORTED_COMPRESSION"}, - {619, L"ERROR_INVALID_HW_PROFILE"}, - {620, L"ERROR_INVALID_PLUGPLAY_DEVICE_PATH"}, - {621, L"ERROR_QUOTA_LIST_INCONSISTENT"}, - {622, L"ERROR_EVALUATION_EXPIRATION"}, - {623, L"ERROR_ILLEGAL_DLL_RELOCATION"}, - {624, L"ERROR_DLL_INIT_FAILED_LOGOFF"}, - {625, L"ERROR_VALIDATE_CONTINUE"}, - {626, L"ERROR_NO_MORE_MATCHES"}, - {627, L"ERROR_RANGE_LIST_CONFLICT"}, - {628, L"ERROR_SERVER_SID_MISMATCH"}, - {629, L"ERROR_CANT_ENABLE_DENY_ONLY"}, - {630, L"ERROR_FLOAT_MULTIPLE_FAULTS"}, - {631, L"ERROR_FLOAT_MULTIPLE_TRAPS"}, - {632, L"ERROR_NOINTERFACE"}, - {633, L"ERROR_DRIVER_FAILED_SLEEP"}, - {634, L"ERROR_CORRUPT_SYSTEM_FILE"}, - {635, L"ERROR_COMMITMENT_MINIMUM"}, - {636, L"ERROR_PNP_RESTART_ENUMERATION"}, - {637, L"ERROR_SYSTEM_IMAGE_BAD_SIGNATURE"}, - {638, L"ERROR_PNP_REBOOT_REQUIRED"}, - {639, L"ERROR_INSUFFICIENT_POWER"}, - {640, L"ERROR_MULTIPLE_FAULT_VIOLATION"}, - {641, L"ERROR_SYSTEM_SHUTDOWN"}, - {642, L"ERROR_PORT_NOT_SET"}, - {643, L"ERROR_DS_VERSION_CHECK_FAILURE"}, - {644, L"ERROR_RANGE_NOT_FOUND"}, - {646, L"ERROR_NOT_SAFE_MODE_DRIVER"}, - {647, L"ERROR_FAILED_DRIVER_ENTRY"}, - {648, L"ERROR_DEVICE_ENUMERATION_ERROR"}, - {649, L"ERROR_MOUNT_POINT_NOT_RESOLVED"}, - {650, L"ERROR_INVALID_DEVICE_OBJECT_PARAMETER"}, - {651, L"ERROR_MCA_OCCURED"}, - {652, L"ERROR_DRIVER_DATABASE_ERROR"}, - {653, L"ERROR_SYSTEM_HIVE_TOO_LARGE"}, - {654, L"ERROR_DRIVER_FAILED_PRIOR_UNLOAD"}, - {655, L"ERROR_VOLSNAP_PREPARE_HIBERNATE"}, - {656, L"ERROR_HIBERNATION_FAILURE"}, - {657, L"ERROR_PWD_TOO_LONG"}, - {665, L"ERROR_FILE_SYSTEM_LIMITATION"}, - {668, L"ERROR_ASSERTION_FAILURE"}, - {669, L"ERROR_ACPI_ERROR"}, - {670, L"ERROR_WOW_ASSERTION"}, - {671, L"ERROR_PNP_BAD_MPS_TABLE"}, - {672, L"ERROR_PNP_TRANSLATION_FAILED"}, - {673, L"ERROR_PNP_IRQ_TRANSLATION_FAILED"}, - {674, L"ERROR_PNP_INVALID_ID"}, - {675, L"ERROR_WAKE_SYSTEM_DEBUGGER"}, - {676, L"ERROR_HANDLES_CLOSED"}, - {677, L"ERROR_EXTRANEOUS_INFORMATION"}, - {678, L"ERROR_RXACT_COMMIT_NECESSARY"}, - {679, L"ERROR_MEDIA_CHECK"}, - {680, L"ERROR_GUID_SUBSTITUTION_MADE"}, - {681, L"ERROR_STOPPED_ON_SYMLINK"}, - {682, L"ERROR_LONGJUMP"}, - {683, L"ERROR_PLUGPLAY_QUERY_VETOED"}, - {684, L"ERROR_UNWIND_CONSOLIDATE"}, - {685, L"ERROR_REGISTRY_HIVE_RECOVERED"}, - {686, L"ERROR_DLL_MIGHT_BE_INSECURE"}, - {687, L"ERROR_DLL_MIGHT_BE_INCOMPATIBLE"}, - {688, L"ERROR_DBG_EXCEPTION_NOT_HANDLED"}, - {689, L"ERROR_DBG_REPLY_LATER"}, - {690, L"ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE"}, - {691, L"ERROR_DBG_TERMINATE_THREAD"}, - {692, L"ERROR_DBG_TERMINATE_PROCESS"}, - {693, L"ERROR_DBG_CONTROL_C"}, - {694, L"ERROR_DBG_PRINTEXCEPTION_C"}, - {695, L"ERROR_DBG_RIPEXCEPTION"}, - {696, L"ERROR_DBG_CONTROL_BREAK"}, - {697, L"ERROR_DBG_COMMAND_EXCEPTION"}, - {698, L"ERROR_OBJECT_NAME_EXISTS"}, - {699, L"ERROR_THREAD_WAS_SUSPENDED"}, - {700, L"ERROR_IMAGE_NOT_AT_BASE"}, - {701, L"ERROR_RXACT_STATE_CREATED"}, - {702, L"ERROR_SEGMENT_NOTIFICATION"}, - {703, L"ERROR_BAD_CURRENT_DIRECTORY"}, - {704, L"ERROR_FT_READ_RECOVERY_FROM_BACKUP"}, - {705, L"ERROR_FT_WRITE_RECOVERY"}, - {706, L"ERROR_IMAGE_MACHINE_TYPE_MISMATCH"}, - {707, L"ERROR_RECEIVE_PARTIAL"}, - {708, L"ERROR_RECEIVE_EXPEDITED"}, - {709, L"ERROR_RECEIVE_PARTIAL_EXPEDITED"}, - {710, L"ERROR_EVENT_DONE"}, - {711, L"ERROR_EVENT_PENDING"}, - {712, L"ERROR_CHECKING_FILE_SYSTEM"}, - {713, L"ERROR_FATAL_APP_EXIT"}, - {714, L"ERROR_PREDEFINED_HANDLE"}, - {715, L"ERROR_WAS_UNLOCKED"}, - {716, L"ERROR_SERVICE_NOTIFICATION"}, - {717, L"ERROR_WAS_LOCKED"}, - {718, L"ERROR_LOG_HARD_ERROR"}, - {719, L"ERROR_ALREADY_WIN32"}, - {720, L"ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE"}, - {721, L"ERROR_NO_YIELD_PERFORMED"}, - {722, L"ERROR_TIMER_RESUME_IGNORED"}, - {723, L"ERROR_ARBITRATION_UNHANDLED"}, - {724, L"ERROR_CARDBUS_NOT_SUPPORTED"}, - {725, L"ERROR_MP_PROCESSOR_MISMATCH"}, - {726, L"ERROR_HIBERNATED"}, - {727, L"ERROR_RESUME_HIBERNATION"}, - {728, L"ERROR_FIRMWARE_UPDATED"}, - {729, L"ERROR_DRIVERS_LEAKING_LOCKED_PAGES"}, - {730, L"ERROR_WAKE_SYSTEM"}, - {731, L"ERROR_WAIT_1"}, - {732, L"ERROR_WAIT_2"}, - {733, L"ERROR_WAIT_3"}, - {734, L"ERROR_WAIT_63"}, - {735, L"ERROR_ABANDONED_WAIT_0"}, - {736, L"ERROR_ABANDONED_WAIT_63"}, - {737, L"ERROR_USER_APC"}, - {738, L"ERROR_KERNEL_APC"}, - {739, L"ERROR_ALERTED"}, - {740, L"ERROR_ELEVATION_REQUIRED"}, - {741, L"ERROR_REPARSE"}, - {742, L"ERROR_OPLOCK_BREAK_IN_PROGRESS"}, - {743, L"ERROR_VOLUME_MOUNTED"}, - {744, L"ERROR_RXACT_COMMITTED"}, - {745, L"ERROR_NOTIFY_CLEANUP"}, - {746, L"ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED"}, - {747, L"ERROR_PAGE_FAULT_TRANSITION"}, - {748, L"ERROR_PAGE_FAULT_DEMAND_ZERO"}, - {749, L"ERROR_PAGE_FAULT_COPY_ON_WRITE"}, - {750, L"ERROR_PAGE_FAULT_GUARD_PAGE"}, - {751, L"ERROR_PAGE_FAULT_PAGING_FILE"}, - {752, L"ERROR_CACHE_PAGE_LOCKED"}, - {753, L"ERROR_CRASH_DUMP"}, - {754, L"ERROR_BUFFER_ALL_ZEROS"}, - {755, L"ERROR_REPARSE_OBJECT"}, - {756, L"ERROR_RESOURCE_REQUIREMENTS_CHANGED"}, - {757, L"ERROR_TRANSLATION_COMPLETE"}, - {758, L"ERROR_NOTHING_TO_TERMINATE"}, - {759, L"ERROR_PROCESS_NOT_IN_JOB"}, - {760, L"ERROR_PROCESS_IN_JOB"}, - {761, L"ERROR_VOLSNAP_HIBERNATE_READY"}, - {762, L"ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY"}, - {763, L"ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED"}, - {764, L"ERROR_INTERRUPT_STILL_CONNECTED"}, - {765, L"ERROR_WAIT_FOR_OPLOCK"}, - {766, L"ERROR_DBG_EXCEPTION_HANDLED"}, - {767, L"ERROR_DBG_CONTINUE"}, - {768, L"ERROR_CALLBACK_POP_STACK"}, - {769, L"ERROR_COMPRESSION_DISABLED"}, - {770, L"ERROR_CANTFETCHBACKWARDS"}, - {771, L"ERROR_CANTSCROLLBACKWARDS"}, - {772, L"ERROR_ROWSNOTRELEASED"}, - {773, L"ERROR_BAD_ACCESSOR_FLAGS"}, - {774, L"ERROR_ERRORS_ENCOUNTERED"}, - {775, L"ERROR_NOT_CAPABLE"}, - {776, L"ERROR_REQUEST_OUT_OF_SEQUENCE"}, - {777, L"ERROR_VERSION_PARSE_ERROR"}, - {778, L"ERROR_BADSTARTPOSITION"}, - {779, L"ERROR_MEMORY_HARDWARE"}, - {780, L"ERROR_DISK_REPAIR_DISABLED"}, - {781, L"ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE"}, - {782, L"ERROR_SYSTEM_POWERSTATE_TRANSITION"}, - {783, L"ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION"}, - {784, L"ERROR_MCA_EXCEPTION"}, - {785, L"ERROR_ACCESS_AUDIT_BY_POLICY"}, - {786, L"ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY"}, - {787, L"ERROR_ABANDON_HIBERFILE"}, - {788, L"ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED"}, - {789, L"ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR"}, - {790, L"ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR"}, - {791, L"ERROR_BAD_MCFG_TABLE"}, - {792, L"ERROR_DISK_REPAIR_REDIRECTED"}, - {793, L"ERROR_DISK_REPAIR_UNSUCCESSFUL"}, - {794, L"ERROR_CORRUPT_LOG_OVERFULL"}, - {795, L"ERROR_CORRUPT_LOG_CORRUPTED"}, - {796, L"ERROR_CORRUPT_LOG_UNAVAILABLE"}, - {797, L"ERROR_CORRUPT_LOG_DELETED_FULL"}, - {798, L"ERROR_CORRUPT_LOG_CLEARED"}, - {799, L"ERROR_ORPHAN_NAME_EXHAUSTED"}, - {800, L"ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE"}, - {801, L"ERROR_CANNOT_GRANT_REQUESTED_OPLOCK"}, - {802, L"ERROR_CANNOT_BREAK_OPLOCK"}, - {803, L"ERROR_OPLOCK_HANDLE_CLOSED"}, - {804, L"ERROR_NO_ACE_CONDITION"}, - {805, L"ERROR_INVALID_ACE_CONDITION"}, - {806, L"ERROR_FILE_HANDLE_REVOKED"}, - {807, L"ERROR_IMAGE_AT_DIFFERENT_BASE"}, - {994, L"ERROR_EA_ACCESS_DENIED"}, - {995, L"ERROR_OPERATION_ABORTED"}, - {996, L"ERROR_IO_INCOMPLETE"}, - {997, L"ERROR_IO_PENDING"}, - {998, L"ERROR_NOACCESS"}, - {999, L"ERROR_SWAPERROR"}, - {1001, L"ERROR_STACK_OVERFLOW"}, - {1002, L"ERROR_INVALID_MESSAGE"}, - {1003, L"ERROR_CAN_NOT_COMPLETE"}, - {1004, L"ERROR_INVALID_FLAGS"}, - {1005, L"ERROR_UNRECOGNIZED_VOLUME"}, - {1006, L"ERROR_FILE_INVALID"}, - {1007, L"ERROR_FULLSCREEN_MODE"}, - {1008, L"ERROR_NO_TOKEN"}, - {1009, L"ERROR_BADDB"}, - {1010, L"ERROR_BADKEY"}, - {1011, L"ERROR_CANTOPEN"}, - {1012, L"ERROR_CANTREAD"}, - {1013, L"ERROR_CANTWRITE"}, - {1014, L"ERROR_REGISTRY_RECOVERED"}, - {1015, L"ERROR_REGISTRY_CORRUPT"}, - {1016, L"ERROR_REGISTRY_IO_FAILED"}, - {1017, L"ERROR_NOT_REGISTRY_FILE"}, - {1018, L"ERROR_KEY_DELETED"}, - {1019, L"ERROR_NO_LOG_SPACE"}, - {1020, L"ERROR_KEY_HAS_CHILDREN"}, - {1021, L"ERROR_CHILD_MUST_BE_VOLATILE"}, - {1022, L"ERROR_NOTIFY_ENUM_DIR"}, - {1051, L"ERROR_DEPENDENT_SERVICES_RUNNING"}, - {1052, L"ERROR_INVALID_SERVICE_CONTROL"}, - {1053, L"ERROR_SERVICE_REQUEST_TIMEOUT"}, - {1054, L"ERROR_SERVICE_NO_THREAD"}, - {1055, L"ERROR_SERVICE_DATABASE_LOCKED"}, - {1056, L"ERROR_SERVICE_ALREADY_RUNNING"}, - {1057, L"ERROR_INVALID_SERVICE_ACCOUNT"}, - {1058, L"ERROR_SERVICE_DISABLED"}, - {1059, L"ERROR_CIRCULAR_DEPENDENCY"}, - {1060, L"ERROR_SERVICE_DOES_NOT_EXIST"}, - {1061, L"ERROR_SERVICE_CANNOT_ACCEPT_CTRL"}, - {1062, L"ERROR_SERVICE_NOT_ACTIVE"}, - {1063, L"ERROR_FAILED_SERVICE_CONTROLLER_CONNECT"}, - {1064, L"ERROR_EXCEPTION_IN_SERVICE"}, - {1065, L"ERROR_DATABASE_DOES_NOT_EXIST"}, - {1066, L"ERROR_SERVICE_SPECIFIC_ERROR"}, - {1067, L"ERROR_PROCESS_ABORTED"}, - {1068, L"ERROR_SERVICE_DEPENDENCY_FAIL"}, - {1069, L"ERROR_SERVICE_LOGON_FAILED"}, - {1070, L"ERROR_SERVICE_START_HANG"}, - {1071, L"ERROR_INVALID_SERVICE_LOCK"}, - {1072, L"ERROR_SERVICE_MARKED_FOR_DELETE"}, - {1073, L"ERROR_SERVICE_EXISTS"}, - {1074, L"ERROR_ALREADY_RUNNING_LKG"}, - {1075, L"ERROR_SERVICE_DEPENDENCY_DELETED"}, - {1076, L"ERROR_BOOT_ALREADY_ACCEPTED"}, - {1077, L"ERROR_SERVICE_NEVER_STARTED"}, - {1078, L"ERROR_DUPLICATE_SERVICE_NAME"}, - {1079, L"ERROR_DIFFERENT_SERVICE_ACCOUNT"}, - {1080, L"ERROR_CANNOT_DETECT_DRIVER_FAILURE"}, - {1081, L"ERROR_CANNOT_DETECT_PROCESS_ABORT"}, - {1082, L"ERROR_NO_RECOVERY_PROGRAM"}, - {1083, L"ERROR_SERVICE_NOT_IN_EXE"}, - {1084, L"ERROR_NOT_SAFEBOOT_SERVICE"}, - {1100, L"ERROR_END_OF_MEDIA"}, - {1101, L"ERROR_FILEMARK_DETECTED"}, - {1102, L"ERROR_BEGINNING_OF_MEDIA"}, - {1103, L"ERROR_SETMARK_DETECTED"}, - {1104, L"ERROR_NO_DATA_DETECTED"}, - {1105, L"ERROR_PARTITION_FAILURE"}, - {1106, L"ERROR_INVALID_BLOCK_LENGTH"}, - {1107, L"ERROR_DEVICE_NOT_PARTITIONED"}, - {1108, L"ERROR_UNABLE_TO_LOCK_MEDIA"}, - {1109, L"ERROR_UNABLE_TO_UNLOAD_MEDIA"}, - {1110, L"ERROR_MEDIA_CHANGED"}, - {1111, L"ERROR_BUS_RESET"}, - {1112, L"ERROR_NO_MEDIA_IN_DRIVE"}, - {1113, L"ERROR_NO_UNICODE_TRANSLATION"}, - {1114, L"ERROR_DLL_INIT_FAILED"}, - {1115, L"ERROR_SHUTDOWN_IN_PROGRESS"}, - {1116, L"ERROR_NO_SHUTDOWN_IN_PROGRESS"}, - {1117, L"ERROR_IO_DEVICE"}, - {1118, L"ERROR_SERIAL_NO_DEVICE"}, - {1119, L"ERROR_IRQ_BUSY"}, - {1120, L"ERROR_MORE_WRITES"}, - {1121, L"ERROR_COUNTER_TIMEOUT"}, - {1122, L"ERROR_FLOPPY_ID_MARK_NOT_FOUND"}, - {1123, L"ERROR_FLOPPY_WRONG_CYLINDER"}, - {1124, L"ERROR_FLOPPY_UNKNOWN_ERROR"}, - {1125, L"ERROR_FLOPPY_BAD_REGISTERS"}, - {1126, L"ERROR_DISK_RECALIBRATE_FAILED"}, - {1127, L"ERROR_DISK_OPERATION_FAILED"}, - {1128, L"ERROR_DISK_RESET_FAILED"}, - {1129, L"ERROR_EOM_OVERFLOW"}, - {1130, L"ERROR_NOT_ENOUGH_SERVER_MEMORY"}, - {1131, L"ERROR_POSSIBLE_DEADLOCK"}, - {1132, L"ERROR_MAPPED_ALIGNMENT"}, - {1140, L"ERROR_SET_POWER_STATE_VETOED"}, - {1141, L"ERROR_SET_POWER_STATE_FAILED"}, - {1142, L"ERROR_TOO_MANY_LINKS"}, - {1150, L"ERROR_OLD_WIN_VERSION"}, - {1151, L"ERROR_APP_WRONG_OS"}, - {1152, L"ERROR_SINGLE_INSTANCE_APP"}, - {1153, L"ERROR_RMODE_APP"}, - {1154, L"ERROR_INVALID_DLL"}, - {1155, L"ERROR_NO_ASSOCIATION"}, - {1156, L"ERROR_DDE_FAIL"}, - {1157, L"ERROR_DLL_NOT_FOUND"}, - {1158, L"ERROR_NO_MORE_USER_HANDLES"}, - {1159, L"ERROR_MESSAGE_SYNC_ONLY"}, - {1160, L"ERROR_SOURCE_ELEMENT_EMPTY"}, - {1161, L"ERROR_DESTINATION_ELEMENT_FULL"}, - {1162, L"ERROR_ILLEGAL_ELEMENT_ADDRESS"}, - {1163, L"ERROR_MAGAZINE_NOT_PRESENT"}, - {1164, L"ERROR_DEVICE_REINITIALIZATION_NEEDED"}, - {1165, L"ERROR_DEVICE_REQUIRES_CLEANING"}, - {1166, L"ERROR_DEVICE_DOOR_OPEN"}, - {1167, L"ERROR_DEVICE_NOT_CONNECTED"}, - {1168, L"ERROR_NOT_FOUND"}, - {1169, L"ERROR_NO_MATCH"}, - {1170, L"ERROR_SET_NOT_FOUND"}, - {1171, L"ERROR_POINT_NOT_FOUND"}, - {1172, L"ERROR_NO_TRACKING_SERVICE"}, - {1173, L"ERROR_NO_VOLUME_ID"}, - {1175, L"ERROR_UNABLE_TO_REMOVE_REPLACED"}, - {1176, L"ERROR_UNABLE_TO_MOVE_REPLACEMENT"}, - {1177, L"ERROR_UNABLE_TO_MOVE_REPLACEMENT_2"}, - {1178, L"ERROR_JOURNAL_DELETE_IN_PROGRESS"}, - {1179, L"ERROR_JOURNAL_NOT_ACTIVE"}, - {1180, L"ERROR_POTENTIAL_FILE_FOUND"}, - {1181, L"ERROR_JOURNAL_ENTRY_DELETED"}, - {1190, L"ERROR_SHUTDOWN_IS_SCHEDULED"}, - {1191, L"ERROR_SHUTDOWN_USERS_LOGGED_ON"}, - {1200, L"ERROR_BAD_DEVICE"}, - {1201, L"ERROR_CONNECTION_UNAVAIL"}, - {1202, L"ERROR_DEVICE_ALREADY_REMEMBERED"}, - {1203, L"ERROR_NO_NET_OR_BAD_PATH"}, - {1204, L"ERROR_BAD_PROVIDER"}, - {1205, L"ERROR_CANNOT_OPEN_PROFILE"}, - {1206, L"ERROR_BAD_PROFILE"}, - {1207, L"ERROR_NOT_CONTAINER"}, - {1208, L"ERROR_EXTENDED_ERROR"}, - {1209, L"ERROR_INVALID_GROUPNAME"}, - {1210, L"ERROR_INVALID_COMPUTERNAME"}, - {1211, L"ERROR_INVALID_EVENTNAME"}, - {1212, L"ERROR_INVALID_DOMAINNAME"}, - {1213, L"ERROR_INVALID_SERVICENAME"}, - {1214, L"ERROR_INVALID_NETNAME"}, - {1215, L"ERROR_INVALID_SHARENAME"}, - {1216, L"ERROR_INVALID_PASSWORDNAME"}, - {1217, L"ERROR_INVALID_MESSAGENAME"}, - {1218, L"ERROR_INVALID_MESSAGEDEST"}, - {1219, L"ERROR_SESSION_CREDENTIAL_CONFLICT"}, - {1220, L"ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"}, - {1221, L"ERROR_DUP_DOMAINNAME"}, - {1222, L"ERROR_NO_NETWORK"}, - {1223, L"ERROR_CANCELLED"}, - {1224, L"ERROR_USER_MAPPED_FILE"}, - {1225, L"ERROR_CONNECTION_REFUSED"}, - {1226, L"ERROR_GRACEFUL_DISCONNECT"}, - {1227, L"ERROR_ADDRESS_ALREADY_ASSOCIATED"}, - {1228, L"ERROR_ADDRESS_NOT_ASSOCIATED"}, - {1229, L"ERROR_CONNECTION_INVALID"}, - {1230, L"ERROR_CONNECTION_ACTIVE"}, - {1231, L"ERROR_NETWORK_UNREACHABLE"}, - {1232, L"ERROR_HOST_UNREACHABLE"}, - {1233, L"ERROR_PROTOCOL_UNREACHABLE"}, - {1234, L"ERROR_PORT_UNREACHABLE"}, - {1235, L"ERROR_REQUEST_ABORTED"}, - {1236, L"ERROR_CONNECTION_ABORTED"}, - {1237, L"ERROR_RETRY"}, - {1238, L"ERROR_CONNECTION_COUNT_LIMIT"}, - {1239, L"ERROR_LOGIN_TIME_RESTRICTION"}, - {1240, L"ERROR_LOGIN_WKSTA_RESTRICTION"}, - {1241, L"ERROR_INCORRECT_ADDRESS"}, - {1242, L"ERROR_ALREADY_REGISTERED"}, - {1243, L"ERROR_SERVICE_NOT_FOUND"}, - {1244, L"ERROR_NOT_AUTHENTICATED"}, - {1245, L"ERROR_NOT_LOGGED_ON"}, - {1246, L"ERROR_CONTINUE"}, - {1247, L"ERROR_ALREADY_INITIALIZED"}, - {1248, L"ERROR_NO_MORE_DEVICES"}, - {1249, L"ERROR_NO_SUCH_SITE"}, - {1250, L"ERROR_DOMAIN_CONTROLLER_EXISTS"}, - {1251, L"ERROR_ONLY_IF_CONNECTED"}, - {1252, L"ERROR_OVERRIDE_NOCHANGES"}, - {1253, L"ERROR_BAD_USER_PROFILE"}, - {1254, L"ERROR_NOT_SUPPORTED_ON_SBS"}, - {1255, L"ERROR_SERVER_SHUTDOWN_IN_PROGRESS"}, - {1256, L"ERROR_HOST_DOWN"}, - {1257, L"ERROR_NON_ACCOUNT_SID"}, - {1258, L"ERROR_NON_DOMAIN_SID"}, - {1259, L"ERROR_APPHELP_BLOCK"}, - {1260, L"ERROR_ACCESS_DISABLED_BY_POLICY"}, - {1261, L"ERROR_REG_NAT_CONSUMPTION"}, - {1262, L"ERROR_CSCSHARE_OFFLINE"}, - {1263, L"ERROR_PKINIT_FAILURE"}, - {1264, L"ERROR_SMARTCARD_SUBSYSTEM_FAILURE"}, - {1265, L"ERROR_DOWNGRADE_DETECTED"}, - {1271, L"ERROR_MACHINE_LOCKED"}, - {1273, L"ERROR_CALLBACK_SUPPLIED_INVALID_DATA"}, - {1274, L"ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED"}, - {1275, L"ERROR_DRIVER_BLOCKED"}, - {1276, L"ERROR_INVALID_IMPORT_OF_NON_DLL"}, - {1277, L"ERROR_ACCESS_DISABLED_WEBBLADE"}, - {1278, L"ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER"}, - {1279, L"ERROR_RECOVERY_FAILURE"}, - {1280, L"ERROR_ALREADY_FIBER"}, - {1281, L"ERROR_ALREADY_THREAD"}, - {1282, L"ERROR_STACK_BUFFER_OVERRUN"}, - {1283, L"ERROR_PARAMETER_QUOTA_EXCEEDED"}, - {1284, L"ERROR_DEBUGGER_INACTIVE"}, - {1285, L"ERROR_DELAY_LOAD_FAILED"}, - {1286, L"ERROR_VDM_DISALLOWED"}, - {1287, L"ERROR_UNIDENTIFIED_ERROR"}, - {1288, L"ERROR_INVALID_CRUNTIME_PARAMETER"}, - {1289, L"ERROR_BEYOND_VDL"}, - {1290, L"ERROR_INCOMPATIBLE_SERVICE_SID_TYPE"}, - {1291, L"ERROR_DRIVER_PROCESS_TERMINATED"}, - {1292, L"ERROR_IMPLEMENTATION_LIMIT"}, - {1293, L"ERROR_PROCESS_IS_PROTECTED"}, - {1294, L"ERROR_SERVICE_NOTIFY_CLIENT_LAGGING"}, - {1295, L"ERROR_DISK_QUOTA_EXCEEDED"}, - {1296, L"ERROR_CONTENT_BLOCKED"}, - {1297, L"ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE"}, - {1298, L"ERROR_APP_HANG"}, - {1299, L"ERROR_INVALID_LABEL"}, - {1300, L"ERROR_NOT_ALL_ASSIGNED"}, - {1301, L"ERROR_SOME_NOT_MAPPED"}, - {1302, L"ERROR_NO_QUOTAS_FOR_ACCOUNT"}, - {1303, L"ERROR_LOCAL_USER_SESSION_KEY"}, - {1304, L"ERROR_NULL_LM_PASSWORD"}, - {1305, L"ERROR_UNKNOWN_REVISION"}, - {1306, L"ERROR_REVISION_MISMATCH"}, - {1307, L"ERROR_INVALID_OWNER"}, - {1308, L"ERROR_INVALID_PRIMARY_GROUP"}, - {1309, L"ERROR_NO_IMPERSONATION_TOKEN"}, - {1310, L"ERROR_CANT_DISABLE_MANDATORY"}, - {1311, L"ERROR_NO_LOGON_SERVERS"}, - {1312, L"ERROR_NO_SUCH_LOGON_SESSION"}, - {1313, L"ERROR_NO_SUCH_PRIVILEGE"}, - {1314, L"ERROR_PRIVILEGE_NOT_HELD"}, - {1315, L"ERROR_INVALID_ACCOUNT_NAME"}, - {1316, L"ERROR_USER_EXISTS"}, - {1317, L"ERROR_NO_SUCH_USER"}, - {1318, L"ERROR_GROUP_EXISTS"}, - {1319, L"ERROR_NO_SUCH_GROUP"}, - {1320, L"ERROR_MEMBER_IN_GROUP"}, - {1321, L"ERROR_MEMBER_NOT_IN_GROUP"}, - {1322, L"ERROR_LAST_ADMIN"}, - {1323, L"ERROR_WRONG_PASSWORD"}, - {1324, L"ERROR_ILL_FORMED_PASSWORD"}, - {1325, L"ERROR_PASSWORD_RESTRICTION"}, - {1326, L"ERROR_LOGON_FAILURE"}, - {1327, L"ERROR_ACCOUNT_RESTRICTION"}, - {1328, L"ERROR_INVALID_LOGON_HOURS"}, - {1329, L"ERROR_INVALID_WORKSTATION"}, - {1330, L"ERROR_PASSWORD_EXPIRED"}, - {1331, L"ERROR_ACCOUNT_DISABLED"}, - {1332, L"ERROR_NONE_MAPPED"}, - {1333, L"ERROR_TOO_MANY_LUIDS_REQUESTED"}, - {1334, L"ERROR_LUIDS_EXHAUSTED"}, - {1335, L"ERROR_INVALID_SUB_AUTHORITY"}, - {1336, L"ERROR_INVALID_ACL"}, - {1337, L"ERROR_INVALID_SID"}, - {1338, L"ERROR_INVALID_SECURITY_DESCR"}, - {1340, L"ERROR_BAD_INHERITANCE_ACL"}, - {1341, L"ERROR_SERVER_DISABLED"}, - {1342, L"ERROR_SERVER_NOT_DISABLED"}, - {1343, L"ERROR_INVALID_ID_AUTHORITY"}, - {1344, L"ERROR_ALLOTTED_SPACE_EXCEEDED"}, - {1345, L"ERROR_INVALID_GROUP_ATTRIBUTES"}, - {1346, L"ERROR_BAD_IMPERSONATION_LEVEL"}, - {1347, L"ERROR_CANT_OPEN_ANONYMOUS"}, - {1348, L"ERROR_BAD_VALIDATION_CLASS"}, - {1349, L"ERROR_BAD_TOKEN_TYPE"}, - {1350, L"ERROR_NO_SECURITY_ON_OBJECT"}, - {1351, L"ERROR_CANT_ACCESS_DOMAIN_INFO"}, - {1352, L"ERROR_INVALID_SERVER_STATE"}, - {1353, L"ERROR_INVALID_DOMAIN_STATE"}, - {1354, L"ERROR_INVALID_DOMAIN_ROLE"}, - {1355, L"ERROR_NO_SUCH_DOMAIN"}, - {1356, L"ERROR_DOMAIN_EXISTS"}, - {1357, L"ERROR_DOMAIN_LIMIT_EXCEEDED"}, - {1358, L"ERROR_INTERNAL_DB_CORRUPTION"}, - {1359, L"ERROR_INTERNAL_ERROR"}, - {1360, L"ERROR_GENERIC_NOT_MAPPED"}, - {1361, L"ERROR_BAD_DESCRIPTOR_FORMAT"}, - {1362, L"ERROR_NOT_LOGON_PROCESS"}, - {1363, L"ERROR_LOGON_SESSION_EXISTS"}, - {1364, L"ERROR_NO_SUCH_PACKAGE"}, - {1365, L"ERROR_BAD_LOGON_SESSION_STATE"}, - {1366, L"ERROR_LOGON_SESSION_COLLISION"}, - {1367, L"ERROR_INVALID_LOGON_TYPE"}, - {1368, L"ERROR_CANNOT_IMPERSONATE"}, - {1369, L"ERROR_RXACT_INVALID_STATE"}, - {1370, L"ERROR_RXACT_COMMIT_FAILURE"}, - {1371, L"ERROR_SPECIAL_ACCOUNT"}, - {1372, L"ERROR_SPECIAL_GROUP"}, - {1373, L"ERROR_SPECIAL_USER"}, - {1374, L"ERROR_MEMBERS_PRIMARY_GROUP"}, - {1375, L"ERROR_TOKEN_ALREADY_IN_USE"}, - {1376, L"ERROR_NO_SUCH_ALIAS"}, - {1377, L"ERROR_MEMBER_NOT_IN_ALIAS"}, - {1378, L"ERROR_MEMBER_IN_ALIAS"}, - {1379, L"ERROR_ALIAS_EXISTS"}, - {1380, L"ERROR_LOGON_NOT_GRANTED"}, - {1381, L"ERROR_TOO_MANY_SECRETS"}, - {1382, L"ERROR_SECRET_TOO_LONG"}, - {1383, L"ERROR_INTERNAL_DB_ERROR"}, - {1384, L"ERROR_TOO_MANY_CONTEXT_IDS"}, - {1385, L"ERROR_LOGON_TYPE_NOT_GRANTED"}, - {1386, L"ERROR_NT_CROSS_ENCRYPTION_REQUIRED"}, - {1387, L"ERROR_NO_SUCH_MEMBER"}, - {1388, L"ERROR_INVALID_MEMBER"}, - {1389, L"ERROR_TOO_MANY_SIDS"}, - {1390, L"ERROR_LM_CROSS_ENCRYPTION_REQUIRED"}, - {1391, L"ERROR_NO_INHERITANCE"}, - {1392, L"ERROR_FILE_CORRUPT"}, - {1393, L"ERROR_DISK_CORRUPT"}, - {1394, L"ERROR_NO_USER_SESSION_KEY"}, - {1395, L"ERROR_LICENSE_QUOTA_EXCEEDED"}, - {1396, L"ERROR_WRONG_TARGET_NAME"}, - {1397, L"ERROR_MUTUAL_AUTH_FAILED"}, - {1398, L"ERROR_TIME_SKEW"}, - {1399, L"ERROR_CURRENT_DOMAIN_NOT_ALLOWED"}, - {1400, L"ERROR_INVALID_WINDOW_HANDLE"}, - {1401, L"ERROR_INVALID_MENU_HANDLE"}, - {1402, L"ERROR_INVALID_CURSOR_HANDLE"}, - {1403, L"ERROR_INVALID_ACCEL_HANDLE"}, - {1404, L"ERROR_INVALID_HOOK_HANDLE"}, - {1405, L"ERROR_INVALID_DWP_HANDLE"}, - {1406, L"ERROR_TLW_WITH_WSCHILD"}, - {1407, L"ERROR_CANNOT_FIND_WND_CLASS"}, - {1408, L"ERROR_WINDOW_OF_OTHER_THREAD"}, - {1409, L"ERROR_HOTKEY_ALREADY_REGISTERED"}, - {1410, L"ERROR_CLASS_ALREADY_EXISTS"}, - {1411, L"ERROR_CLASS_DOES_NOT_EXIST"}, - {1412, L"ERROR_CLASS_HAS_WINDOWS"}, - {1413, L"ERROR_INVALID_INDEX"}, - {1414, L"ERROR_INVALID_ICON_HANDLE"}, - {1415, L"ERROR_PRIVATE_DIALOG_INDEX"}, - {1416, L"ERROR_LISTBOX_ID_NOT_FOUND"}, - {1417, L"ERROR_NO_WILDCARD_CHARACTERS"}, - {1418, L"ERROR_CLIPBOARD_NOT_OPEN"}, - {1419, L"ERROR_HOTKEY_NOT_REGISTERED"}, - {1420, L"ERROR_WINDOW_NOT_DIALOG"}, - {1421, L"ERROR_CONTROL_ID_NOT_FOUND"}, - {1422, L"ERROR_INVALID_COMBOBOX_MESSAGE"}, - {1423, L"ERROR_WINDOW_NOT_COMBOBOX"}, - {1424, L"ERROR_INVALID_EDIT_HEIGHT"}, - {1425, L"ERROR_DC_NOT_FOUND"}, - {1426, L"ERROR_INVALID_HOOK_FILTER"}, - {1427, L"ERROR_INVALID_FILTER_PROC"}, - {1428, L"ERROR_HOOK_NEEDS_HMOD"}, - {1429, L"ERROR_GLOBAL_ONLY_HOOK"}, - {1430, L"ERROR_JOURNAL_HOOK_SET"}, - {1431, L"ERROR_HOOK_NOT_INSTALLED"}, - {1432, L"ERROR_INVALID_LB_MESSAGE"}, - {1433, L"ERROR_SETCOUNT_ON_BAD_LB"}, - {1434, L"ERROR_LB_WITHOUT_TABSTOPS"}, - {1435, L"ERROR_DESTROY_OBJECT_OF_OTHER_THREAD"}, - {1436, L"ERROR_CHILD_WINDOW_MENU"}, - {1437, L"ERROR_NO_SYSTEM_MENU"}, - {1438, L"ERROR_INVALID_MSGBOX_STYLE"}, - {1439, L"ERROR_INVALID_SPI_VALUE"}, - {1440, L"ERROR_SCREEN_ALREADY_LOCKED"}, - {1441, L"ERROR_HWNDS_HAVE_DIFF_PARENT"}, - {1442, L"ERROR_NOT_CHILD_WINDOW"}, - {1443, L"ERROR_INVALID_GW_COMMAND"}, - {1444, L"ERROR_INVALID_THREAD_ID"}, - {1445, L"ERROR_NON_MDICHILD_WINDOW"}, - {1446, L"ERROR_POPUP_ALREADY_ACTIVE"}, - {1447, L"ERROR_NO_SCROLLBARS"}, - {1448, L"ERROR_INVALID_SCROLLBAR_RANGE"}, - {1449, L"ERROR_INVALID_SHOWWIN_COMMAND"}, - {1450, L"ERROR_NO_SYSTEM_RESOURCES"}, - {1451, L"ERROR_NONPAGED_SYSTEM_RESOURCES"}, - {1452, L"ERROR_PAGED_SYSTEM_RESOURCES"}, - {1453, L"ERROR_WORKING_SET_QUOTA"}, - {1454, L"ERROR_PAGEFILE_QUOTA"}, - {1455, L"ERROR_COMMITMENT_LIMIT"}, - {1456, L"ERROR_MENU_ITEM_NOT_FOUND"}, - {1457, L"ERROR_INVALID_KEYBOARD_HANDLE"}, - {1458, L"ERROR_HOOK_TYPE_NOT_ALLOWED"}, - {1459, L"ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION"}, - {1460, L"ERROR_TIMEOUT"}, - {1461, L"ERROR_INVALID_MONITOR_HANDLE"}, - {1462, L"ERROR_INCORRECT_SIZE"}, - {1463, L"ERROR_SYMLINK_CLASS_DISABLED"}, - {1464, L"ERROR_SYMLINK_NOT_SUPPORTED"}, - {1465, L"ERROR_XML_PARSE_ERROR"}, - {1466, L"ERROR_XMLDSIG_ERROR"}, - {1467, L"ERROR_RESTART_APPLICATION"}, - {1468, L"ERROR_WRONG_COMPARTMENT"}, - {1469, L"ERROR_AUTHIP_FAILURE"}, - {1470, L"ERROR_NO_NVRAM_RESOURCES"}, - {1471, L"ERROR_NOT_GUI_PROCESS"}, - {1500, L"ERROR_EVENTLOG_FILE_CORRUPT"}, - {1501, L"ERROR_EVENTLOG_CANT_START"}, - {1502, L"ERROR_LOG_FILE_FULL"}, - {1503, L"ERROR_EVENTLOG_FILE_CHANGED"}, - {1550, L"ERROR_INVALID_TASK_NAME"}, - {1551, L"ERROR_INVALID_TASK_INDEX"}, - {1552, L"ERROR_THREAD_ALREADY_IN_TASK"}, - {1601, L"ERROR_INSTALL_SERVICE_FAILURE"}, - {1602, L"ERROR_INSTALL_USEREXIT"}, - {1603, L"ERROR_INSTALL_FAILURE"}, - {1604, L"ERROR_INSTALL_SUSPEND"}, - {1605, L"ERROR_UNKNOWN_PRODUCT"}, - {1606, L"ERROR_UNKNOWN_FEATURE"}, - {1607, L"ERROR_UNKNOWN_COMPONENT"}, - {1608, L"ERROR_UNKNOWN_PROPERTY"}, - {1609, L"ERROR_INVALID_HANDLE_STATE"}, - {1610, L"ERROR_BAD_CONFIGURATION"}, - {1611, L"ERROR_INDEX_ABSENT"}, - {1612, L"ERROR_INSTALL_SOURCE_ABSENT"}, - {1613, L"ERROR_INSTALL_PACKAGE_VERSION"}, - {1614, L"ERROR_PRODUCT_UNINSTALLED"}, - {1615, L"ERROR_BAD_QUERY_SYNTAX"}, - {1616, L"ERROR_INVALID_FIELD"}, - {1617, L"ERROR_DEVICE_REMOVED"}, - {1618, L"ERROR_INSTALL_ALREADY_RUNNING"}, - {1619, L"ERROR_INSTALL_PACKAGE_OPEN_FAILED"}, - {1620, L"ERROR_INSTALL_PACKAGE_INVALID"}, - {1621, L"ERROR_INSTALL_UI_FAILURE"}, - {1622, L"ERROR_INSTALL_LOG_FAILURE"}, - {1623, L"ERROR_INSTALL_LANGUAGE_UNSUPPORTED"}, - {1624, L"ERROR_INSTALL_TRANSFORM_FAILURE"}, - {1625, L"ERROR_INSTALL_PACKAGE_REJECTED"}, - {1626, L"ERROR_FUNCTION_NOT_CALLED"}, - {1627, L"ERROR_FUNCTION_FAILED"}, - {1628, L"ERROR_INVALID_TABLE"}, - {1629, L"ERROR_DATATYPE_MISMATCH"}, - {1630, L"ERROR_UNSUPPORTED_TYPE"}, - {1631, L"ERROR_CREATE_FAILED"}, - {1632, L"ERROR_INSTALL_TEMP_UNWRITABLE"}, - {1633, L"ERROR_INSTALL_PLATFORM_UNSUPPORTED"}, - {1634, L"ERROR_INSTALL_NOTUSED"}, - {1635, L"ERROR_PATCH_PACKAGE_OPEN_FAILED"}, - {1636, L"ERROR_PATCH_PACKAGE_INVALID"}, - {1637, L"ERROR_PATCH_PACKAGE_UNSUPPORTED"}, - {1638, L"ERROR_PRODUCT_VERSION"}, - {1639, L"ERROR_INVALID_COMMAND_LINE"}, - {1640, L"ERROR_INSTALL_REMOTE_DISALLOWED"}, - {1641, L"ERROR_SUCCESS_REBOOT_INITIATED"}, - {1642, L"ERROR_PATCH_TARGET_NOT_FOUND"}, - {1643, L"ERROR_PATCH_PACKAGE_REJECTED"}, - {1644, L"ERROR_INSTALL_TRANSFORM_REJECTED"}, - {1645, L"ERROR_INSTALL_REMOTE_PROHIBITED"}, - {1646, L"ERROR_PATCH_REMOVAL_UNSUPPORTED"}, - {1647, L"ERROR_UNKNOWN_PATCH"}, - {1648, L"ERROR_PATCH_NO_SEQUENCE"}, - {1649, L"ERROR_PATCH_REMOVAL_DISALLOWED"}, - {1650, L"ERROR_INVALID_PATCH_XML"}, - {1651, L"ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT"}, - {1652, L"ERROR_INSTALL_SERVICE_SAFEBOOT"}, - {1653, L"ERROR_FAIL_FAST_EXCEPTION"}, - {1654, L"ERROR_INSTALL_REJECTED"}, - {1700, L"RPC_S_INVALID_STRING_BINDING"}, - {1701, L"RPC_S_WRONG_KIND_OF_BINDING"}, - {1702, L"RPC_S_INVALID_BINDING"}, - {1703, L"RPC_S_PROTSEQ_NOT_SUPPORTED"}, - {1704, L"RPC_S_INVALID_RPC_PROTSEQ"}, - {1705, L"RPC_S_INVALID_STRING_UUID"}, - {1706, L"RPC_S_INVALID_ENDPOINT_FORMAT"}, - {1707, L"RPC_S_INVALID_NET_ADDR"}, - {1708, L"RPC_S_NO_ENDPOINT_FOUND"}, - {1709, L"RPC_S_INVALID_TIMEOUT"}, - {1710, L"RPC_S_OBJECT_NOT_FOUND"}, - {1711, L"RPC_S_ALREADY_REGISTERED"}, - {1712, L"RPC_S_TYPE_ALREADY_REGISTERED"}, - {1713, L"RPC_S_ALREADY_LISTENING"}, - {1714, L"RPC_S_NO_PROTSEQS_REGISTERED"}, - {1715, L"RPC_S_NOT_LISTENING"}, - {1716, L"RPC_S_UNKNOWN_MGR_TYPE"}, - {1717, L"RPC_S_UNKNOWN_IF"}, - {1718, L"RPC_S_NO_BINDINGS"}, - {1719, L"RPC_S_NO_PROTSEQS"}, - {1720, L"RPC_S_CANT_CREATE_ENDPOINT"}, - {1721, L"RPC_S_OUT_OF_RESOURCES"}, - {1722, L"RPC_S_SERVER_UNAVAILABLE"}, - {1723, L"RPC_S_SERVER_TOO_BUSY"}, - {1724, L"RPC_S_INVALID_NETWORK_OPTIONS"}, - {1725, L"RPC_S_NO_CALL_ACTIVE"}, - {1726, L"RPC_S_CALL_FAILED"}, - {1727, L"RPC_S_CALL_FAILED_DNE"}, - {1728, L"RPC_S_PROTOCOL_ERROR"}, - {1729, L"RPC_S_PROXY_ACCESS_DENIED"}, - {1730, L"RPC_S_UNSUPPORTED_TRANS_SYN"}, - {1732, L"RPC_S_UNSUPPORTED_TYPE"}, - {1733, L"RPC_S_INVALID_TAG"}, - {1734, L"RPC_S_INVALID_BOUND"}, - {1735, L"RPC_S_NO_ENTRY_NAME"}, - {1736, L"RPC_S_INVALID_NAME_SYNTAX"}, - {1737, L"RPC_S_UNSUPPORTED_NAME_SYNTAX"}, - {1739, L"RPC_S_UUID_NO_ADDRESS"}, - {1740, L"RPC_S_DUPLICATE_ENDPOINT"}, - {1741, L"RPC_S_UNKNOWN_AUTHN_TYPE"}, - {1742, L"RPC_S_MAX_CALLS_TOO_SMALL"}, - {1743, L"RPC_S_STRING_TOO_LONG"}, - {1744, L"RPC_S_PROTSEQ_NOT_FOUND"}, - {1745, L"RPC_S_PROCNUM_OUT_OF_RANGE"}, - {1746, L"RPC_S_BINDING_HAS_NO_AUTH"}, - {1747, L"RPC_S_UNKNOWN_AUTHN_SERVICE"}, - {1748, L"RPC_S_UNKNOWN_AUTHN_LEVEL"}, - {1749, L"RPC_S_INVALID_AUTH_IDENTITY"}, - {1750, L"RPC_S_UNKNOWN_AUTHZ_SERVICE"}, - {1751, L"EPT_S_INVALID_ENTRY"}, - {1752, L"EPT_S_CANT_PERFORM_OP"}, - {1753, L"EPT_S_NOT_REGISTERED"}, - {1754, L"RPC_S_NOTHING_TO_EXPORT"}, - {1755, L"RPC_S_INCOMPLETE_NAME"}, - {1756, L"RPC_S_INVALID_VERS_OPTION"}, - {1757, L"RPC_S_NO_MORE_MEMBERS"}, - {1758, L"RPC_S_NOT_ALL_OBJS_UNEXPORTED"}, - {1759, L"RPC_S_INTERFACE_NOT_FOUND"}, - {1760, L"RPC_S_ENTRY_ALREADY_EXISTS"}, - {1761, L"RPC_S_ENTRY_NOT_FOUND"}, - {1762, L"RPC_S_NAME_SERVICE_UNAVAILABLE"}, - {1763, L"RPC_S_INVALID_NAF_ID"}, - {1764, L"RPC_S_CANNOT_SUPPORT"}, - {1765, L"RPC_S_NO_CONTEXT_AVAILABLE"}, - {1766, L"RPC_S_INTERNAL_ERROR"}, - {1767, L"RPC_S_ZERO_DIVIDE"}, - {1768, L"RPC_S_ADDRESS_ERROR"}, - {1769, L"RPC_S_FP_DIV_ZERO"}, - {1770, L"RPC_S_FP_UNDERFLOW"}, - {1771, L"RPC_S_FP_OVERFLOW"}, - {1772, L"RPC_X_NO_MORE_ENTRIES"}, - {1773, L"RPC_X_SS_CHAR_TRANS_OPEN_FAIL"}, - {1774, L"RPC_X_SS_CHAR_TRANS_SHORT_FILE"}, - {1775, L"RPC_X_SS_IN_NULL_CONTEXT"}, - {1777, L"RPC_X_SS_CONTEXT_DAMAGED"}, - {1778, L"RPC_X_SS_HANDLES_MISMATCH"}, - {1779, L"RPC_X_SS_CANNOT_GET_CALL_HANDLE"}, - {1780, L"RPC_X_NULL_REF_POINTER"}, - {1781, L"RPC_X_ENUM_VALUE_OUT_OF_RANGE"}, - {1782, L"RPC_X_BYTE_COUNT_TOO_SMALL"}, - {1783, L"RPC_X_BAD_STUB_DATA"}, - {1784, L"ERROR_INVALID_USER_BUFFER"}, - {1785, L"ERROR_UNRECOGNIZED_MEDIA"}, - {1786, L"ERROR_NO_TRUST_LSA_SECRET"}, - {1787, L"ERROR_NO_TRUST_SAM_ACCOUNT"}, - {1788, L"ERROR_TRUSTED_DOMAIN_FAILURE"}, - {1789, L"ERROR_TRUSTED_RELATIONSHIP_FAILURE"}, - {1790, L"ERROR_TRUST_FAILURE"}, - {1791, L"RPC_S_CALL_IN_PROGRESS"}, - {1792, L"ERROR_NETLOGON_NOT_STARTED"}, - {1793, L"ERROR_ACCOUNT_EXPIRED"}, - {1794, L"ERROR_REDIRECTOR_HAS_OPEN_HANDLES"}, - {1795, L"ERROR_PRINTER_DRIVER_ALREADY_INSTALLED"}, - {1796, L"ERROR_UNKNOWN_PORT"}, - {1797, L"ERROR_UNKNOWN_PRINTER_DRIVER"}, - {1798, L"ERROR_UNKNOWN_PRINTPROCESSOR"}, - {1799, L"ERROR_INVALID_SEPARATOR_FILE"}, - {1800, L"ERROR_INVALID_PRIORITY"}, - {1801, L"ERROR_INVALID_PRINTER_NAME"}, - {1802, L"ERROR_PRINTER_ALREADY_EXISTS"}, - {1803, L"ERROR_INVALID_PRINTER_COMMAND"}, - {1804, L"ERROR_INVALID_DATATYPE"}, - {1805, L"ERROR_INVALID_ENVIRONMENT"}, - {1806, L"RPC_S_NO_MORE_BINDINGS"}, - {1807, L"ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"}, - {1808, L"ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT"}, - {1809, L"ERROR_NOLOGON_SERVER_TRUST_ACCOUNT"}, - {1810, L"ERROR_DOMAIN_TRUST_INCONSISTENT"}, - {1811, L"ERROR_SERVER_HAS_OPEN_HANDLES"}, - {1812, L"ERROR_RESOURCE_DATA_NOT_FOUND"}, - {1813, L"ERROR_RESOURCE_TYPE_NOT_FOUND"}, - {1814, L"ERROR_RESOURCE_NAME_NOT_FOUND"}, - {1815, L"ERROR_RESOURCE_LANG_NOT_FOUND"}, - {1816, L"ERROR_NOT_ENOUGH_QUOTA"}, - {1817, L"RPC_S_NO_INTERFACES"}, - {1818, L"RPC_S_CALL_CANCELLED"}, - {1819, L"RPC_S_BINDING_INCOMPLETE"}, - {1820, L"RPC_S_COMM_FAILURE"}, - {1821, L"RPC_S_UNSUPPORTED_AUTHN_LEVEL"}, - {1822, L"RPC_S_NO_PRINC_NAME"}, - {1823, L"RPC_S_NOT_RPC_ERROR"}, - {1824, L"RPC_S_UUID_LOCAL_ONLY"}, - {1825, L"RPC_S_SEC_PKG_ERROR"}, - {1826, L"RPC_S_NOT_CANCELLED"}, - {1827, L"RPC_X_INVALID_ES_ACTION"}, - {1828, L"RPC_X_WRONG_ES_VERSION"}, - {1829, L"RPC_X_WRONG_STUB_VERSION"}, - {1830, L"RPC_X_INVALID_PIPE_OBJECT"}, - {1831, L"RPC_X_WRONG_PIPE_ORDER"}, - {1832, L"RPC_X_WRONG_PIPE_VERSION"}, - {1833, L"RPC_S_COOKIE_AUTH_FAILED"}, - {1898, L"RPC_S_GROUP_MEMBER_NOT_FOUND"}, - {1899, L"EPT_S_CANT_CREATE"}, - {1900, L"RPC_S_INVALID_OBJECT"}, - {1901, L"ERROR_INVALID_TIME"}, - {1902, L"ERROR_INVALID_FORM_NAME"}, - {1903, L"ERROR_INVALID_FORM_SIZE"}, - {1904, L"ERROR_ALREADY_WAITING"}, - {1905, L"ERROR_PRINTER_DELETED"}, - {1906, L"ERROR_INVALID_PRINTER_STATE"}, - {1907, L"ERROR_PASSWORD_MUST_CHANGE"}, - {1908, L"ERROR_DOMAIN_CONTROLLER_NOT_FOUND"}, - {1909, L"ERROR_ACCOUNT_LOCKED_OUT"}, - {1910, L"OR_INVALID_OXID"}, - {1911, L"OR_INVALID_OID"}, - {1912, L"OR_INVALID_SET"}, - {1913, L"RPC_S_SEND_INCOMPLETE"}, - {1914, L"RPC_S_INVALID_ASYNC_HANDLE"}, - {1915, L"RPC_S_INVALID_ASYNC_CALL"}, - {1916, L"RPC_X_PIPE_CLOSED"}, - {1917, L"RPC_X_PIPE_DISCIPLINE_ERROR"}, - {1918, L"RPC_X_PIPE_EMPTY"}, - {1919, L"ERROR_NO_SITENAME"}, - {1920, L"ERROR_CANT_ACCESS_FILE"}, - {1921, L"ERROR_CANT_RESOLVE_FILENAME"}, - {1922, L"RPC_S_ENTRY_TYPE_MISMATCH"}, - {1923, L"RPC_S_NOT_ALL_OBJS_EXPORTED"}, - {1924, L"RPC_S_INTERFACE_NOT_EXPORTED"}, - {1925, L"RPC_S_PROFILE_NOT_ADDED"}, - {1926, L"RPC_S_PRF_ELT_NOT_ADDED"}, - {1927, L"RPC_S_PRF_ELT_NOT_REMOVED"}, - {1928, L"RPC_S_GRP_ELT_NOT_ADDED"}, - {1929, L"RPC_S_GRP_ELT_NOT_REMOVED"}, - {1930, L"ERROR_KM_DRIVER_BLOCKED"}, - {1931, L"ERROR_CONTEXT_EXPIRED"}, - {1932, L"ERROR_PER_USER_TRUST_QUOTA_EXCEEDED"}, - {1933, L"ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED"}, - {1934, L"ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED"}, - {1935, L"ERROR_AUTHENTICATION_FIREWALL_FAILED"}, - {1936, L"ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED"}, - {1937, L"ERROR_NTLM_BLOCKED"}, - {1938, L"ERROR_PASSWORD_CHANGE_REQUIRED"}, - {2000, L"ERROR_INVALID_PIXEL_FORMAT"}, - {2001, L"ERROR_BAD_DRIVER"}, - {2002, L"ERROR_INVALID_WINDOW_STYLE"}, - {2003, L"ERROR_METAFILE_NOT_SUPPORTED"}, - {2004, L"ERROR_TRANSFORM_NOT_SUPPORTED"}, - {2005, L"ERROR_CLIPPING_NOT_SUPPORTED"}, - {2010, L"ERROR_INVALID_CMM"}, - {2011, L"ERROR_INVALID_PROFILE"}, - {2012, L"ERROR_TAG_NOT_FOUND"}, - {2013, L"ERROR_TAG_NOT_PRESENT"}, - {2014, L"ERROR_DUPLICATE_TAG"}, - {2015, L"ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE"}, - {2016, L"ERROR_PROFILE_NOT_FOUND"}, - {2017, L"ERROR_INVALID_COLORSPACE"}, - {2018, L"ERROR_ICM_NOT_ENABLED"}, - {2019, L"ERROR_DELETING_ICM_XFORM"}, - {2020, L"ERROR_INVALID_TRANSFORM"}, - {2021, L"ERROR_COLORSPACE_MISMATCH"}, - {2022, L"ERROR_INVALID_COLORINDEX"}, - {2023, L"ERROR_PROFILE_DOES_NOT_MATCH_DEVICE"}, - {2108, L"ERROR_CONNECTED_OTHER_PASSWORD"}, - {2109, L"ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT"}, - {2202, L"ERROR_BAD_USERNAME"}, - {2250, L"ERROR_NOT_CONNECTED"}, - {2401, L"ERROR_OPEN_FILES"}, - {2402, L"ERROR_ACTIVE_CONNECTIONS"}, - {2404, L"ERROR_DEVICE_IN_USE"}, - {3000, L"ERROR_UNKNOWN_PRINT_MONITOR"}, - {3001, L"ERROR_PRINTER_DRIVER_IN_USE"}, - {3002, L"ERROR_SPOOL_FILE_NOT_FOUND"}, - {3003, L"ERROR_SPL_NO_STARTDOC"}, - {3004, L"ERROR_SPL_NO_ADDJOB"}, - {3005, L"ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED"}, - {3006, L"ERROR_PRINT_MONITOR_ALREADY_INSTALLED"}, - {3007, L"ERROR_INVALID_PRINT_MONITOR"}, - {3008, L"ERROR_PRINT_MONITOR_IN_USE"}, - {3009, L"ERROR_PRINTER_HAS_JOBS_QUEUED"}, - {3010, L"ERROR_SUCCESS_REBOOT_REQUIRED"}, - {3011, L"ERROR_SUCCESS_RESTART_REQUIRED"}, - {3012, L"ERROR_PRINTER_NOT_FOUND"}, - {3013, L"ERROR_PRINTER_DRIVER_WARNED"}, - {3014, L"ERROR_PRINTER_DRIVER_BLOCKED"}, - {3015, L"ERROR_PRINTER_DRIVER_PACKAGE_IN_USE"}, - {3016, L"ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND"}, - {3017, L"ERROR_FAIL_REBOOT_REQUIRED"}, - {3018, L"ERROR_FAIL_REBOOT_INITIATED"}, - {3019, L"ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED"}, - {3020, L"ERROR_PRINT_JOB_RESTART_REQUIRED"}, - {3021, L"ERROR_INVALID_PRINTER_DRIVER_MANIFEST"}, - {3022, L"ERROR_PRINTER_NOT_SHAREABLE"}, - {3050, L"ERROR_REQUEST_PAUSED"}, - {3950, L"ERROR_IO_REISSUE_AS_CACHED"}, - {4000, L"ERROR_WINS_INTERNAL"}, - {4001, L"ERROR_CAN_NOT_DEL_LOCAL_WINS"}, - {4002, L"ERROR_STATIC_INIT"}, - {4003, L"ERROR_INC_BACKUP"}, - {4004, L"ERROR_FULL_BACKUP"}, - {4005, L"ERROR_REC_NON_EXISTENT"}, - {4006, L"ERROR_RPL_NOT_ALLOWED"}, - {4050, L"PEERDIST_ERROR_CONTENTINFO_VERSION_UNSUPPORTED"}, - {4051, L"PEERDIST_ERROR_CANNOT_PARSE_CONTENTINFO"}, - {4052, L"PEERDIST_ERROR_MISSING_DATA"}, - {4053, L"PEERDIST_ERROR_NO_MORE"}, - {4054, L"PEERDIST_ERROR_NOT_INITIALIZED"}, - {4055, L"PEERDIST_ERROR_ALREADY_INITIALIZED"}, - {4056, L"PEERDIST_ERROR_SHUTDOWN_IN_PROGRESS"}, - {4057, L"PEERDIST_ERROR_INVALIDATED"}, - {4058, L"PEERDIST_ERROR_ALREADY_EXISTS"}, - {4059, L"PEERDIST_ERROR_OPERATION_NOTFOUND"}, - {4060, L"PEERDIST_ERROR_ALREADY_COMPLETED"}, - {4061, L"PEERDIST_ERROR_OUT_OF_BOUNDS"}, - {4062, L"PEERDIST_ERROR_VERSION_UNSUPPORTED"}, - {4063, L"PEERDIST_ERROR_INVALID_CONFIGURATION"}, - {4064, L"PEERDIST_ERROR_NOT_LICENSED"}, - {4065, L"PEERDIST_ERROR_SERVICE_UNAVAILABLE"}, - {4066, L"PEERDIST_ERROR_TRUST_FAILURE"}, - {4100, L"ERROR_DHCP_ADDRESS_CONFLICT"}, - {4200, L"ERROR_WMI_GUID_NOT_FOUND"}, - {4201, L"ERROR_WMI_INSTANCE_NOT_FOUND"}, - {4202, L"ERROR_WMI_ITEMID_NOT_FOUND"}, - {4203, L"ERROR_WMI_TRY_AGAIN"}, - {4204, L"ERROR_WMI_DP_NOT_FOUND"}, - {4205, L"ERROR_WMI_UNRESOLVED_INSTANCE_REF"}, - {4206, L"ERROR_WMI_ALREADY_ENABLED"}, - {4207, L"ERROR_WMI_GUID_DISCONNECTED"}, - {4208, L"ERROR_WMI_SERVER_UNAVAILABLE"}, - {4209, L"ERROR_WMI_DP_FAILED"}, - {4210, L"ERROR_WMI_INVALID_MOF"}, - {4211, L"ERROR_WMI_INVALID_REGINFO"}, - {4212, L"ERROR_WMI_ALREADY_DISABLED"}, - {4213, L"ERROR_WMI_READ_ONLY"}, - {4214, L"ERROR_WMI_SET_FAILURE"}, - {4250, L"ERROR_NOT_APPCONTAINER"}, - {4251, L"ERROR_APPCONTAINER_REQUIRED"}, - {4252, L"ERROR_NOT_SUPPORTED_IN_APPCONTAINER"}, - {4253, L"ERROR_INVALID_PACKAGE_SID_LENGTH"}, - {4300, L"ERROR_INVALID_MEDIA"}, - {4301, L"ERROR_INVALID_LIBRARY"}, - {4302, L"ERROR_INVALID_MEDIA_POOL"}, - {4303, L"ERROR_DRIVE_MEDIA_MISMATCH"}, - {4304, L"ERROR_MEDIA_OFFLINE"}, - {4305, L"ERROR_LIBRARY_OFFLINE"}, - {4306, L"ERROR_EMPTY"}, - {4307, L"ERROR_NOT_EMPTY"}, - {4308, L"ERROR_MEDIA_UNAVAILABLE"}, - {4309, L"ERROR_RESOURCE_DISABLED"}, - {4310, L"ERROR_INVALID_CLEANER"}, - {4311, L"ERROR_UNABLE_TO_CLEAN"}, - {4312, L"ERROR_OBJECT_NOT_FOUND"}, - {4313, L"ERROR_DATABASE_FAILURE"}, - {4314, L"ERROR_DATABASE_FULL"}, - {4315, L"ERROR_MEDIA_INCOMPATIBLE"}, - {4316, L"ERROR_RESOURCE_NOT_PRESENT"}, - {4317, L"ERROR_INVALID_OPERATION"}, - {4318, L"ERROR_MEDIA_NOT_AVAILABLE"}, - {4319, L"ERROR_DEVICE_NOT_AVAILABLE"}, - {4320, L"ERROR_REQUEST_REFUSED"}, - {4321, L"ERROR_INVALID_DRIVE_OBJECT"}, - {4322, L"ERROR_LIBRARY_FULL"}, - {4323, L"ERROR_MEDIUM_NOT_ACCESSIBLE"}, - {4324, L"ERROR_UNABLE_TO_LOAD_MEDIUM"}, - {4325, L"ERROR_UNABLE_TO_INVENTORY_DRIVE"}, - {4326, L"ERROR_UNABLE_TO_INVENTORY_SLOT"}, - {4327, L"ERROR_UNABLE_TO_INVENTORY_TRANSPORT"}, - {4328, L"ERROR_TRANSPORT_FULL"}, - {4329, L"ERROR_CONTROLLING_IEPORT"}, - {4330, L"ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA"}, - {4331, L"ERROR_CLEANER_SLOT_SET"}, - {4332, L"ERROR_CLEANER_SLOT_NOT_SET"}, - {4333, L"ERROR_CLEANER_CARTRIDGE_SPENT"}, - {4334, L"ERROR_UNEXPECTED_OMID"}, - {4335, L"ERROR_CANT_DELETE_LAST_ITEM"}, - {4336, L"ERROR_MESSAGE_EXCEEDS_MAX_SIZE"}, - {4337, L"ERROR_VOLUME_CONTAINS_SYS_FILES"}, - {4338, L"ERROR_INDIGENOUS_TYPE"}, - {4339, L"ERROR_NO_SUPPORTING_DRIVES"}, - {4340, L"ERROR_CLEANER_CARTRIDGE_INSTALLED"}, - {4341, L"ERROR_IEPORT_FULL"}, - {4350, L"ERROR_FILE_OFFLINE"}, - {4351, L"ERROR_REMOTE_STORAGE_NOT_ACTIVE"}, - {4352, L"ERROR_REMOTE_STORAGE_MEDIA_ERROR"}, - {4390, L"ERROR_NOT_A_REPARSE_POINT"}, - {4391, L"ERROR_REPARSE_ATTRIBUTE_CONFLICT"}, - {4392, L"ERROR_INVALID_REPARSE_DATA"}, - {4393, L"ERROR_REPARSE_TAG_INVALID"}, - {4394, L"ERROR_REPARSE_TAG_MISMATCH"}, - {4400, L"ERROR_APP_DATA_NOT_FOUND"}, - {4401, L"ERROR_APP_DATA_EXPIRED"}, - {4402, L"ERROR_APP_DATA_CORRUPT"}, - {4403, L"ERROR_APP_DATA_LIMIT_EXCEEDED"}, - {4404, L"ERROR_APP_DATA_REBOOT_REQUIRED"}, - {4420, L"ERROR_SECUREBOOT_ROLLBACK_DETECTED"}, - {4421, L"ERROR_SECUREBOOT_POLICY_VIOLATION"}, - {4422, L"ERROR_SECUREBOOT_INVALID_POLICY"}, - {4423, L"ERROR_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND"}, - {4424, L"ERROR_SECUREBOOT_POLICY_NOT_SIGNED"}, - {4425, L"ERROR_SECUREBOOT_NOT_ENABLED"}, - {4426, L"ERROR_SECUREBOOT_FILE_REPLACED"}, - {4440, L"ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED"}, - {4441, L"ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED"}, - {4442, L"ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED"}, - {4443, L"ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED"}, - {4500, L"ERROR_VOLUME_NOT_SIS_ENABLED"}, - {5001, L"ERROR_DEPENDENT_RESOURCE_EXISTS"}, - {5002, L"ERROR_DEPENDENCY_NOT_FOUND"}, - {5003, L"ERROR_DEPENDENCY_ALREADY_EXISTS"}, - {5004, L"ERROR_RESOURCE_NOT_ONLINE"}, - {5005, L"ERROR_HOST_NODE_NOT_AVAILABLE"}, - {5006, L"ERROR_RESOURCE_NOT_AVAILABLE"}, - {5007, L"ERROR_RESOURCE_NOT_FOUND"}, - {5008, L"ERROR_SHUTDOWN_CLUSTER"}, - {5009, L"ERROR_CANT_EVICT_ACTIVE_NODE"}, - {5010, L"ERROR_OBJECT_ALREADY_EXISTS"}, - {5011, L"ERROR_OBJECT_IN_LIST"}, - {5012, L"ERROR_GROUP_NOT_AVAILABLE"}, - {5013, L"ERROR_GROUP_NOT_FOUND"}, - {5014, L"ERROR_GROUP_NOT_ONLINE"}, - {5015, L"ERROR_HOST_NODE_NOT_RESOURCE_OWNER"}, - {5016, L"ERROR_HOST_NODE_NOT_GROUP_OWNER"}, - {5017, L"ERROR_RESMON_CREATE_FAILED"}, - {5018, L"ERROR_RESMON_ONLINE_FAILED"}, - {5019, L"ERROR_RESOURCE_ONLINE"}, - {5020, L"ERROR_QUORUM_RESOURCE"}, - {5021, L"ERROR_NOT_QUORUM_CAPABLE"}, - {5022, L"ERROR_CLUSTER_SHUTTING_DOWN"}, - {5023, L"ERROR_INVALID_STATE"}, - {5024, L"ERROR_RESOURCE_PROPERTIES_STORED"}, - {5025, L"ERROR_NOT_QUORUM_CLASS"}, - {5026, L"ERROR_CORE_RESOURCE"}, - {5027, L"ERROR_QUORUM_RESOURCE_ONLINE_FAILED"}, - {5028, L"ERROR_QUORUMLOG_OPEN_FAILED"}, - {5029, L"ERROR_CLUSTERLOG_CORRUPT"}, - {5030, L"ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE"}, - {5031, L"ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE"}, - {5032, L"ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND"}, - {5033, L"ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE"}, - {5034, L"ERROR_QUORUM_OWNER_ALIVE"}, - {5035, L"ERROR_NETWORK_NOT_AVAILABLE"}, - {5036, L"ERROR_NODE_NOT_AVAILABLE"}, - {5037, L"ERROR_ALL_NODES_NOT_AVAILABLE"}, - {5038, L"ERROR_RESOURCE_FAILED"}, - {5039, L"ERROR_CLUSTER_INVALID_NODE"}, - {5040, L"ERROR_CLUSTER_NODE_EXISTS"}, - {5041, L"ERROR_CLUSTER_JOIN_IN_PROGRESS"}, - {5042, L"ERROR_CLUSTER_NODE_NOT_FOUND"}, - {5043, L"ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND"}, - {5044, L"ERROR_CLUSTER_NETWORK_EXISTS"}, - {5045, L"ERROR_CLUSTER_NETWORK_NOT_FOUND"}, - {5046, L"ERROR_CLUSTER_NETINTERFACE_EXISTS"}, - {5047, L"ERROR_CLUSTER_NETINTERFACE_NOT_FOUND"}, - {5048, L"ERROR_CLUSTER_INVALID_REQUEST"}, - {5049, L"ERROR_CLUSTER_INVALID_NETWORK_PROVIDER"}, - {5050, L"ERROR_CLUSTER_NODE_DOWN"}, - {5051, L"ERROR_CLUSTER_NODE_UNREACHABLE"}, - {5052, L"ERROR_CLUSTER_NODE_NOT_MEMBER"}, - {5053, L"ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS"}, - {5054, L"ERROR_CLUSTER_INVALID_NETWORK"}, - {5056, L"ERROR_CLUSTER_NODE_UP"}, - {5057, L"ERROR_CLUSTER_IPADDR_IN_USE"}, - {5058, L"ERROR_CLUSTER_NODE_NOT_PAUSED"}, - {5059, L"ERROR_CLUSTER_NO_SECURITY_CONTEXT"}, - {5060, L"ERROR_CLUSTER_NETWORK_NOT_INTERNAL"}, - {5061, L"ERROR_CLUSTER_NODE_ALREADY_UP"}, - {5062, L"ERROR_CLUSTER_NODE_ALREADY_DOWN"}, - {5063, L"ERROR_CLUSTER_NETWORK_ALREADY_ONLINE"}, - {5064, L"ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE"}, - {5065, L"ERROR_CLUSTER_NODE_ALREADY_MEMBER"}, - {5066, L"ERROR_CLUSTER_LAST_INTERNAL_NETWORK"}, - {5067, L"ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS"}, - {5068, L"ERROR_INVALID_OPERATION_ON_QUORUM"}, - {5069, L"ERROR_DEPENDENCY_NOT_ALLOWED"}, - {5070, L"ERROR_CLUSTER_NODE_PAUSED"}, - {5071, L"ERROR_NODE_CANT_HOST_RESOURCE"}, - {5072, L"ERROR_CLUSTER_NODE_NOT_READY"}, - {5073, L"ERROR_CLUSTER_NODE_SHUTTING_DOWN"}, - {5074, L"ERROR_CLUSTER_JOIN_ABORTED"}, - {5075, L"ERROR_CLUSTER_INCOMPATIBLE_VERSIONS"}, - {5076, L"ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED"}, - {5077, L"ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED"}, - {5078, L"ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND"}, - {5079, L"ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED"}, - {5080, L"ERROR_CLUSTER_RESNAME_NOT_FOUND"}, - {5081, L"ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED"}, - {5082, L"ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST"}, - {5083, L"ERROR_CLUSTER_DATABASE_SEQMISMATCH"}, - {5084, L"ERROR_RESMON_INVALID_STATE"}, - {5085, L"ERROR_CLUSTER_GUM_NOT_LOCKER"}, - {5086, L"ERROR_QUORUM_DISK_NOT_FOUND"}, - {5087, L"ERROR_DATABASE_BACKUP_CORRUPT"}, - {5088, L"ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT"}, - {5089, L"ERROR_RESOURCE_PROPERTY_UNCHANGEABLE"}, - {5890, L"ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE"}, - {5891, L"ERROR_CLUSTER_QUORUMLOG_NOT_FOUND"}, - {5892, L"ERROR_CLUSTER_MEMBERSHIP_HALT"}, - {5893, L"ERROR_CLUSTER_INSTANCE_ID_MISMATCH"}, - {5894, L"ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP"}, - {5895, L"ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH"}, - {5896, L"ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP"}, - {5897, L"ERROR_CLUSTER_PARAMETER_MISMATCH"}, - {5898, L"ERROR_NODE_CANNOT_BE_CLUSTERED"}, - {5899, L"ERROR_CLUSTER_WRONG_OS_VERSION"}, - {5900, L"ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME"}, - {5901, L"ERROR_CLUSCFG_ALREADY_COMMITTED"}, - {5902, L"ERROR_CLUSCFG_ROLLBACK_FAILED"}, - {5903, L"ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT"}, - {5904, L"ERROR_CLUSTER_OLD_VERSION"}, - {5905, L"ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME"}, - {5906, L"ERROR_CLUSTER_NO_NET_ADAPTERS"}, - {5907, L"ERROR_CLUSTER_POISONED"}, - {5908, L"ERROR_CLUSTER_GROUP_MOVING"}, - {5909, L"ERROR_CLUSTER_RESOURCE_TYPE_BUSY"}, - {5910, L"ERROR_RESOURCE_CALL_TIMED_OUT"}, - {5911, L"ERROR_INVALID_CLUSTER_IPV6_ADDRESS"}, - {5912, L"ERROR_CLUSTER_INTERNAL_INVALID_FUNCTION"}, - {5913, L"ERROR_CLUSTER_PARAMETER_OUT_OF_BOUNDS"}, - {5914, L"ERROR_CLUSTER_PARTIAL_SEND"}, - {5915, L"ERROR_CLUSTER_REGISTRY_INVALID_FUNCTION"}, - {5916, L"ERROR_CLUSTER_INVALID_STRING_TERMINATION"}, - {5917, L"ERROR_CLUSTER_INVALID_STRING_FORMAT"}, - {5918, L"ERROR_CLUSTER_DATABASE_TRANSACTION_IN_PROGRESS"}, - {5919, L"ERROR_CLUSTER_DATABASE_TRANSACTION_NOT_IN_PROGRESS"}, - {5920, L"ERROR_CLUSTER_NULL_DATA"}, - {5921, L"ERROR_CLUSTER_PARTIAL_READ"}, - {5922, L"ERROR_CLUSTER_PARTIAL_WRITE"}, - {5923, L"ERROR_CLUSTER_CANT_DESERIALIZE_DATA"}, - {5924, L"ERROR_DEPENDENT_RESOURCE_PROPERTY_CONFLICT"}, - {5925, L"ERROR_CLUSTER_NO_QUORUM"}, - {5926, L"ERROR_CLUSTER_INVALID_IPV6_NETWORK"}, - {5927, L"ERROR_CLUSTER_INVALID_IPV6_TUNNEL_NETWORK"}, - {5928, L"ERROR_QUORUM_NOT_ALLOWED_IN_THIS_GROUP"}, - {5929, L"ERROR_DEPENDENCY_TREE_TOO_COMPLEX"}, - {5930, L"ERROR_EXCEPTION_IN_RESOURCE_CALL"}, - {5931, L"ERROR_CLUSTER_RHS_FAILED_INITIALIZATION"}, - {5932, L"ERROR_CLUSTER_NOT_INSTALLED"}, - {5933, L"ERROR_CLUSTER_RESOURCES_MUST_BE_ONLINE_ON_THE_SAME_NODE"}, - {5934, L"ERROR_CLUSTER_MAX_NODES_IN_CLUSTER"}, - {5935, L"ERROR_CLUSTER_TOO_MANY_NODES"}, - {5936, L"ERROR_CLUSTER_OBJECT_ALREADY_USED"}, - {5937, L"ERROR_NONCORE_GROUPS_FOUND"}, - {5938, L"ERROR_FILE_SHARE_RESOURCE_CONFLICT"}, - {5939, L"ERROR_CLUSTER_EVICT_INVALID_REQUEST"}, - {5940, L"ERROR_CLUSTER_SINGLETON_RESOURCE"}, - {5941, L"ERROR_CLUSTER_GROUP_SINGLETON_RESOURCE"}, - {5942, L"ERROR_CLUSTER_RESOURCE_PROVIDER_FAILED"}, - {5943, L"ERROR_CLUSTER_RESOURCE_CONFIGURATION_ERROR"}, - {5944, L"ERROR_CLUSTER_GROUP_BUSY"}, - {5945, L"ERROR_CLUSTER_NOT_SHARED_VOLUME"}, - {5946, L"ERROR_CLUSTER_INVALID_SECURITY_DESCRIPTOR"}, - {5947, L"ERROR_CLUSTER_SHARED_VOLUMES_IN_USE"}, - {5948, L"ERROR_CLUSTER_USE_SHARED_VOLUMES_API"}, - {5949, L"ERROR_CLUSTER_BACKUP_IN_PROGRESS"}, - {5950, L"ERROR_NON_CSV_PATH"}, - {5951, L"ERROR_CSV_VOLUME_NOT_LOCAL"}, - {5952, L"ERROR_CLUSTER_WATCHDOG_TERMINATING"}, - {5953, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_INCOMPATIBLE_NODES"}, - {5954, L"ERROR_CLUSTER_INVALID_NODE_WEIGHT"}, - {5955, L"ERROR_CLUSTER_RESOURCE_VETOED_CALL"}, - {5956, L"ERROR_RESMON_SYSTEM_RESOURCES_LACKING"}, - {5957, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_DESTINATION"}, - {5958, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_SOURCE"}, - {5959, L"ERROR_CLUSTER_GROUP_QUEUED"}, - {5960, L"ERROR_CLUSTER_RESOURCE_LOCKED_STATUS"}, - {5961, L"ERROR_CLUSTER_SHARED_VOLUME_FAILOVER_NOT_ALLOWED"}, - {5962, L"ERROR_CLUSTER_NODE_DRAIN_IN_PROGRESS"}, - {5963, L"ERROR_CLUSTER_DISK_NOT_CONNECTED"}, - {5964, L"ERROR_DISK_NOT_CSV_CAPABLE"}, - {5965, L"ERROR_RESOURCE_NOT_IN_AVAILABLE_STORAGE"}, - {5966, L"ERROR_CLUSTER_SHARED_VOLUME_REDIRECTED"}, - {5967, L"ERROR_CLUSTER_SHARED_VOLUME_NOT_REDIRECTED"}, - {5968, L"ERROR_CLUSTER_CANNOT_RETURN_PROPERTIES"}, - {5969, L"ERROR_CLUSTER_RESOURCE_CONTAINS_UNSUPPORTED_DIFF_AREA_FOR_SHARED_VOLUMES"}, - {5970, L"ERROR_CLUSTER_RESOURCE_IS_IN_MAINTENANCE_MODE"}, - {5971, L"ERROR_CLUSTER_AFFINITY_CONFLICT"}, - {5972, L"ERROR_CLUSTER_RESOURCE_IS_REPLICA_VIRTUAL_MACHINE"}, - {6000, L"ERROR_ENCRYPTION_FAILED"}, - {6001, L"ERROR_DECRYPTION_FAILED"}, - {6002, L"ERROR_FILE_ENCRYPTED"}, - {6003, L"ERROR_NO_RECOVERY_POLICY"}, - {6004, L"ERROR_NO_EFS"}, - {6005, L"ERROR_WRONG_EFS"}, - {6006, L"ERROR_NO_USER_KEYS"}, - {6007, L"ERROR_FILE_NOT_ENCRYPTED"}, - {6008, L"ERROR_NOT_EXPORT_FORMAT"}, - {6009, L"ERROR_FILE_READ_ONLY"}, - {6010, L"ERROR_DIR_EFS_DISALLOWED"}, - {6011, L"ERROR_EFS_SERVER_NOT_TRUSTED"}, - {6012, L"ERROR_BAD_RECOVERY_POLICY"}, - {6013, L"ERROR_EFS_ALG_BLOB_TOO_BIG"}, - {6014, L"ERROR_VOLUME_NOT_SUPPORT_EFS"}, - {6015, L"ERROR_EFS_DISABLED"}, - {6016, L"ERROR_EFS_VERSION_NOT_SUPPORT"}, - {6017, L"ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE"}, - {6018, L"ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER"}, - {6019, L"ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE"}, - {6020, L"ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE"}, - {6021, L"ERROR_CS_ENCRYPTION_FILE_NOT_CSE"}, - {6022, L"ERROR_ENCRYPTION_POLICY_DENIES_OPERATION"}, - {6118, L"ERROR_NO_BROWSER_SERVERS_FOUND"}, - {6200, L"SCHED_E_SERVICE_NOT_LOCALSYSTEM"}, - {6600, L"ERROR_LOG_SECTOR_INVALID"}, - {6601, L"ERROR_LOG_SECTOR_PARITY_INVALID"}, - {6602, L"ERROR_LOG_SECTOR_REMAPPED"}, - {6603, L"ERROR_LOG_BLOCK_INCOMPLETE"}, - {6604, L"ERROR_LOG_INVALID_RANGE"}, - {6605, L"ERROR_LOG_BLOCKS_EXHAUSTED"}, - {6606, L"ERROR_LOG_READ_CONTEXT_INVALID"}, - {6607, L"ERROR_LOG_RESTART_INVALID"}, - {6608, L"ERROR_LOG_BLOCK_VERSION"}, - {6609, L"ERROR_LOG_BLOCK_INVALID"}, - {6610, L"ERROR_LOG_READ_MODE_INVALID"}, - {6611, L"ERROR_LOG_NO_RESTART"}, - {6612, L"ERROR_LOG_METADATA_CORRUPT"}, - {6613, L"ERROR_LOG_METADATA_INVALID"}, - {6614, L"ERROR_LOG_METADATA_INCONSISTENT"}, - {6615, L"ERROR_LOG_RESERVATION_INVALID"}, - {6616, L"ERROR_LOG_CANT_DELETE"}, - {6617, L"ERROR_LOG_CONTAINER_LIMIT_EXCEEDED"}, - {6618, L"ERROR_LOG_START_OF_LOG"}, - {6619, L"ERROR_LOG_POLICY_ALREADY_INSTALLED"}, - {6620, L"ERROR_LOG_POLICY_NOT_INSTALLED"}, - {6621, L"ERROR_LOG_POLICY_INVALID"}, - {6622, L"ERROR_LOG_POLICY_CONFLICT"}, - {6623, L"ERROR_LOG_PINNED_ARCHIVE_TAIL"}, - {6624, L"ERROR_LOG_RECORD_NONEXISTENT"}, - {6625, L"ERROR_LOG_RECORDS_RESERVED_INVALID"}, - {6626, L"ERROR_LOG_SPACE_RESERVED_INVALID"}, - {6627, L"ERROR_LOG_TAIL_INVALID"}, - {6628, L"ERROR_LOG_FULL"}, - {6629, L"ERROR_COULD_NOT_RESIZE_LOG"}, - {6630, L"ERROR_LOG_MULTIPLEXED"}, - {6631, L"ERROR_LOG_DEDICATED"}, - {6632, L"ERROR_LOG_ARCHIVE_NOT_IN_PROGRESS"}, - {6633, L"ERROR_LOG_ARCHIVE_IN_PROGRESS"}, - {6634, L"ERROR_LOG_EPHEMERAL"}, - {6635, L"ERROR_LOG_NOT_ENOUGH_CONTAINERS"}, - {6636, L"ERROR_LOG_CLIENT_ALREADY_REGISTERED"}, - {6637, L"ERROR_LOG_CLIENT_NOT_REGISTERED"}, - {6638, L"ERROR_LOG_FULL_HANDLER_IN_PROGRESS"}, - {6639, L"ERROR_LOG_CONTAINER_READ_FAILED"}, - {6640, L"ERROR_LOG_CONTAINER_WRITE_FAILED"}, - {6641, L"ERROR_LOG_CONTAINER_OPEN_FAILED"}, - {6642, L"ERROR_LOG_CONTAINER_STATE_INVALID"}, - {6643, L"ERROR_LOG_STATE_INVALID"}, - {6644, L"ERROR_LOG_PINNED"}, - {6645, L"ERROR_LOG_METADATA_FLUSH_FAILED"}, - {6646, L"ERROR_LOG_INCONSISTENT_SECURITY"}, - {6647, L"ERROR_LOG_APPENDED_FLUSH_FAILED"}, - {6648, L"ERROR_LOG_PINNED_RESERVATION"}, - {6700, L"ERROR_INVALID_TRANSACTION"}, - {6701, L"ERROR_TRANSACTION_NOT_ACTIVE"}, - {6702, L"ERROR_TRANSACTION_REQUEST_NOT_VALID"}, - {6703, L"ERROR_TRANSACTION_NOT_REQUESTED"}, - {6704, L"ERROR_TRANSACTION_ALREADY_ABORTED"}, - {6705, L"ERROR_TRANSACTION_ALREADY_COMMITTED"}, - {6706, L"ERROR_TM_INITIALIZATION_FAILED"}, - {6707, L"ERROR_RESOURCEMANAGER_READ_ONLY"}, - {6708, L"ERROR_TRANSACTION_NOT_JOINED"}, - {6709, L"ERROR_TRANSACTION_SUPERIOR_EXISTS"}, - {6710, L"ERROR_CRM_PROTOCOL_ALREADY_EXISTS"}, - {6711, L"ERROR_TRANSACTION_PROPAGATION_FAILED"}, - {6712, L"ERROR_CRM_PROTOCOL_NOT_FOUND"}, - {6713, L"ERROR_TRANSACTION_INVALID_MARSHALL_BUFFER"}, - {6714, L"ERROR_CURRENT_TRANSACTION_NOT_VALID"}, - {6715, L"ERROR_TRANSACTION_NOT_FOUND"}, - {6716, L"ERROR_RESOURCEMANAGER_NOT_FOUND"}, - {6717, L"ERROR_ENLISTMENT_NOT_FOUND"}, - {6718, L"ERROR_TRANSACTIONMANAGER_NOT_FOUND"}, - {6719, L"ERROR_TRANSACTIONMANAGER_NOT_ONLINE"}, - {6720, L"ERROR_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION"}, - {6721, L"ERROR_TRANSACTION_NOT_ROOT"}, - {6722, L"ERROR_TRANSACTION_OBJECT_EXPIRED"}, - {6723, L"ERROR_TRANSACTION_RESPONSE_NOT_ENLISTED"}, - {6724, L"ERROR_TRANSACTION_RECORD_TOO_LONG"}, - {6725, L"ERROR_IMPLICIT_TRANSACTION_NOT_SUPPORTED"}, - {6726, L"ERROR_TRANSACTION_INTEGRITY_VIOLATED"}, - {6727, L"ERROR_TRANSACTIONMANAGER_IDENTITY_MISMATCH"}, - {6728, L"ERROR_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT"}, - {6729, L"ERROR_TRANSACTION_MUST_WRITETHROUGH"}, - {6730, L"ERROR_TRANSACTION_NO_SUPERIOR"}, - {6731, L"ERROR_HEURISTIC_DAMAGE_POSSIBLE"}, - {6800, L"ERROR_TRANSACTIONAL_CONFLICT"}, - {6801, L"ERROR_RM_NOT_ACTIVE"}, - {6802, L"ERROR_RM_METADATA_CORRUPT"}, - {6803, L"ERROR_DIRECTORY_NOT_RM"}, - {6805, L"ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE"}, - {6806, L"ERROR_LOG_RESIZE_INVALID_SIZE"}, - {6807, L"ERROR_OBJECT_NO_LONGER_EXISTS"}, - {6808, L"ERROR_STREAM_MINIVERSION_NOT_FOUND"}, - {6809, L"ERROR_STREAM_MINIVERSION_NOT_VALID"}, - {6810, L"ERROR_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION"}, - {6811, L"ERROR_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT"}, - {6812, L"ERROR_CANT_CREATE_MORE_STREAM_MINIVERSIONS"}, - {6814, L"ERROR_REMOTE_FILE_VERSION_MISMATCH"}, - {6815, L"ERROR_HANDLE_NO_LONGER_VALID"}, - {6816, L"ERROR_NO_TXF_METADATA"}, - {6817, L"ERROR_LOG_CORRUPTION_DETECTED"}, - {6818, L"ERROR_CANT_RECOVER_WITH_HANDLE_OPEN"}, - {6819, L"ERROR_RM_DISCONNECTED"}, - {6820, L"ERROR_ENLISTMENT_NOT_SUPERIOR"}, - {6821, L"ERROR_RECOVERY_NOT_NEEDED"}, - {6822, L"ERROR_RM_ALREADY_STARTED"}, - {6823, L"ERROR_FILE_IDENTITY_NOT_PERSISTENT"}, - {6824, L"ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCY"}, - {6825, L"ERROR_CANT_CROSS_RM_BOUNDARY"}, - {6826, L"ERROR_TXF_DIR_NOT_EMPTY"}, - {6827, L"ERROR_INDOUBT_TRANSACTIONS_EXIST"}, - {6828, L"ERROR_TM_VOLATILE"}, - {6829, L"ERROR_ROLLBACK_TIMER_EXPIRED"}, - {6830, L"ERROR_TXF_ATTRIBUTE_CORRUPT"}, - {6831, L"ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION"}, - {6832, L"ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED"}, - {6833, L"ERROR_LOG_GROWTH_FAILED"}, - {6834, L"ERROR_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE"}, - {6835, L"ERROR_TXF_METADATA_ALREADY_PRESENT"}, - {6836, L"ERROR_TRANSACTION_SCOPE_CALLBACKS_NOT_SET"}, - {6837, L"ERROR_TRANSACTION_REQUIRED_PROMOTION"}, - {6838, L"ERROR_CANNOT_EXECUTE_FILE_IN_TRANSACTION"}, - {6839, L"ERROR_TRANSACTIONS_NOT_FROZEN"}, - {6840, L"ERROR_TRANSACTION_FREEZE_IN_PROGRESS"}, - {6841, L"ERROR_NOT_SNAPSHOT_VOLUME"}, - {6842, L"ERROR_NO_SAVEPOINT_WITH_OPEN_FILES"}, - {6843, L"ERROR_DATA_LOST_REPAIR"}, - {6844, L"ERROR_SPARSE_NOT_ALLOWED_IN_TRANSACTION"}, - {6845, L"ERROR_TM_IDENTITY_MISMATCH"}, - {6846, L"ERROR_FLOATED_SECTION"}, - {6847, L"ERROR_CANNOT_ACCEPT_TRANSACTED_WORK"}, - {6848, L"ERROR_CANNOT_ABORT_TRANSACTIONS"}, - {6849, L"ERROR_BAD_CLUSTERS"}, - {6850, L"ERROR_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION"}, - {6851, L"ERROR_VOLUME_DIRTY"}, - {6852, L"ERROR_NO_LINK_TRACKING_IN_TRANSACTION"}, - {6853, L"ERROR_OPERATION_NOT_SUPPORTED_IN_TRANSACTION"}, - {6854, L"ERROR_EXPIRED_HANDLE"}, - {6855, L"ERROR_TRANSACTION_NOT_ENLISTED"}, - {7001, L"ERROR_CTX_WINSTATION_NAME_INVALID"}, - {7002, L"ERROR_CTX_INVALID_PD"}, - {7003, L"ERROR_CTX_PD_NOT_FOUND"}, - {7004, L"ERROR_CTX_WD_NOT_FOUND"}, - {7005, L"ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY"}, - {7006, L"ERROR_CTX_SERVICE_NAME_COLLISION"}, - {7007, L"ERROR_CTX_CLOSE_PENDING"}, - {7008, L"ERROR_CTX_NO_OUTBUF"}, - {7009, L"ERROR_CTX_MODEM_INF_NOT_FOUND"}, - {7010, L"ERROR_CTX_INVALID_MODEMNAME"}, - {7011, L"ERROR_CTX_MODEM_RESPONSE_ERROR"}, - {7012, L"ERROR_CTX_MODEM_RESPONSE_TIMEOUT"}, - {7013, L"ERROR_CTX_MODEM_RESPONSE_NO_CARRIER"}, - {7014, L"ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE"}, - {7015, L"ERROR_CTX_MODEM_RESPONSE_BUSY"}, - {7016, L"ERROR_CTX_MODEM_RESPONSE_VOICE"}, - {7017, L"ERROR_CTX_TD_ERROR"}, - {7022, L"ERROR_CTX_WINSTATION_NOT_FOUND"}, - {7023, L"ERROR_CTX_WINSTATION_ALREADY_EXISTS"}, - {7024, L"ERROR_CTX_WINSTATION_BUSY"}, - {7025, L"ERROR_CTX_BAD_VIDEO_MODE"}, - {7035, L"ERROR_CTX_GRAPHICS_INVALID"}, - {7037, L"ERROR_CTX_LOGON_DISABLED"}, - {7038, L"ERROR_CTX_NOT_CONSOLE"}, - {7040, L"ERROR_CTX_CLIENT_QUERY_TIMEOUT"}, - {7041, L"ERROR_CTX_CONSOLE_DISCONNECT"}, - {7042, L"ERROR_CTX_CONSOLE_CONNECT"}, - {7044, L"ERROR_CTX_SHADOW_DENIED"}, - {7045, L"ERROR_CTX_WINSTATION_ACCESS_DENIED"}, - {7049, L"ERROR_CTX_INVALID_WD"}, - {7050, L"ERROR_CTX_SHADOW_INVALID"}, - {7051, L"ERROR_CTX_SHADOW_DISABLED"}, - {7052, L"ERROR_CTX_CLIENT_LICENSE_IN_USE"}, - {7053, L"ERROR_CTX_CLIENT_LICENSE_NOT_SET"}, - {7054, L"ERROR_CTX_LICENSE_NOT_AVAILABLE"}, - {7055, L"ERROR_CTX_LICENSE_CLIENT_INVALID"}, - {7056, L"ERROR_CTX_LICENSE_EXPIRED"}, - {7057, L"ERROR_CTX_SHADOW_NOT_RUNNING"}, - {7058, L"ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE"}, - {7059, L"ERROR_ACTIVATION_COUNT_EXCEEDED"}, - {7060, L"ERROR_CTX_WINSTATIONS_DISABLED"}, - {7061, L"ERROR_CTX_ENCRYPTION_LEVEL_REQUIRED"}, - {7062, L"ERROR_CTX_SESSION_IN_USE"}, - {7063, L"ERROR_CTX_NO_FORCE_LOGOFF"}, - {7064, L"ERROR_CTX_ACCOUNT_RESTRICTION"}, - {7065, L"ERROR_RDP_PROTOCOL_ERROR"}, - {7066, L"ERROR_CTX_CDM_CONNECT"}, - {7067, L"ERROR_CTX_CDM_DISCONNECT"}, - {7068, L"ERROR_CTX_SECURITY_LAYER_ERROR"}, - {7069, L"ERROR_TS_INCOMPATIBLE_SESSIONS"}, - {7070, L"ERROR_TS_VIDEO_SUBSYSTEM_ERROR"}, - {8001, L"FRS_ERR_INVALID_API_SEQUENCE"}, - {8002, L"FRS_ERR_STARTING_SERVICE"}, - {8003, L"FRS_ERR_STOPPING_SERVICE"}, - {8004, L"FRS_ERR_INTERNAL_API"}, - {8005, L"FRS_ERR_INTERNAL"}, - {8006, L"FRS_ERR_SERVICE_COMM"}, - {8007, L"FRS_ERR_INSUFFICIENT_PRIV"}, - {8008, L"FRS_ERR_AUTHENTICATION"}, - {8009, L"FRS_ERR_PARENT_INSUFFICIENT_PRIV"}, - {8010, L"FRS_ERR_PARENT_AUTHENTICATION"}, - {8011, L"FRS_ERR_CHILD_TO_PARENT_COMM"}, - {8012, L"FRS_ERR_PARENT_TO_CHILD_COMM"}, - {8013, L"FRS_ERR_SYSVOL_POPULATE"}, - {8014, L"FRS_ERR_SYSVOL_POPULATE_TIMEOUT"}, - {8015, L"FRS_ERR_SYSVOL_IS_BUSY"}, - {8016, L"FRS_ERR_SYSVOL_DEMOTE"}, - {8017, L"FRS_ERR_INVALID_SERVICE_PARAMETER"}, - {8200, L"ERROR_DS_NOT_INSTALLED"}, - {8201, L"ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY"}, - {8202, L"ERROR_DS_NO_ATTRIBUTE_OR_VALUE"}, - {8203, L"ERROR_DS_INVALID_ATTRIBUTE_SYNTAX"}, - {8204, L"ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED"}, - {8205, L"ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS"}, - {8206, L"ERROR_DS_BUSY"}, - {8207, L"ERROR_DS_UNAVAILABLE"}, - {8208, L"ERROR_DS_NO_RIDS_ALLOCATED"}, - {8209, L"ERROR_DS_NO_MORE_RIDS"}, - {8210, L"ERROR_DS_INCORRECT_ROLE_OWNER"}, - {8211, L"ERROR_DS_RIDMGR_INIT_ERROR"}, - {8212, L"ERROR_DS_OBJ_CLASS_VIOLATION"}, - {8213, L"ERROR_DS_CANT_ON_NON_LEAF"}, - {8214, L"ERROR_DS_CANT_ON_RDN"}, - {8215, L"ERROR_DS_CANT_MOD_OBJ_CLASS"}, - {8216, L"ERROR_DS_CROSS_DOM_MOVE_ERROR"}, - {8217, L"ERROR_DS_GC_NOT_AVAILABLE"}, - {8218, L"ERROR_SHARED_POLICY"}, - {8219, L"ERROR_POLICY_OBJECT_NOT_FOUND"}, - {8220, L"ERROR_POLICY_ONLY_IN_DS"}, - {8221, L"ERROR_PROMOTION_ACTIVE"}, - {8222, L"ERROR_NO_PROMOTION_ACTIVE"}, - {8224, L"ERROR_DS_OPERATIONS_ERROR"}, - {8225, L"ERROR_DS_PROTOCOL_ERROR"}, - {8226, L"ERROR_DS_TIMELIMIT_EXCEEDED"}, - {8227, L"ERROR_DS_SIZELIMIT_EXCEEDED"}, - {8228, L"ERROR_DS_ADMIN_LIMIT_EXCEEDED"}, - {8229, L"ERROR_DS_COMPARE_FALSE"}, - {8230, L"ERROR_DS_COMPARE_TRUE"}, - {8231, L"ERROR_DS_AUTH_METHOD_NOT_SUPPORTED"}, - {8232, L"ERROR_DS_STRONG_AUTH_REQUIRED"}, - {8233, L"ERROR_DS_INAPPROPRIATE_AUTH"}, - {8234, L"ERROR_DS_AUTH_UNKNOWN"}, - {8235, L"ERROR_DS_REFERRAL"}, - {8236, L"ERROR_DS_UNAVAILABLE_CRIT_EXTENSION"}, - {8237, L"ERROR_DS_CONFIDENTIALITY_REQUIRED"}, - {8238, L"ERROR_DS_INAPPROPRIATE_MATCHING"}, - {8239, L"ERROR_DS_CONSTRAINT_VIOLATION"}, - {8240, L"ERROR_DS_NO_SUCH_OBJECT"}, - {8241, L"ERROR_DS_ALIAS_PROBLEM"}, - {8242, L"ERROR_DS_INVALID_DN_SYNTAX"}, - {8243, L"ERROR_DS_IS_LEAF"}, - {8244, L"ERROR_DS_ALIAS_DEREF_PROBLEM"}, - {8245, L"ERROR_DS_UNWILLING_TO_PERFORM"}, - {8246, L"ERROR_DS_LOOP_DETECT"}, - {8247, L"ERROR_DS_NAMING_VIOLATION"}, - {8248, L"ERROR_DS_OBJECT_RESULTS_TOO_LARGE"}, - {8249, L"ERROR_DS_AFFECTS_MULTIPLE_DSAS"}, - {8250, L"ERROR_DS_SERVER_DOWN"}, - {8251, L"ERROR_DS_LOCAL_ERROR"}, - {8252, L"ERROR_DS_ENCODING_ERROR"}, - {8253, L"ERROR_DS_DECODING_ERROR"}, - {8254, L"ERROR_DS_FILTER_UNKNOWN"}, - {8255, L"ERROR_DS_PARAM_ERROR"}, - {8256, L"ERROR_DS_NOT_SUPPORTED"}, - {8257, L"ERROR_DS_NO_RESULTS_RETURNED"}, - {8258, L"ERROR_DS_CONTROL_NOT_FOUND"}, - {8259, L"ERROR_DS_CLIENT_LOOP"}, - {8260, L"ERROR_DS_REFERRAL_LIMIT_EXCEEDED"}, - {8261, L"ERROR_DS_SORT_CONTROL_MISSING"}, - {8262, L"ERROR_DS_OFFSET_RANGE_ERROR"}, - {8263, L"ERROR_DS_RIDMGR_DISABLED"}, - {8301, L"ERROR_DS_ROOT_MUST_BE_NC"}, - {8302, L"ERROR_DS_ADD_REPLICA_INHIBITED"}, - {8303, L"ERROR_DS_ATT_NOT_DEF_IN_SCHEMA"}, - {8304, L"ERROR_DS_MAX_OBJ_SIZE_EXCEEDED"}, - {8305, L"ERROR_DS_OBJ_STRING_NAME_EXISTS"}, - {8306, L"ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA"}, - {8307, L"ERROR_DS_RDN_DOESNT_MATCH_SCHEMA"}, - {8308, L"ERROR_DS_NO_REQUESTED_ATTS_FOUND"}, - {8309, L"ERROR_DS_USER_BUFFER_TO_SMALL"}, - {8310, L"ERROR_DS_ATT_IS_NOT_ON_OBJ"}, - {8311, L"ERROR_DS_ILLEGAL_MOD_OPERATION"}, - {8312, L"ERROR_DS_OBJ_TOO_LARGE"}, - {8313, L"ERROR_DS_BAD_INSTANCE_TYPE"}, - {8314, L"ERROR_DS_MASTERDSA_REQUIRED"}, - {8315, L"ERROR_DS_OBJECT_CLASS_REQUIRED"}, - {8316, L"ERROR_DS_MISSING_REQUIRED_ATT"}, - {8317, L"ERROR_DS_ATT_NOT_DEF_FOR_CLASS"}, - {8318, L"ERROR_DS_ATT_ALREADY_EXISTS"}, - {8320, L"ERROR_DS_CANT_ADD_ATT_VALUES"}, - {8321, L"ERROR_DS_SINGLE_VALUE_CONSTRAINT"}, - {8322, L"ERROR_DS_RANGE_CONSTRAINT"}, - {8323, L"ERROR_DS_ATT_VAL_ALREADY_EXISTS"}, - {8324, L"ERROR_DS_CANT_REM_MISSING_ATT"}, - {8325, L"ERROR_DS_CANT_REM_MISSING_ATT_VAL"}, - {8326, L"ERROR_DS_ROOT_CANT_BE_SUBREF"}, - {8327, L"ERROR_DS_NO_CHAINING"}, - {8328, L"ERROR_DS_NO_CHAINED_EVAL"}, - {8329, L"ERROR_DS_NO_PARENT_OBJECT"}, - {8330, L"ERROR_DS_PARENT_IS_AN_ALIAS"}, - {8331, L"ERROR_DS_CANT_MIX_MASTER_AND_REPS"}, - {8332, L"ERROR_DS_CHILDREN_EXIST"}, - {8333, L"ERROR_DS_OBJ_NOT_FOUND"}, - {8334, L"ERROR_DS_ALIASED_OBJ_MISSING"}, - {8335, L"ERROR_DS_BAD_NAME_SYNTAX"}, - {8336, L"ERROR_DS_ALIAS_POINTS_TO_ALIAS"}, - {8337, L"ERROR_DS_CANT_DEREF_ALIAS"}, - {8338, L"ERROR_DS_OUT_OF_SCOPE"}, - {8339, L"ERROR_DS_OBJECT_BEING_REMOVED"}, - {8340, L"ERROR_DS_CANT_DELETE_DSA_OBJ"}, - {8341, L"ERROR_DS_GENERIC_ERROR"}, - {8342, L"ERROR_DS_DSA_MUST_BE_INT_MASTER"}, - {8343, L"ERROR_DS_CLASS_NOT_DSA"}, - {8344, L"ERROR_DS_INSUFF_ACCESS_RIGHTS"}, - {8345, L"ERROR_DS_ILLEGAL_SUPERIOR"}, - {8346, L"ERROR_DS_ATTRIBUTE_OWNED_BY_SAM"}, - {8347, L"ERROR_DS_NAME_TOO_MANY_PARTS"}, - {8348, L"ERROR_DS_NAME_TOO_LONG"}, - {8349, L"ERROR_DS_NAME_VALUE_TOO_LONG"}, - {8350, L"ERROR_DS_NAME_UNPARSEABLE"}, - {8351, L"ERROR_DS_NAME_TYPE_UNKNOWN"}, - {8352, L"ERROR_DS_NOT_AN_OBJECT"}, - {8353, L"ERROR_DS_SEC_DESC_TOO_SHORT"}, - {8354, L"ERROR_DS_SEC_DESC_INVALID"}, - {8355, L"ERROR_DS_NO_DELETED_NAME"}, - {8356, L"ERROR_DS_SUBREF_MUST_HAVE_PARENT"}, - {8357, L"ERROR_DS_NCNAME_MUST_BE_NC"}, - {8358, L"ERROR_DS_CANT_ADD_SYSTEM_ONLY"}, - {8359, L"ERROR_DS_CLASS_MUST_BE_CONCRETE"}, - {8360, L"ERROR_DS_INVALID_DMD"}, - {8361, L"ERROR_DS_OBJ_GUID_EXISTS"}, - {8362, L"ERROR_DS_NOT_ON_BACKLINK"}, - {8363, L"ERROR_DS_NO_CROSSREF_FOR_NC"}, - {8364, L"ERROR_DS_SHUTTING_DOWN"}, - {8365, L"ERROR_DS_UNKNOWN_OPERATION"}, - {8366, L"ERROR_DS_INVALID_ROLE_OWNER"}, - {8367, L"ERROR_DS_COULDNT_CONTACT_FSMO"}, - {8368, L"ERROR_DS_CROSS_NC_DN_RENAME"}, - {8369, L"ERROR_DS_CANT_MOD_SYSTEM_ONLY"}, - {8370, L"ERROR_DS_REPLICATOR_ONLY"}, - {8371, L"ERROR_DS_OBJ_CLASS_NOT_DEFINED"}, - {8372, L"ERROR_DS_OBJ_CLASS_NOT_SUBCLASS"}, - {8373, L"ERROR_DS_NAME_REFERENCE_INVALID"}, - {8374, L"ERROR_DS_CROSS_REF_EXISTS"}, - {8375, L"ERROR_DS_CANT_DEL_MASTER_CROSSREF"}, - {8376, L"ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD"}, - {8377, L"ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX"}, - {8378, L"ERROR_DS_DUP_RDN"}, - {8379, L"ERROR_DS_DUP_OID"}, - {8380, L"ERROR_DS_DUP_MAPI_ID"}, - {8381, L"ERROR_DS_DUP_SCHEMA_ID_GUID"}, - {8382, L"ERROR_DS_DUP_LDAP_DISPLAY_NAME"}, - {8383, L"ERROR_DS_SEMANTIC_ATT_TEST"}, - {8384, L"ERROR_DS_SYNTAX_MISMATCH"}, - {8385, L"ERROR_DS_EXISTS_IN_MUST_HAVE"}, - {8386, L"ERROR_DS_EXISTS_IN_MAY_HAVE"}, - {8387, L"ERROR_DS_NONEXISTENT_MAY_HAVE"}, - {8388, L"ERROR_DS_NONEXISTENT_MUST_HAVE"}, - {8389, L"ERROR_DS_AUX_CLS_TEST_FAIL"}, - {8390, L"ERROR_DS_NONEXISTENT_POSS_SUP"}, - {8391, L"ERROR_DS_SUB_CLS_TEST_FAIL"}, - {8392, L"ERROR_DS_BAD_RDN_ATT_ID_SYNTAX"}, - {8393, L"ERROR_DS_EXISTS_IN_AUX_CLS"}, - {8394, L"ERROR_DS_EXISTS_IN_SUB_CLS"}, - {8395, L"ERROR_DS_EXISTS_IN_POSS_SUP"}, - {8396, L"ERROR_DS_RECALCSCHEMA_FAILED"}, - {8397, L"ERROR_DS_TREE_DELETE_NOT_FINISHED"}, - {8398, L"ERROR_DS_CANT_DELETE"}, - {8399, L"ERROR_DS_ATT_SCHEMA_REQ_ID"}, - {8400, L"ERROR_DS_BAD_ATT_SCHEMA_SYNTAX"}, - {8401, L"ERROR_DS_CANT_CACHE_ATT"}, - {8402, L"ERROR_DS_CANT_CACHE_CLASS"}, - {8403, L"ERROR_DS_CANT_REMOVE_ATT_CACHE"}, - {8404, L"ERROR_DS_CANT_REMOVE_CLASS_CACHE"}, - {8405, L"ERROR_DS_CANT_RETRIEVE_DN"}, - {8406, L"ERROR_DS_MISSING_SUPREF"}, - {8407, L"ERROR_DS_CANT_RETRIEVE_INSTANCE"}, - {8408, L"ERROR_DS_CODE_INCONSISTENCY"}, - {8409, L"ERROR_DS_DATABASE_ERROR"}, - {8410, L"ERROR_DS_GOVERNSID_MISSING"}, - {8411, L"ERROR_DS_MISSING_EXPECTED_ATT"}, - {8412, L"ERROR_DS_NCNAME_MISSING_CR_REF"}, - {8413, L"ERROR_DS_SECURITY_CHECKING_ERROR"}, - {8414, L"ERROR_DS_SCHEMA_NOT_LOADED"}, - {8415, L"ERROR_DS_SCHEMA_ALLOC_FAILED"}, - {8416, L"ERROR_DS_ATT_SCHEMA_REQ_SYNTAX"}, - {8417, L"ERROR_DS_GCVERIFY_ERROR"}, - {8418, L"ERROR_DS_DRA_SCHEMA_MISMATCH"}, - {8419, L"ERROR_DS_CANT_FIND_DSA_OBJ"}, - {8420, L"ERROR_DS_CANT_FIND_EXPECTED_NC"}, - {8421, L"ERROR_DS_CANT_FIND_NC_IN_CACHE"}, - {8422, L"ERROR_DS_CANT_RETRIEVE_CHILD"}, - {8423, L"ERROR_DS_SECURITY_ILLEGAL_MODIFY"}, - {8424, L"ERROR_DS_CANT_REPLACE_HIDDEN_REC"}, - {8425, L"ERROR_DS_BAD_HIERARCHY_FILE"}, - {8426, L"ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED"}, - {8427, L"ERROR_DS_CONFIG_PARAM_MISSING"}, - {8428, L"ERROR_DS_COUNTING_AB_INDICES_FAILED"}, - {8429, L"ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED"}, - {8430, L"ERROR_DS_INTERNAL_FAILURE"}, - {8431, L"ERROR_DS_UNKNOWN_ERROR"}, - {8432, L"ERROR_DS_ROOT_REQUIRES_CLASS_TOP"}, - {8433, L"ERROR_DS_REFUSING_FSMO_ROLES"}, - {8434, L"ERROR_DS_MISSING_FSMO_SETTINGS"}, - {8435, L"ERROR_DS_UNABLE_TO_SURRENDER_ROLES"}, - {8436, L"ERROR_DS_DRA_GENERIC"}, - {8437, L"ERROR_DS_DRA_INVALID_PARAMETER"}, - {8438, L"ERROR_DS_DRA_BUSY"}, - {8439, L"ERROR_DS_DRA_BAD_DN"}, - {8440, L"ERROR_DS_DRA_BAD_NC"}, - {8441, L"ERROR_DS_DRA_DN_EXISTS"}, - {8442, L"ERROR_DS_DRA_INTERNAL_ERROR"}, - {8443, L"ERROR_DS_DRA_INCONSISTENT_DIT"}, - {8444, L"ERROR_DS_DRA_CONNECTION_FAILED"}, - {8445, L"ERROR_DS_DRA_BAD_INSTANCE_TYPE"}, - {8446, L"ERROR_DS_DRA_OUT_OF_MEM"}, - {8447, L"ERROR_DS_DRA_MAIL_PROBLEM"}, - {8448, L"ERROR_DS_DRA_REF_ALREADY_EXISTS"}, - {8449, L"ERROR_DS_DRA_REF_NOT_FOUND"}, - {8450, L"ERROR_DS_DRA_OBJ_IS_REP_SOURCE"}, - {8451, L"ERROR_DS_DRA_DB_ERROR"}, - {8452, L"ERROR_DS_DRA_NO_REPLICA"}, - {8453, L"ERROR_DS_DRA_ACCESS_DENIED"}, - {8454, L"ERROR_DS_DRA_NOT_SUPPORTED"}, - {8455, L"ERROR_DS_DRA_RPC_CANCELLED"}, - {8456, L"ERROR_DS_DRA_SOURCE_DISABLED"}, - {8457, L"ERROR_DS_DRA_SINK_DISABLED"}, - {8458, L"ERROR_DS_DRA_NAME_COLLISION"}, - {8459, L"ERROR_DS_DRA_SOURCE_REINSTALLED"}, - {8460, L"ERROR_DS_DRA_MISSING_PARENT"}, - {8461, L"ERROR_DS_DRA_PREEMPTED"}, - {8462, L"ERROR_DS_DRA_ABANDON_SYNC"}, - {8463, L"ERROR_DS_DRA_SHUTDOWN"}, - {8464, L"ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET"}, - {8465, L"ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA"}, - {8466, L"ERROR_DS_DRA_EXTN_CONNECTION_FAILED"}, - {8467, L"ERROR_DS_INSTALL_SCHEMA_MISMATCH"}, - {8468, L"ERROR_DS_DUP_LINK_ID"}, - {8469, L"ERROR_DS_NAME_ERROR_RESOLVING"}, - {8470, L"ERROR_DS_NAME_ERROR_NOT_FOUND"}, - {8471, L"ERROR_DS_NAME_ERROR_NOT_UNIQUE"}, - {8472, L"ERROR_DS_NAME_ERROR_NO_MAPPING"}, - {8473, L"ERROR_DS_NAME_ERROR_DOMAIN_ONLY"}, - {8474, L"ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING"}, - {8475, L"ERROR_DS_CONSTRUCTED_ATT_MOD"}, - {8476, L"ERROR_DS_WRONG_OM_OBJ_CLASS"}, - {8477, L"ERROR_DS_DRA_REPL_PENDING"}, - {8478, L"ERROR_DS_DS_REQUIRED"}, - {8479, L"ERROR_DS_INVALID_LDAP_DISPLAY_NAME"}, - {8480, L"ERROR_DS_NON_BASE_SEARCH"}, - {8481, L"ERROR_DS_CANT_RETRIEVE_ATTS"}, - {8482, L"ERROR_DS_BACKLINK_WITHOUT_LINK"}, - {8483, L"ERROR_DS_EPOCH_MISMATCH"}, - {8484, L"ERROR_DS_SRC_NAME_MISMATCH"}, - {8485, L"ERROR_DS_SRC_AND_DST_NC_IDENTICAL"}, - {8486, L"ERROR_DS_DST_NC_MISMATCH"}, - {8487, L"ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC"}, - {8488, L"ERROR_DS_SRC_GUID_MISMATCH"}, - {8489, L"ERROR_DS_CANT_MOVE_DELETED_OBJECT"}, - {8490, L"ERROR_DS_PDC_OPERATION_IN_PROGRESS"}, - {8491, L"ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD"}, - {8492, L"ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION"}, - {8493, L"ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS"}, - {8494, L"ERROR_DS_NC_MUST_HAVE_NC_PARENT"}, - {8495, L"ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE"}, - {8496, L"ERROR_DS_DST_DOMAIN_NOT_NATIVE"}, - {8497, L"ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER"}, - {8498, L"ERROR_DS_CANT_MOVE_ACCOUNT_GROUP"}, - {8499, L"ERROR_DS_CANT_MOVE_RESOURCE_GROUP"}, - {8500, L"ERROR_DS_INVALID_SEARCH_FLAG"}, - {8501, L"ERROR_DS_NO_TREE_DELETE_ABOVE_NC"}, - {8502, L"ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE"}, - {8503, L"ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE"}, - {8504, L"ERROR_DS_SAM_INIT_FAILURE"}, - {8505, L"ERROR_DS_SENSITIVE_GROUP_VIOLATION"}, - {8506, L"ERROR_DS_CANT_MOD_PRIMARYGROUPID"}, - {8507, L"ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD"}, - {8508, L"ERROR_DS_NONSAFE_SCHEMA_CHANGE"}, - {8509, L"ERROR_DS_SCHEMA_UPDATE_DISALLOWED"}, - {8510, L"ERROR_DS_CANT_CREATE_UNDER_SCHEMA"}, - {8511, L"ERROR_DS_INSTALL_NO_SRC_SCH_VERSION"}, - {8512, L"ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE"}, - {8513, L"ERROR_DS_INVALID_GROUP_TYPE"}, - {8514, L"ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN"}, - {8515, L"ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN"}, - {8516, L"ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER"}, - {8517, L"ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER"}, - {8518, L"ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER"}, - {8519, L"ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER"}, - {8520, L"ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER"}, - {8521, L"ERROR_DS_HAVE_PRIMARY_MEMBERS"}, - {8522, L"ERROR_DS_STRING_SD_CONVERSION_FAILED"}, - {8523, L"ERROR_DS_NAMING_MASTER_GC"}, - {8524, L"ERROR_DS_DNS_LOOKUP_FAILURE"}, - {8525, L"ERROR_DS_COULDNT_UPDATE_SPNS"}, - {8526, L"ERROR_DS_CANT_RETRIEVE_SD"}, - {8527, L"ERROR_DS_KEY_NOT_UNIQUE"}, - {8528, L"ERROR_DS_WRONG_LINKED_ATT_SYNTAX"}, - {8529, L"ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD"}, - {8530, L"ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY"}, - {8531, L"ERROR_DS_CANT_START"}, - {8532, L"ERROR_DS_INIT_FAILURE"}, - {8533, L"ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION"}, - {8534, L"ERROR_DS_SOURCE_DOMAIN_IN_FOREST"}, - {8535, L"ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST"}, - {8536, L"ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED"}, - {8537, L"ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN"}, - {8538, L"ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER"}, - {8539, L"ERROR_DS_SRC_SID_EXISTS_IN_FOREST"}, - {8540, L"ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH"}, - {8541, L"ERROR_SAM_INIT_FAILURE"}, - {8542, L"ERROR_DS_DRA_SCHEMA_INFO_SHIP"}, - {8543, L"ERROR_DS_DRA_SCHEMA_CONFLICT"}, - {8544, L"ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT"}, - {8545, L"ERROR_DS_DRA_OBJ_NC_MISMATCH"}, - {8546, L"ERROR_DS_NC_STILL_HAS_DSAS"}, - {8547, L"ERROR_DS_GC_REQUIRED"}, - {8548, L"ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY"}, - {8549, L"ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS"}, - {8550, L"ERROR_DS_CANT_ADD_TO_GC"}, - {8551, L"ERROR_DS_NO_CHECKPOINT_WITH_PDC"}, - {8552, L"ERROR_DS_SOURCE_AUDITING_NOT_ENABLED"}, - {8553, L"ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC"}, - {8554, L"ERROR_DS_INVALID_NAME_FOR_SPN"}, - {8555, L"ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS"}, - {8556, L"ERROR_DS_UNICODEPWD_NOT_IN_QUOTES"}, - {8557, L"ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED"}, - {8558, L"ERROR_DS_MUST_BE_RUN_ON_DST_DC"}, - {8559, L"ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER"}, - {8560, L"ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ"}, - {8561, L"ERROR_DS_INIT_FAILURE_CONSOLE"}, - {8562, L"ERROR_DS_SAM_INIT_FAILURE_CONSOLE"}, - {8563, L"ERROR_DS_FOREST_VERSION_TOO_HIGH"}, - {8564, L"ERROR_DS_DOMAIN_VERSION_TOO_HIGH"}, - {8565, L"ERROR_DS_FOREST_VERSION_TOO_LOW"}, - {8566, L"ERROR_DS_DOMAIN_VERSION_TOO_LOW"}, - {8567, L"ERROR_DS_INCOMPATIBLE_VERSION"}, - {8568, L"ERROR_DS_LOW_DSA_VERSION"}, - {8569, L"ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN"}, - {8570, L"ERROR_DS_NOT_SUPPORTED_SORT_ORDER"}, - {8571, L"ERROR_DS_NAME_NOT_UNIQUE"}, - {8572, L"ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4"}, - {8573, L"ERROR_DS_OUT_OF_VERSION_STORE"}, - {8574, L"ERROR_DS_INCOMPATIBLE_CONTROLS_USED"}, - {8575, L"ERROR_DS_NO_REF_DOMAIN"}, - {8576, L"ERROR_DS_RESERVED_LINK_ID"}, - {8577, L"ERROR_DS_LINK_ID_NOT_AVAILABLE"}, - {8578, L"ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER"}, - {8579, L"ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE"}, - {8580, L"ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC"}, - {8581, L"ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG"}, - {8582, L"ERROR_DS_MODIFYDN_WRONG_GRANDPARENT"}, - {8583, L"ERROR_DS_NAME_ERROR_TRUST_REFERRAL"}, - {8584, L"ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER"}, - {8585, L"ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD"}, - {8586, L"ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2"}, - {8587, L"ERROR_DS_THREAD_LIMIT_EXCEEDED"}, - {8588, L"ERROR_DS_NOT_CLOSEST"}, - {8589, L"ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF"}, - {8590, L"ERROR_DS_SINGLE_USER_MODE_FAILED"}, - {8591, L"ERROR_DS_NTDSCRIPT_SYNTAX_ERROR"}, - {8592, L"ERROR_DS_NTDSCRIPT_PROCESS_ERROR"}, - {8593, L"ERROR_DS_DIFFERENT_REPL_EPOCHS"}, - {8594, L"ERROR_DS_DRS_EXTENSIONS_CHANGED"}, - {8595, L"ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR"}, - {8596, L"ERROR_DS_NO_MSDS_INTID"}, - {8597, L"ERROR_DS_DUP_MSDS_INTID"}, - {8598, L"ERROR_DS_EXISTS_IN_RDNATTID"}, - {8599, L"ERROR_DS_AUTHORIZATION_FAILED"}, - {8600, L"ERROR_DS_INVALID_SCRIPT"}, - {8601, L"ERROR_DS_REMOTE_CROSSREF_OP_FAILED"}, - {8602, L"ERROR_DS_CROSS_REF_BUSY"}, - {8603, L"ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN"}, - {8604, L"ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC"}, - {8605, L"ERROR_DS_DUPLICATE_ID_FOUND"}, - {8606, L"ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT"}, - {8607, L"ERROR_DS_GROUP_CONVERSION_ERROR"}, - {8608, L"ERROR_DS_CANT_MOVE_APP_BASIC_GROUP"}, - {8609, L"ERROR_DS_CANT_MOVE_APP_QUERY_GROUP"}, - {8610, L"ERROR_DS_ROLE_NOT_VERIFIED"}, - {8611, L"ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL"}, - {8612, L"ERROR_DS_DOMAIN_RENAME_IN_PROGRESS"}, - {8613, L"ERROR_DS_EXISTING_AD_CHILD_NC"}, - {8614, L"ERROR_DS_REPL_LIFETIME_EXCEEDED"}, - {8615, L"ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER"}, - {8616, L"ERROR_DS_LDAP_SEND_QUEUE_FULL"}, - {8617, L"ERROR_DS_DRA_OUT_SCHEDULE_WINDOW"}, - {8618, L"ERROR_DS_POLICY_NOT_KNOWN"}, - {8619, L"ERROR_NO_SITE_SETTINGS_OBJECT"}, - {8620, L"ERROR_NO_SECRETS"}, - {8621, L"ERROR_NO_WRITABLE_DC_FOUND"}, - {8622, L"ERROR_DS_NO_SERVER_OBJECT"}, - {8623, L"ERROR_DS_NO_NTDSA_OBJECT"}, - {8624, L"ERROR_DS_NON_ASQ_SEARCH"}, - {8625, L"ERROR_DS_AUDIT_FAILURE"}, - {8626, L"ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE"}, - {8627, L"ERROR_DS_INVALID_SEARCH_FLAG_TUPLE"}, - {8628, L"ERROR_DS_HIERARCHY_TABLE_TOO_DEEP"}, - {8629, L"ERROR_DS_DRA_CORRUPT_UTD_VECTOR"}, - {8630, L"ERROR_DS_DRA_SECRETS_DENIED"}, - {8631, L"ERROR_DS_RESERVED_MAPI_ID"}, - {8632, L"ERROR_DS_MAPI_ID_NOT_AVAILABLE"}, - {8633, L"ERROR_DS_DRA_MISSING_KRBTGT_SECRET"}, - {8634, L"ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST"}, - {8635, L"ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST"}, - {8636, L"ERROR_INVALID_USER_PRINCIPAL_NAME"}, - {8637, L"ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS"}, - {8638, L"ERROR_DS_OID_NOT_FOUND"}, - {8639, L"ERROR_DS_DRA_RECYCLED_TARGET"}, - {8640, L"ERROR_DS_DISALLOWED_NC_REDIRECT"}, - {8641, L"ERROR_DS_HIGH_ADLDS_FFL"}, - {8642, L"ERROR_DS_HIGH_DSA_VERSION"}, - {8643, L"ERROR_DS_LOW_ADLDS_FFL"}, - {8644, L"ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION"}, - {8645, L"ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED"}, - {8646, L"ERROR_INCORRECT_ACCOUNT_TYPE"}, - {9001, L"DNS_ERROR_RCODE_FORMAT_ERROR"}, - {9002, L"DNS_ERROR_RCODE_SERVER_FAILURE"}, - {9003, L"DNS_ERROR_RCODE_NAME_ERROR"}, - {9004, L"DNS_ERROR_RCODE_NOT_IMPLEMENTED"}, - {9005, L"DNS_ERROR_RCODE_REFUSED"}, - {9006, L"DNS_ERROR_RCODE_YXDOMAIN"}, - {9007, L"DNS_ERROR_RCODE_YXRRSET"}, - {9008, L"DNS_ERROR_RCODE_NXRRSET"}, - {9009, L"DNS_ERROR_RCODE_NOTAUTH"}, - {9010, L"DNS_ERROR_RCODE_NOTZONE"}, - {9016, L"DNS_ERROR_RCODE_BADSIG"}, - {9017, L"DNS_ERROR_RCODE_BADKEY"}, - {9018, L"DNS_ERROR_RCODE_BADTIME"}, - {9101, L"DNS_ERROR_KEYMASTER_REQUIRED"}, - {9102, L"DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE"}, - {9103, L"DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1"}, - {9104, L"DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS"}, - {9105, L"DNS_ERROR_UNSUPPORTED_ALGORITHM"}, - {9106, L"DNS_ERROR_INVALID_KEY_SIZE"}, - {9107, L"DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE"}, - {9108, L"DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION"}, - {9109, L"DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR"}, - {9110, L"DNS_ERROR_UNEXPECTED_CNG_ERROR"}, - {9111, L"DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION"}, - {9112, L"DNS_ERROR_KSP_NOT_ACCESSIBLE"}, - {9113, L"DNS_ERROR_TOO_MANY_SKDS"}, - {9114, L"DNS_ERROR_INVALID_ROLLOVER_PERIOD"}, - {9115, L"DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET"}, - {9116, L"DNS_ERROR_ROLLOVER_IN_PROGRESS"}, - {9117, L"DNS_ERROR_STANDBY_KEY_NOT_PRESENT"}, - {9118, L"DNS_ERROR_NOT_ALLOWED_ON_ZSK"}, - {9119, L"DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD"}, - {9120, L"DNS_ERROR_ROLLOVER_ALREADY_QUEUED"}, - {9121, L"DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE"}, - {9122, L"DNS_ERROR_BAD_KEYMASTER"}, - {9123, L"DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD"}, - {9124, L"DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT"}, - {9125, L"DNS_ERROR_DNSSEC_IS_DISABLED"}, - {9126, L"DNS_ERROR_INVALID_XML"}, - {9127, L"DNS_ERROR_NO_VALID_TRUST_ANCHORS"}, - {9128, L"DNS_ERROR_ROLLOVER_NOT_POKEABLE"}, - {9129, L"DNS_ERROR_NSEC3_NAME_COLLISION"}, - {9130, L"DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1"}, - {9501, L"DNS_INFO_NO_RECORDS"}, - {9502, L"DNS_ERROR_BAD_PACKET"}, - {9503, L"DNS_ERROR_NO_PACKET"}, - {9504, L"DNS_ERROR_RCODE"}, - {9505, L"DNS_ERROR_UNSECURE_PACKET"}, - {9506, L"DNS_REQUEST_PENDING"}, - {9551, L"DNS_ERROR_INVALID_TYPE"}, - {9552, L"DNS_ERROR_INVALID_IP_ADDRESS"}, - {9553, L"DNS_ERROR_INVALID_PROPERTY"}, - {9554, L"DNS_ERROR_TRY_AGAIN_LATER"}, - {9555, L"DNS_ERROR_NOT_UNIQUE"}, - {9556, L"DNS_ERROR_NON_RFC_NAME"}, - {9557, L"DNS_STATUS_FQDN"}, - {9558, L"DNS_STATUS_DOTTED_NAME"}, - {9559, L"DNS_STATUS_SINGLE_PART_NAME"}, - {9560, L"DNS_ERROR_INVALID_NAME_CHAR"}, - {9561, L"DNS_ERROR_NUMERIC_NAME"}, - {9562, L"DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER"}, - {9563, L"DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION"}, - {9564, L"DNS_ERROR_CANNOT_FIND_ROOT_HINTS"}, - {9565, L"DNS_ERROR_INCONSISTENT_ROOT_HINTS"}, - {9566, L"DNS_ERROR_DWORD_VALUE_TOO_SMALL"}, - {9567, L"DNS_ERROR_DWORD_VALUE_TOO_LARGE"}, - {9568, L"DNS_ERROR_BACKGROUND_LOADING"}, - {9569, L"DNS_ERROR_NOT_ALLOWED_ON_RODC"}, - {9570, L"DNS_ERROR_NOT_ALLOWED_UNDER_DNAME"}, - {9571, L"DNS_ERROR_DELEGATION_REQUIRED"}, - {9572, L"DNS_ERROR_INVALID_POLICY_TABLE"}, - {9601, L"DNS_ERROR_ZONE_DOES_NOT_EXIST"}, - {9602, L"DNS_ERROR_NO_ZONE_INFO"}, - {9603, L"DNS_ERROR_INVALID_ZONE_OPERATION"}, - {9604, L"DNS_ERROR_ZONE_CONFIGURATION_ERROR"}, - {9605, L"DNS_ERROR_ZONE_HAS_NO_SOA_RECORD"}, - {9606, L"DNS_ERROR_ZONE_HAS_NO_NS_RECORDS"}, - {9607, L"DNS_ERROR_ZONE_LOCKED"}, - {9608, L"DNS_ERROR_ZONE_CREATION_FAILED"}, - {9609, L"DNS_ERROR_ZONE_ALREADY_EXISTS"}, - {9610, L"DNS_ERROR_AUTOZONE_ALREADY_EXISTS"}, - {9611, L"DNS_ERROR_INVALID_ZONE_TYPE"}, - {9612, L"DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP"}, - {9613, L"DNS_ERROR_ZONE_NOT_SECONDARY"}, - {9614, L"DNS_ERROR_NEED_SECONDARY_ADDRESSES"}, - {9615, L"DNS_ERROR_WINS_INIT_FAILED"}, - {9616, L"DNS_ERROR_NEED_WINS_SERVERS"}, - {9617, L"DNS_ERROR_NBSTAT_INIT_FAILED"}, - {9618, L"DNS_ERROR_SOA_DELETE_INVALID"}, - {9619, L"DNS_ERROR_FORWARDER_ALREADY_EXISTS"}, - {9620, L"DNS_ERROR_ZONE_REQUIRES_MASTER_IP"}, - {9621, L"DNS_ERROR_ZONE_IS_SHUTDOWN"}, - {9622, L"DNS_ERROR_ZONE_LOCKED_FOR_SIGNING"}, - {9651, L"DNS_ERROR_PRIMARY_REQUIRES_DATAFILE"}, - {9652, L"DNS_ERROR_INVALID_DATAFILE_NAME"}, - {9653, L"DNS_ERROR_DATAFILE_OPEN_FAILURE"}, - {9654, L"DNS_ERROR_FILE_WRITEBACK_FAILED"}, - {9655, L"DNS_ERROR_DATAFILE_PARSING"}, - {9701, L"DNS_ERROR_RECORD_DOES_NOT_EXIST"}, - {9702, L"DNS_ERROR_RECORD_FORMAT"}, - {9703, L"DNS_ERROR_NODE_CREATION_FAILED"}, - {9704, L"DNS_ERROR_UNKNOWN_RECORD_TYPE"}, - {9705, L"DNS_ERROR_RECORD_TIMED_OUT"}, - {9706, L"DNS_ERROR_NAME_NOT_IN_ZONE"}, - {9707, L"DNS_ERROR_CNAME_LOOP"}, - {9708, L"DNS_ERROR_NODE_IS_CNAME"}, - {9709, L"DNS_ERROR_CNAME_COLLISION"}, - {9710, L"DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT"}, - {9711, L"DNS_ERROR_RECORD_ALREADY_EXISTS"}, - {9712, L"DNS_ERROR_SECONDARY_DATA"}, - {9713, L"DNS_ERROR_NO_CREATE_CACHE_DATA"}, - {9714, L"DNS_ERROR_NAME_DOES_NOT_EXIST"}, - {9715, L"DNS_WARNING_PTR_CREATE_FAILED"}, - {9716, L"DNS_WARNING_DOMAIN_UNDELETED"}, - {9717, L"DNS_ERROR_DS_UNAVAILABLE"}, - {9718, L"DNS_ERROR_DS_ZONE_ALREADY_EXISTS"}, - {9719, L"DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE"}, - {9720, L"DNS_ERROR_NODE_IS_DNAME"}, - {9721, L"DNS_ERROR_DNAME_COLLISION"}, - {9722, L"DNS_ERROR_ALIAS_LOOP"}, - {9751, L"DNS_INFO_AXFR_COMPLETE"}, - {9752, L"DNS_ERROR_AXFR"}, - {9753, L"DNS_INFO_ADDED_LOCAL_WINS"}, - {9801, L"DNS_STATUS_CONTINUE_NEEDED"}, - {9851, L"DNS_ERROR_NO_TCPIP"}, - {9852, L"DNS_ERROR_NO_DNS_SERVERS"}, - {9901, L"DNS_ERROR_DP_DOES_NOT_EXIST"}, - {9902, L"DNS_ERROR_DP_ALREADY_EXISTS"}, - {9903, L"DNS_ERROR_DP_NOT_ENLISTED"}, - {9904, L"DNS_ERROR_DP_ALREADY_ENLISTED"}, - {9905, L"DNS_ERROR_DP_NOT_AVAILABLE"}, - {9906, L"DNS_ERROR_DP_FSMO_ERROR"}, - {10004, L"WSAEINTR"}, - {10009, L"WSAEBADF"}, - {10013, L"WSAEACCES"}, - {10014, L"WSAEFAULT"}, - {10022, L"WSAEINVAL"}, - {10024, L"WSAEMFILE"}, - {10035, L"WSAEWOULDBLOCK"}, - {10036, L"WSAEINPROGRESS"}, - {10037, L"WSAEALREADY"}, - {10038, L"WSAENOTSOCK"}, - {10039, L"WSAEDESTADDRREQ"}, - {10040, L"WSAEMSGSIZE"}, - {10041, L"WSAEPROTOTYPE"}, - {10042, L"WSAENOPROTOOPT"}, - {10043, L"WSAEPROTONOSUPPORT"}, - {10044, L"WSAESOCKTNOSUPPORT"}, - {10045, L"WSAEOPNOTSUPP"}, - {10046, L"WSAEPFNOSUPPORT"}, - {10047, L"WSAEAFNOSUPPORT"}, - {10048, L"WSAEADDRINUSE"}, - {10049, L"WSAEADDRNOTAVAIL"}, - {10050, L"WSAENETDOWN"}, - {10051, L"WSAENETUNREACH"}, - {10052, L"WSAENETRESET"}, - {10053, L"WSAECONNABORTED"}, - {10054, L"WSAECONNRESET"}, - {10055, L"WSAENOBUFS"}, - {10056, L"WSAEISCONN"}, - {10057, L"WSAENOTCONN"}, - {10058, L"WSAESHUTDOWN"}, - {10059, L"WSAETOOMANYREFS"}, - {10060, L"WSAETIMEDOUT"}, - {10061, L"WSAECONNREFUSED"}, - {10062, L"WSAELOOP"}, - {10063, L"WSAENAMETOOLONG"}, - {10064, L"WSAEHOSTDOWN"}, - {10065, L"WSAEHOSTUNREACH"}, - {10066, L"WSAENOTEMPTY"}, - {10067, L"WSAEPROCLIM"}, - {10068, L"WSAEUSERS"}, - {10069, L"WSAEDQUOT"}, - {10070, L"WSAESTALE"}, - {10071, L"WSAEREMOTE"}, - {10091, L"WSASYSNOTREADY"}, - {10092, L"WSAVERNOTSUPPORTED"}, - {10093, L"WSANOTINITIALISED"}, - {10101, L"WSAEDISCON"}, - {10102, L"WSAENOMORE"}, - {10103, L"WSAECANCELLED"}, - {10104, L"WSAEINVALIDPROCTABLE"}, - {10105, L"WSAEINVALIDPROVIDER"}, - {10106, L"WSAEPROVIDERFAILEDINIT"}, - {10107, L"WSASYSCALLFAILURE"}, - {10108, L"WSASERVICE_NOT_FOUND"}, - {10109, L"WSATYPE_NOT_FOUND"}, - {10110, L"WSA_E_NO_MORE"}, - {10111, L"WSA_E_CANCELLED"}, - {10112, L"WSAEREFUSED"}, - {11001, L"WSAHOST_NOT_FOUND"}, - {11002, L"WSATRY_AGAIN"}, - {11003, L"WSANO_RECOVERY"}, - {11004, L"WSANO_DATA"}, - {11005, L"WSA_QOS_RECEIVERS"}, - {11006, L"WSA_QOS_SENDERS"}, - {11007, L"WSA_QOS_NO_SENDERS"}, - {11008, L"WSA_QOS_NO_RECEIVERS"}, - {11009, L"WSA_QOS_REQUEST_CONFIRMED"}, - {11010, L"WSA_QOS_ADMISSION_FAILURE"}, - {11011, L"WSA_QOS_POLICY_FAILURE"}, - {11012, L"WSA_QOS_BAD_STYLE"}, - {11013, L"WSA_QOS_BAD_OBJECT"}, - {11014, L"WSA_QOS_TRAFFIC_CTRL_ERROR"}, - {11015, L"WSA_QOS_GENERIC_ERROR"}, - {11016, L"WSA_QOS_ESERVICETYPE"}, - {11017, L"WSA_QOS_EFLOWSPEC"}, - {11018, L"WSA_QOS_EPROVSPECBUF"}, - {11019, L"WSA_QOS_EFILTERSTYLE"}, - {11020, L"WSA_QOS_EFILTERTYPE"}, - {11021, L"WSA_QOS_EFILTERCOUNT"}, - {11022, L"WSA_QOS_EOBJLENGTH"}, - {11023, L"WSA_QOS_EFLOWCOUNT"}, - {11024, L"WSA_QOS_EUNKOWNPSOBJ"}, - {11025, L"WSA_QOS_EPOLICYOBJ"}, - {11026, L"WSA_QOS_EFLOWDESC"}, - {11027, L"WSA_QOS_EPSFLOWSPEC"}, - {11028, L"WSA_QOS_EPSFILTERSPEC"}, - {11029, L"WSA_QOS_ESDMODEOBJ"}, - {11030, L"WSA_QOS_ESHAPERATEOBJ"}, - {11031, L"WSA_QOS_RESERVED_PETYPE"}, - {11032, L"WSA_SECURE_HOST_NOT_FOUND"}, - {11033, L"WSA_IPSEC_NAME_POLICY_ERROR"} -}; + {1, L"ERROR_INVALID_FUNCTION"}, + {2, L"ERROR_FILE_NOT_FOUND"}, + {3, L"ERROR_PATH_NOT_FOUND"}, + {4, L"ERROR_TOO_MANY_OPEN_FILES"}, + {5, L"ERROR_ACCESS_DENIED"}, + {6, L"ERROR_INVALID_HANDLE"}, + {7, L"ERROR_ARENA_TRASHED"}, + {8, L"ERROR_NOT_ENOUGH_MEMORY"}, + {9, L"ERROR_INVALID_BLOCK"}, + {10, L"ERROR_BAD_ENVIRONMENT"}, + {11, L"ERROR_BAD_FORMAT"}, + {12, L"ERROR_INVALID_ACCESS"}, + {13, L"ERROR_INVALID_DATA"}, + {14, L"ERROR_OUTOFMEMORY"}, + {15, L"ERROR_INVALID_DRIVE"}, + {16, L"ERROR_CURRENT_DIRECTORY"}, + {17, L"ERROR_NOT_SAME_DEVICE"}, + {18, L"ERROR_NO_MORE_FILES"}, + {19, L"ERROR_WRITE_PROTECT"}, + {20, L"ERROR_BAD_UNIT"}, + {21, L"ERROR_NOT_READY"}, + {22, L"ERROR_BAD_COMMAND"}, + {23, L"ERROR_CRC"}, + {24, L"ERROR_BAD_LENGTH"}, + {25, L"ERROR_SEEK"}, + {26, L"ERROR_NOT_DOS_DISK"}, + {27, L"ERROR_SECTOR_NOT_FOUND"}, + {28, L"ERROR_OUT_OF_PAPER"}, + {29, L"ERROR_WRITE_FAULT"}, + {30, L"ERROR_READ_FAULT"}, + {31, L"ERROR_GEN_FAILURE"}, + {32, L"ERROR_SHARING_VIOLATION"}, + {33, L"ERROR_LOCK_VIOLATION"}, + {34, L"ERROR_WRONG_DISK"}, + {36, L"ERROR_SHARING_BUFFER_EXCEEDED"}, + {38, L"ERROR_HANDLE_EOF"}, + {39, L"ERROR_HANDLE_DISK_FULL"}, + {50, L"ERROR_NOT_SUPPORTED"}, + {51, L"ERROR_REM_NOT_LIST"}, + {52, L"ERROR_DUP_NAME"}, + {53, L"ERROR_BAD_NETPATH"}, + {54, L"ERROR_NETWORK_BUSY"}, + {55, L"ERROR_DEV_NOT_EXIST"}, + {56, L"ERROR_TOO_MANY_CMDS"}, + {57, L"ERROR_ADAP_HDW_ERR"}, + {58, L"ERROR_BAD_NET_RESP"}, + {59, L"ERROR_UNEXP_NET_ERR"}, + {60, L"ERROR_BAD_REM_ADAP"}, + {61, L"ERROR_PRINTQ_FULL"}, + {62, L"ERROR_NO_SPOOL_SPACE"}, + {63, L"ERROR_PRINT_CANCELLED"}, + {64, L"ERROR_NETNAME_DELETED"}, + {65, L"ERROR_NETWORK_ACCESS_DENIED"}, + {66, L"ERROR_BAD_DEV_TYPE"}, + {67, L"ERROR_BAD_NET_NAME"}, + {68, L"ERROR_TOO_MANY_NAMES"}, + {69, L"ERROR_TOO_MANY_SESS"}, + {70, L"ERROR_SHARING_PAUSED"}, + {71, L"ERROR_REQ_NOT_ACCEP"}, + {72, L"ERROR_REDIR_PAUSED"}, + {80, L"ERROR_FILE_EXISTS"}, + {82, L"ERROR_CANNOT_MAKE"}, + {83, L"ERROR_FAIL_I24"}, + {84, L"ERROR_OUT_OF_STRUCTURES"}, + {85, L"ERROR_ALREADY_ASSIGNED"}, + {86, L"ERROR_INVALID_PASSWORD"}, + {87, L"ERROR_INVALID_PARAMETER"}, + {88, L"ERROR_NET_WRITE_FAULT"}, + {89, L"ERROR_NO_PROC_SLOTS"}, + {100, L"ERROR_TOO_MANY_SEMAPHORES"}, + {101, L"ERROR_EXCL_SEM_ALREADY_OWNED"}, + {102, L"ERROR_SEM_IS_SET"}, + {103, L"ERROR_TOO_MANY_SEM_REQUESTS"}, + {104, L"ERROR_INVALID_AT_INTERRUPT_TIME"}, + {105, L"ERROR_SEM_OWNER_DIED"}, + {106, L"ERROR_SEM_USER_LIMIT"}, + {107, L"ERROR_DISK_CHANGE"}, + {108, L"ERROR_DRIVE_LOCKED"}, + {109, L"ERROR_BROKEN_PIPE"}, + {110, L"ERROR_OPEN_FAILED"}, + {111, L"ERROR_BUFFER_OVERFLOW"}, + {112, L"ERROR_DISK_FULL"}, + {113, L"ERROR_NO_MORE_SEARCH_HANDLES"}, + {114, L"ERROR_INVALID_TARGET_HANDLE"}, + {117, L"ERROR_INVALID_CATEGORY"}, + {118, L"ERROR_INVALID_VERIFY_SWITCH"}, + {119, L"ERROR_BAD_DRIVER_LEVEL"}, + {120, L"ERROR_CALL_NOT_IMPLEMENTED"}, + {121, L"ERROR_SEM_TIMEOUT"}, + {122, L"ERROR_INSUFFICIENT_BUFFER"}, + {123, L"ERROR_INVALID_NAME"}, + {124, L"ERROR_INVALID_LEVEL"}, + {125, L"ERROR_NO_VOLUME_LABEL"}, + {126, L"ERROR_MOD_NOT_FOUND"}, + {127, L"ERROR_PROC_NOT_FOUND"}, + {128, L"ERROR_WAIT_NO_CHILDREN"}, + {129, L"ERROR_CHILD_NOT_COMPLETE"}, + {130, L"ERROR_DIRECT_ACCESS_HANDLE"}, + {131, L"ERROR_NEGATIVE_SEEK"}, + {132, L"ERROR_SEEK_ON_DEVICE"}, + {133, L"ERROR_IS_JOIN_TARGET"}, + {134, L"ERROR_IS_JOINED"}, + {135, L"ERROR_IS_SUBSTED"}, + {136, L"ERROR_NOT_JOINED"}, + {137, L"ERROR_NOT_SUBSTED"}, + {138, L"ERROR_JOIN_TO_JOIN"}, + {139, L"ERROR_SUBST_TO_SUBST"}, + {140, L"ERROR_JOIN_TO_SUBST"}, + {141, L"ERROR_SUBST_TO_JOIN"}, + {142, L"ERROR_BUSY_DRIVE"}, + {143, L"ERROR_SAME_DRIVE"}, + {144, L"ERROR_DIR_NOT_ROOT"}, + {145, L"ERROR_DIR_NOT_EMPTY"}, + {146, L"ERROR_IS_SUBST_PATH"}, + {147, L"ERROR_IS_JOIN_PATH"}, + {148, L"ERROR_PATH_BUSY"}, + {149, L"ERROR_IS_SUBST_TARGET"}, + {150, L"ERROR_SYSTEM_TRACE"}, + {151, L"ERROR_INVALID_EVENT_COUNT"}, + {152, L"ERROR_TOO_MANY_MUXWAITERS"}, + {153, L"ERROR_INVALID_LIST_FORMAT"}, + {154, L"ERROR_LABEL_TOO_LONG"}, + {155, L"ERROR_TOO_MANY_TCBS"}, + {156, L"ERROR_SIGNAL_REFUSED"}, + {157, L"ERROR_DISCARDED"}, + {158, L"ERROR_NOT_LOCKED"}, + {159, L"ERROR_BAD_THREADID_ADDR"}, + {160, L"ERROR_BAD_ARGUMENTS"}, + {161, L"ERROR_BAD_PATHNAME"}, + {162, L"ERROR_SIGNAL_PENDING"}, + {164, L"ERROR_MAX_THRDS_REACHED"}, + {167, L"ERROR_LOCK_FAILED"}, + {170, L"ERROR_BUSY"}, + {171, L"ERROR_DEVICE_SUPPORT_IN_PROGRESS"}, + {173, L"ERROR_CANCEL_VIOLATION"}, + {174, L"ERROR_ATOMIC_LOCKS_NOT_SUPPORTED"}, + {180, L"ERROR_INVALID_SEGMENT_NUMBER"}, + {182, L"ERROR_INVALID_ORDINAL"}, + {183, L"ERROR_ALREADY_EXISTS"}, + {186, L"ERROR_INVALID_FLAG_NUMBER"}, + {187, L"ERROR_SEM_NOT_FOUND"}, + {188, L"ERROR_INVALID_STARTING_CODESEG"}, + {189, L"ERROR_INVALID_STACKSEG"}, + {190, L"ERROR_INVALID_MODULETYPE"}, + {191, L"ERROR_INVALID_EXE_SIGNATURE"}, + {192, L"ERROR_EXE_MARKED_INVALID"}, + {193, L"ERROR_BAD_EXE_FORMAT"}, + {194, L"ERROR_ITERATED_DATA_EXCEEDS_64k"}, + {195, L"ERROR_INVALID_MINALLOCSIZE"}, + {196, L"ERROR_DYNLINK_FROM_INVALID_RING"}, + {197, L"ERROR_IOPL_NOT_ENABLED"}, + {198, L"ERROR_INVALID_SEGDPL"}, + {199, L"ERROR_AUTODATASEG_EXCEEDS_64k"}, + {200, L"ERROR_RING2SEG_MUST_BE_MOVABLE"}, + {201, L"ERROR_RELOC_CHAIN_XEEDS_SEGLIM"}, + {202, L"ERROR_INFLOOP_IN_RELOC_CHAIN"}, + {203, L"ERROR_ENVVAR_NOT_FOUND"}, + {205, L"ERROR_NO_SIGNAL_SENT"}, + {206, L"ERROR_FILENAME_EXCED_RANGE"}, + {207, L"ERROR_RING2_STACK_IN_USE"}, + {208, L"ERROR_META_EXPANSION_TOO_LONG"}, + {209, L"ERROR_INVALID_SIGNAL_NUMBER"}, + {210, L"ERROR_THREAD_1_INACTIVE"}, + {212, L"ERROR_LOCKED"}, + {214, L"ERROR_TOO_MANY_MODULES"}, + {215, L"ERROR_NESTING_NOT_ALLOWED"}, + {216, L"ERROR_EXE_MACHINE_TYPE_MISMATCH"}, + {217, L"ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY"}, + {218, L"ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY"}, + {220, L"ERROR_FILE_CHECKED_OUT"}, + {221, L"ERROR_CHECKOUT_REQUIRED"}, + {222, L"ERROR_BAD_FILE_TYPE"}, + {223, L"ERROR_FILE_TOO_LARGE"}, + {224, L"ERROR_FORMS_AUTH_REQUIRED"}, + {225, L"ERROR_VIRUS_INFECTED"}, + {226, L"ERROR_VIRUS_DELETED"}, + {229, L"ERROR_PIPE_LOCAL"}, + {230, L"ERROR_BAD_PIPE"}, + {231, L"ERROR_PIPE_BUSY"}, + {232, L"ERROR_NO_DATA"}, + {233, L"ERROR_PIPE_NOT_CONNECTED"}, + {234, L"ERROR_MORE_DATA"}, + {240, L"ERROR_VC_DISCONNECTED"}, + {254, L"ERROR_INVALID_EA_NAME"}, + {255, L"ERROR_EA_LIST_INCONSISTENT"}, + {258, L"WAIT_TIMEOUT"}, + {259, L"ERROR_NO_MORE_ITEMS"}, + {266, L"ERROR_CANNOT_COPY"}, + {267, L"ERROR_DIRECTORY"}, + {275, L"ERROR_EAS_DIDNT_FIT"}, + {276, L"ERROR_EA_FILE_CORRUPT"}, + {277, L"ERROR_EA_TABLE_FULL"}, + {278, L"ERROR_INVALID_EA_HANDLE"}, + {282, L"ERROR_EAS_NOT_SUPPORTED"}, + {288, L"ERROR_NOT_OWNER"}, + {298, L"ERROR_TOO_MANY_POSTS"}, + {299, L"ERROR_PARTIAL_COPY"}, + {300, L"ERROR_OPLOCK_NOT_GRANTED"}, + {301, L"ERROR_INVALID_OPLOCK_PROTOCOL"}, + {302, L"ERROR_DISK_TOO_FRAGMENTED"}, + {303, L"ERROR_DELETE_PENDING"}, + {304, L"ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING"}, + {305, L"ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME"}, + {306, L"ERROR_SECURITY_STREAM_IS_INCONSISTENT"}, + {307, L"ERROR_INVALID_LOCK_RANGE"}, + {308, L"ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT"}, + {309, L"ERROR_NOTIFICATION_GUID_ALREADY_DEFINED"}, + {310, L"ERROR_INVALID_EXCEPTION_HANDLER"}, + {311, L"ERROR_DUPLICATE_PRIVILEGES"}, + {312, L"ERROR_NO_RANGES_PROCESSED"}, + {313, L"ERROR_NOT_ALLOWED_ON_SYSTEM_FILE"}, + {314, L"ERROR_DISK_RESOURCES_EXHAUSTED"}, + {315, L"ERROR_INVALID_TOKEN"}, + {316, L"ERROR_DEVICE_FEATURE_NOT_SUPPORTED"}, + {317, L"ERROR_MR_MID_NOT_FOUND"}, + {318, L"ERROR_SCOPE_NOT_FOUND"}, + {319, L"ERROR_UNDEFINED_SCOPE"}, + {320, L"ERROR_INVALID_CAP"}, + {321, L"ERROR_DEVICE_UNREACHABLE"}, + {322, L"ERROR_DEVICE_NO_RESOURCES"}, + {323, L"ERROR_DATA_CHECKSUM_ERROR"}, + {324, L"ERROR_INTERMIXED_KERNEL_EA_OPERATION"}, + {326, L"ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED"}, + {327, L"ERROR_OFFSET_ALIGNMENT_VIOLATION"}, + {328, L"ERROR_INVALID_FIELD_IN_PARAMETER_LIST"}, + {329, L"ERROR_OPERATION_IN_PROGRESS"}, + {330, L"ERROR_BAD_DEVICE_PATH"}, + {331, L"ERROR_TOO_MANY_DESCRIPTORS"}, + {332, L"ERROR_SCRUB_DATA_DISABLED"}, + {333, L"ERROR_NOT_REDUNDANT_STORAGE"}, + {334, L"ERROR_RESIDENT_FILE_NOT_SUPPORTED"}, + {335, L"ERROR_COMPRESSED_FILE_NOT_SUPPORTED"}, + {336, L"ERROR_DIRECTORY_NOT_SUPPORTED"}, + {337, L"ERROR_NOT_READ_FROM_COPY"}, + {350, L"ERROR_FAIL_NOACTION_REBOOT"}, + {351, L"ERROR_FAIL_SHUTDOWN"}, + {352, L"ERROR_FAIL_RESTART"}, + {353, L"ERROR_MAX_SESSIONS_REACHED"}, + {400, L"ERROR_THREAD_MODE_ALREADY_BACKGROUND"}, + {401, L"ERROR_THREAD_MODE_NOT_BACKGROUND"}, + {402, L"ERROR_PROCESS_MODE_ALREADY_BACKGROUND"}, + {403, L"ERROR_PROCESS_MODE_NOT_BACKGROUND"}, + {487, L"ERROR_INVALID_ADDRESS"}, + {500, L"ERROR_USER_PROFILE_LOAD"}, + {534, L"ERROR_ARITHMETIC_OVERFLOW"}, + {535, L"ERROR_PIPE_CONNECTED"}, + {536, L"ERROR_PIPE_LISTENING"}, + {537, L"ERROR_VERIFIER_STOP"}, + {538, L"ERROR_ABIOS_ERROR"}, + {539, L"ERROR_WX86_WARNING"}, + {540, L"ERROR_WX86_ERROR"}, + {541, L"ERROR_TIMER_NOT_CANCELED"}, + {542, L"ERROR_UNWIND"}, + {543, L"ERROR_BAD_STACK"}, + {544, L"ERROR_INVALID_UNWIND_TARGET"}, + {545, L"ERROR_INVALID_PORT_ATTRIBUTES"}, + {546, L"ERROR_PORT_MESSAGE_TOO_LONG"}, + {547, L"ERROR_INVALID_QUOTA_LOWER"}, + {548, L"ERROR_DEVICE_ALREADY_ATTACHED"}, + {549, L"ERROR_INSTRUCTION_MISALIGNMENT"}, + {550, L"ERROR_PROFILING_NOT_STARTED"}, + {551, L"ERROR_PROFILING_NOT_STOPPED"}, + {552, L"ERROR_COULD_NOT_INTERPRET"}, + {553, L"ERROR_PROFILING_AT_LIMIT"}, + {554, L"ERROR_CANT_WAIT"}, + {555, L"ERROR_CANT_TERMINATE_SELF"}, + {556, L"ERROR_UNEXPECTED_MM_CREATE_ERR"}, + {557, L"ERROR_UNEXPECTED_MM_MAP_ERROR"}, + {558, L"ERROR_UNEXPECTED_MM_EXTEND_ERR"}, + {559, L"ERROR_BAD_FUNCTION_TABLE"}, + {560, L"ERROR_NO_GUID_TRANSLATION"}, + {561, L"ERROR_INVALID_LDT_SIZE"}, + {563, L"ERROR_INVALID_LDT_OFFSET"}, + {564, L"ERROR_INVALID_LDT_DESCRIPTOR"}, + {565, L"ERROR_TOO_MANY_THREADS"}, + {566, L"ERROR_THREAD_NOT_IN_PROCESS"}, + {567, L"ERROR_PAGEFILE_QUOTA_EXCEEDED"}, + {568, L"ERROR_LOGON_SERVER_CONFLICT"}, + {569, L"ERROR_SYNCHRONIZATION_REQUIRED"}, + {570, L"ERROR_NET_OPEN_FAILED"}, + {571, L"ERROR_IO_PRIVILEGE_FAILED"}, + {572, L"ERROR_CONTROL_C_EXIT"}, + {573, L"ERROR_MISSING_SYSTEMFILE"}, + {574, L"ERROR_UNHANDLED_EXCEPTION"}, + {575, L"ERROR_APP_INIT_FAILURE"}, + {576, L"ERROR_PAGEFILE_CREATE_FAILED"}, + {577, L"ERROR_INVALID_IMAGE_HASH"}, + {578, L"ERROR_NO_PAGEFILE"}, + {579, L"ERROR_ILLEGAL_FLOAT_CONTEXT"}, + {580, L"ERROR_NO_EVENT_PAIR"}, + {581, L"ERROR_DOMAIN_CTRLR_CONFIG_ERROR"}, + {582, L"ERROR_ILLEGAL_CHARACTER"}, + {583, L"ERROR_UNDEFINED_CHARACTER"}, + {584, L"ERROR_FLOPPY_VOLUME"}, + {585, L"ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT"}, + {586, L"ERROR_BACKUP_CONTROLLER"}, + {587, L"ERROR_MUTANT_LIMIT_EXCEEDED"}, + {588, L"ERROR_FS_DRIVER_REQUIRED"}, + {589, L"ERROR_CANNOT_LOAD_REGISTRY_FILE"}, + {590, L"ERROR_DEBUG_ATTACH_FAILED"}, + {591, L"ERROR_SYSTEM_PROCESS_TERMINATED"}, + {592, L"ERROR_DATA_NOT_ACCEPTED"}, + {593, L"ERROR_VDM_HARD_ERROR"}, + {594, L"ERROR_DRIVER_CANCEL_TIMEOUT"}, + {595, L"ERROR_REPLY_MESSAGE_MISMATCH"}, + {596, L"ERROR_LOST_WRITEBEHIND_DATA"}, + {597, L"ERROR_CLIENT_SERVER_PARAMETERS_INVALID"}, + {598, L"ERROR_NOT_TINY_STREAM"}, + {599, L"ERROR_STACK_OVERFLOW_READ"}, + {600, L"ERROR_CONVERT_TO_LARGE"}, + {601, L"ERROR_FOUND_OUT_OF_SCOPE"}, + {602, L"ERROR_ALLOCATE_BUCKET"}, + {603, L"ERROR_MARSHALL_OVERFLOW"}, + {604, L"ERROR_INVALID_VARIANT"}, + {605, L"ERROR_BAD_COMPRESSION_BUFFER"}, + {606, L"ERROR_AUDIT_FAILED"}, + {607, L"ERROR_TIMER_RESOLUTION_NOT_SET"}, + {608, L"ERROR_INSUFFICIENT_LOGON_INFO"}, + {609, L"ERROR_BAD_DLL_ENTRYPOINT"}, + {610, L"ERROR_BAD_SERVICE_ENTRYPOINT"}, + {611, L"ERROR_IP_ADDRESS_CONFLICT1"}, + {612, L"ERROR_IP_ADDRESS_CONFLICT2"}, + {613, L"ERROR_REGISTRY_QUOTA_LIMIT"}, + {614, L"ERROR_NO_CALLBACK_ACTIVE"}, + {615, L"ERROR_PWD_TOO_SHORT"}, + {616, L"ERROR_PWD_TOO_RECENT"}, + {617, L"ERROR_PWD_HISTORY_CONFLICT"}, + {618, L"ERROR_UNSUPPORTED_COMPRESSION"}, + {619, L"ERROR_INVALID_HW_PROFILE"}, + {620, L"ERROR_INVALID_PLUGPLAY_DEVICE_PATH"}, + {621, L"ERROR_QUOTA_LIST_INCONSISTENT"}, + {622, L"ERROR_EVALUATION_EXPIRATION"}, + {623, L"ERROR_ILLEGAL_DLL_RELOCATION"}, + {624, L"ERROR_DLL_INIT_FAILED_LOGOFF"}, + {625, L"ERROR_VALIDATE_CONTINUE"}, + {626, L"ERROR_NO_MORE_MATCHES"}, + {627, L"ERROR_RANGE_LIST_CONFLICT"}, + {628, L"ERROR_SERVER_SID_MISMATCH"}, + {629, L"ERROR_CANT_ENABLE_DENY_ONLY"}, + {630, L"ERROR_FLOAT_MULTIPLE_FAULTS"}, + {631, L"ERROR_FLOAT_MULTIPLE_TRAPS"}, + {632, L"ERROR_NOINTERFACE"}, + {633, L"ERROR_DRIVER_FAILED_SLEEP"}, + {634, L"ERROR_CORRUPT_SYSTEM_FILE"}, + {635, L"ERROR_COMMITMENT_MINIMUM"}, + {636, L"ERROR_PNP_RESTART_ENUMERATION"}, + {637, L"ERROR_SYSTEM_IMAGE_BAD_SIGNATURE"}, + {638, L"ERROR_PNP_REBOOT_REQUIRED"}, + {639, L"ERROR_INSUFFICIENT_POWER"}, + {640, L"ERROR_MULTIPLE_FAULT_VIOLATION"}, + {641, L"ERROR_SYSTEM_SHUTDOWN"}, + {642, L"ERROR_PORT_NOT_SET"}, + {643, L"ERROR_DS_VERSION_CHECK_FAILURE"}, + {644, L"ERROR_RANGE_NOT_FOUND"}, + {646, L"ERROR_NOT_SAFE_MODE_DRIVER"}, + {647, L"ERROR_FAILED_DRIVER_ENTRY"}, + {648, L"ERROR_DEVICE_ENUMERATION_ERROR"}, + {649, L"ERROR_MOUNT_POINT_NOT_RESOLVED"}, + {650, L"ERROR_INVALID_DEVICE_OBJECT_PARAMETER"}, + {651, L"ERROR_MCA_OCCURED"}, + {652, L"ERROR_DRIVER_DATABASE_ERROR"}, + {653, L"ERROR_SYSTEM_HIVE_TOO_LARGE"}, + {654, L"ERROR_DRIVER_FAILED_PRIOR_UNLOAD"}, + {655, L"ERROR_VOLSNAP_PREPARE_HIBERNATE"}, + {656, L"ERROR_HIBERNATION_FAILURE"}, + {657, L"ERROR_PWD_TOO_LONG"}, + {665, L"ERROR_FILE_SYSTEM_LIMITATION"}, + {668, L"ERROR_ASSERTION_FAILURE"}, + {669, L"ERROR_ACPI_ERROR"}, + {670, L"ERROR_WOW_ASSERTION"}, + {671, L"ERROR_PNP_BAD_MPS_TABLE"}, + {672, L"ERROR_PNP_TRANSLATION_FAILED"}, + {673, L"ERROR_PNP_IRQ_TRANSLATION_FAILED"}, + {674, L"ERROR_PNP_INVALID_ID"}, + {675, L"ERROR_WAKE_SYSTEM_DEBUGGER"}, + {676, L"ERROR_HANDLES_CLOSED"}, + {677, L"ERROR_EXTRANEOUS_INFORMATION"}, + {678, L"ERROR_RXACT_COMMIT_NECESSARY"}, + {679, L"ERROR_MEDIA_CHECK"}, + {680, L"ERROR_GUID_SUBSTITUTION_MADE"}, + {681, L"ERROR_STOPPED_ON_SYMLINK"}, + {682, L"ERROR_LONGJUMP"}, + {683, L"ERROR_PLUGPLAY_QUERY_VETOED"}, + {684, L"ERROR_UNWIND_CONSOLIDATE"}, + {685, L"ERROR_REGISTRY_HIVE_RECOVERED"}, + {686, L"ERROR_DLL_MIGHT_BE_INSECURE"}, + {687, L"ERROR_DLL_MIGHT_BE_INCOMPATIBLE"}, + {688, L"ERROR_DBG_EXCEPTION_NOT_HANDLED"}, + {689, L"ERROR_DBG_REPLY_LATER"}, + {690, L"ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE"}, + {691, L"ERROR_DBG_TERMINATE_THREAD"}, + {692, L"ERROR_DBG_TERMINATE_PROCESS"}, + {693, L"ERROR_DBG_CONTROL_C"}, + {694, L"ERROR_DBG_PRINTEXCEPTION_C"}, + {695, L"ERROR_DBG_RIPEXCEPTION"}, + {696, L"ERROR_DBG_CONTROL_BREAK"}, + {697, L"ERROR_DBG_COMMAND_EXCEPTION"}, + {698, L"ERROR_OBJECT_NAME_EXISTS"}, + {699, L"ERROR_THREAD_WAS_SUSPENDED"}, + {700, L"ERROR_IMAGE_NOT_AT_BASE"}, + {701, L"ERROR_RXACT_STATE_CREATED"}, + {702, L"ERROR_SEGMENT_NOTIFICATION"}, + {703, L"ERROR_BAD_CURRENT_DIRECTORY"}, + {704, L"ERROR_FT_READ_RECOVERY_FROM_BACKUP"}, + {705, L"ERROR_FT_WRITE_RECOVERY"}, + {706, L"ERROR_IMAGE_MACHINE_TYPE_MISMATCH"}, + {707, L"ERROR_RECEIVE_PARTIAL"}, + {708, L"ERROR_RECEIVE_EXPEDITED"}, + {709, L"ERROR_RECEIVE_PARTIAL_EXPEDITED"}, + {710, L"ERROR_EVENT_DONE"}, + {711, L"ERROR_EVENT_PENDING"}, + {712, L"ERROR_CHECKING_FILE_SYSTEM"}, + {713, L"ERROR_FATAL_APP_EXIT"}, + {714, L"ERROR_PREDEFINED_HANDLE"}, + {715, L"ERROR_WAS_UNLOCKED"}, + {716, L"ERROR_SERVICE_NOTIFICATION"}, + {717, L"ERROR_WAS_LOCKED"}, + {718, L"ERROR_LOG_HARD_ERROR"}, + {719, L"ERROR_ALREADY_WIN32"}, + {720, L"ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE"}, + {721, L"ERROR_NO_YIELD_PERFORMED"}, + {722, L"ERROR_TIMER_RESUME_IGNORED"}, + {723, L"ERROR_ARBITRATION_UNHANDLED"}, + {724, L"ERROR_CARDBUS_NOT_SUPPORTED"}, + {725, L"ERROR_MP_PROCESSOR_MISMATCH"}, + {726, L"ERROR_HIBERNATED"}, + {727, L"ERROR_RESUME_HIBERNATION"}, + {728, L"ERROR_FIRMWARE_UPDATED"}, + {729, L"ERROR_DRIVERS_LEAKING_LOCKED_PAGES"}, + {730, L"ERROR_WAKE_SYSTEM"}, + {731, L"ERROR_WAIT_1"}, + {732, L"ERROR_WAIT_2"}, + {733, L"ERROR_WAIT_3"}, + {734, L"ERROR_WAIT_63"}, + {735, L"ERROR_ABANDONED_WAIT_0"}, + {736, L"ERROR_ABANDONED_WAIT_63"}, + {737, L"ERROR_USER_APC"}, + {738, L"ERROR_KERNEL_APC"}, + {739, L"ERROR_ALERTED"}, + {740, L"ERROR_ELEVATION_REQUIRED"}, + {741, L"ERROR_REPARSE"}, + {742, L"ERROR_OPLOCK_BREAK_IN_PROGRESS"}, + {743, L"ERROR_VOLUME_MOUNTED"}, + {744, L"ERROR_RXACT_COMMITTED"}, + {745, L"ERROR_NOTIFY_CLEANUP"}, + {746, L"ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED"}, + {747, L"ERROR_PAGE_FAULT_TRANSITION"}, + {748, L"ERROR_PAGE_FAULT_DEMAND_ZERO"}, + {749, L"ERROR_PAGE_FAULT_COPY_ON_WRITE"}, + {750, L"ERROR_PAGE_FAULT_GUARD_PAGE"}, + {751, L"ERROR_PAGE_FAULT_PAGING_FILE"}, + {752, L"ERROR_CACHE_PAGE_LOCKED"}, + {753, L"ERROR_CRASH_DUMP"}, + {754, L"ERROR_BUFFER_ALL_ZEROS"}, + {755, L"ERROR_REPARSE_OBJECT"}, + {756, L"ERROR_RESOURCE_REQUIREMENTS_CHANGED"}, + {757, L"ERROR_TRANSLATION_COMPLETE"}, + {758, L"ERROR_NOTHING_TO_TERMINATE"}, + {759, L"ERROR_PROCESS_NOT_IN_JOB"}, + {760, L"ERROR_PROCESS_IN_JOB"}, + {761, L"ERROR_VOLSNAP_HIBERNATE_READY"}, + {762, L"ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY"}, + {763, L"ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED"}, + {764, L"ERROR_INTERRUPT_STILL_CONNECTED"}, + {765, L"ERROR_WAIT_FOR_OPLOCK"}, + {766, L"ERROR_DBG_EXCEPTION_HANDLED"}, + {767, L"ERROR_DBG_CONTINUE"}, + {768, L"ERROR_CALLBACK_POP_STACK"}, + {769, L"ERROR_COMPRESSION_DISABLED"}, + {770, L"ERROR_CANTFETCHBACKWARDS"}, + {771, L"ERROR_CANTSCROLLBACKWARDS"}, + {772, L"ERROR_ROWSNOTRELEASED"}, + {773, L"ERROR_BAD_ACCESSOR_FLAGS"}, + {774, L"ERROR_ERRORS_ENCOUNTERED"}, + {775, L"ERROR_NOT_CAPABLE"}, + {776, L"ERROR_REQUEST_OUT_OF_SEQUENCE"}, + {777, L"ERROR_VERSION_PARSE_ERROR"}, + {778, L"ERROR_BADSTARTPOSITION"}, + {779, L"ERROR_MEMORY_HARDWARE"}, + {780, L"ERROR_DISK_REPAIR_DISABLED"}, + {781, L"ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE"}, + {782, L"ERROR_SYSTEM_POWERSTATE_TRANSITION"}, + {783, L"ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION"}, + {784, L"ERROR_MCA_EXCEPTION"}, + {785, L"ERROR_ACCESS_AUDIT_BY_POLICY"}, + {786, L"ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY"}, + {787, L"ERROR_ABANDON_HIBERFILE"}, + {788, L"ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED"}, + {789, L"ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR"}, + {790, L"ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR"}, + {791, L"ERROR_BAD_MCFG_TABLE"}, + {792, L"ERROR_DISK_REPAIR_REDIRECTED"}, + {793, L"ERROR_DISK_REPAIR_UNSUCCESSFUL"}, + {794, L"ERROR_CORRUPT_LOG_OVERFULL"}, + {795, L"ERROR_CORRUPT_LOG_CORRUPTED"}, + {796, L"ERROR_CORRUPT_LOG_UNAVAILABLE"}, + {797, L"ERROR_CORRUPT_LOG_DELETED_FULL"}, + {798, L"ERROR_CORRUPT_LOG_CLEARED"}, + {799, L"ERROR_ORPHAN_NAME_EXHAUSTED"}, + {800, L"ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE"}, + {801, L"ERROR_CANNOT_GRANT_REQUESTED_OPLOCK"}, + {802, L"ERROR_CANNOT_BREAK_OPLOCK"}, + {803, L"ERROR_OPLOCK_HANDLE_CLOSED"}, + {804, L"ERROR_NO_ACE_CONDITION"}, + {805, L"ERROR_INVALID_ACE_CONDITION"}, + {806, L"ERROR_FILE_HANDLE_REVOKED"}, + {807, L"ERROR_IMAGE_AT_DIFFERENT_BASE"}, + {994, L"ERROR_EA_ACCESS_DENIED"}, + {995, L"ERROR_OPERATION_ABORTED"}, + {996, L"ERROR_IO_INCOMPLETE"}, + {997, L"ERROR_IO_PENDING"}, + {998, L"ERROR_NOACCESS"}, + {999, L"ERROR_SWAPERROR"}, + {1001, L"ERROR_STACK_OVERFLOW"}, + {1002, L"ERROR_INVALID_MESSAGE"}, + {1003, L"ERROR_CAN_NOT_COMPLETE"}, + {1004, L"ERROR_INVALID_FLAGS"}, + {1005, L"ERROR_UNRECOGNIZED_VOLUME"}, + {1006, L"ERROR_FILE_INVALID"}, + {1007, L"ERROR_FULLSCREEN_MODE"}, + {1008, L"ERROR_NO_TOKEN"}, + {1009, L"ERROR_BADDB"}, + {1010, L"ERROR_BADKEY"}, + {1011, L"ERROR_CANTOPEN"}, + {1012, L"ERROR_CANTREAD"}, + {1013, L"ERROR_CANTWRITE"}, + {1014, L"ERROR_REGISTRY_RECOVERED"}, + {1015, L"ERROR_REGISTRY_CORRUPT"}, + {1016, L"ERROR_REGISTRY_IO_FAILED"}, + {1017, L"ERROR_NOT_REGISTRY_FILE"}, + {1018, L"ERROR_KEY_DELETED"}, + {1019, L"ERROR_NO_LOG_SPACE"}, + {1020, L"ERROR_KEY_HAS_CHILDREN"}, + {1021, L"ERROR_CHILD_MUST_BE_VOLATILE"}, + {1022, L"ERROR_NOTIFY_ENUM_DIR"}, + {1051, L"ERROR_DEPENDENT_SERVICES_RUNNING"}, + {1052, L"ERROR_INVALID_SERVICE_CONTROL"}, + {1053, L"ERROR_SERVICE_REQUEST_TIMEOUT"}, + {1054, L"ERROR_SERVICE_NO_THREAD"}, + {1055, L"ERROR_SERVICE_DATABASE_LOCKED"}, + {1056, L"ERROR_SERVICE_ALREADY_RUNNING"}, + {1057, L"ERROR_INVALID_SERVICE_ACCOUNT"}, + {1058, L"ERROR_SERVICE_DISABLED"}, + {1059, L"ERROR_CIRCULAR_DEPENDENCY"}, + {1060, L"ERROR_SERVICE_DOES_NOT_EXIST"}, + {1061, L"ERROR_SERVICE_CANNOT_ACCEPT_CTRL"}, + {1062, L"ERROR_SERVICE_NOT_ACTIVE"}, + {1063, L"ERROR_FAILED_SERVICE_CONTROLLER_CONNECT"}, + {1064, L"ERROR_EXCEPTION_IN_SERVICE"}, + {1065, L"ERROR_DATABASE_DOES_NOT_EXIST"}, + {1066, L"ERROR_SERVICE_SPECIFIC_ERROR"}, + {1067, L"ERROR_PROCESS_ABORTED"}, + {1068, L"ERROR_SERVICE_DEPENDENCY_FAIL"}, + {1069, L"ERROR_SERVICE_LOGON_FAILED"}, + {1070, L"ERROR_SERVICE_START_HANG"}, + {1071, L"ERROR_INVALID_SERVICE_LOCK"}, + {1072, L"ERROR_SERVICE_MARKED_FOR_DELETE"}, + {1073, L"ERROR_SERVICE_EXISTS"}, + {1074, L"ERROR_ALREADY_RUNNING_LKG"}, + {1075, L"ERROR_SERVICE_DEPENDENCY_DELETED"}, + {1076, L"ERROR_BOOT_ALREADY_ACCEPTED"}, + {1077, L"ERROR_SERVICE_NEVER_STARTED"}, + {1078, L"ERROR_DUPLICATE_SERVICE_NAME"}, + {1079, L"ERROR_DIFFERENT_SERVICE_ACCOUNT"}, + {1080, L"ERROR_CANNOT_DETECT_DRIVER_FAILURE"}, + {1081, L"ERROR_CANNOT_DETECT_PROCESS_ABORT"}, + {1082, L"ERROR_NO_RECOVERY_PROGRAM"}, + {1083, L"ERROR_SERVICE_NOT_IN_EXE"}, + {1084, L"ERROR_NOT_SAFEBOOT_SERVICE"}, + {1100, L"ERROR_END_OF_MEDIA"}, + {1101, L"ERROR_FILEMARK_DETECTED"}, + {1102, L"ERROR_BEGINNING_OF_MEDIA"}, + {1103, L"ERROR_SETMARK_DETECTED"}, + {1104, L"ERROR_NO_DATA_DETECTED"}, + {1105, L"ERROR_PARTITION_FAILURE"}, + {1106, L"ERROR_INVALID_BLOCK_LENGTH"}, + {1107, L"ERROR_DEVICE_NOT_PARTITIONED"}, + {1108, L"ERROR_UNABLE_TO_LOCK_MEDIA"}, + {1109, L"ERROR_UNABLE_TO_UNLOAD_MEDIA"}, + {1110, L"ERROR_MEDIA_CHANGED"}, + {1111, L"ERROR_BUS_RESET"}, + {1112, L"ERROR_NO_MEDIA_IN_DRIVE"}, + {1113, L"ERROR_NO_UNICODE_TRANSLATION"}, + {1114, L"ERROR_DLL_INIT_FAILED"}, + {1115, L"ERROR_SHUTDOWN_IN_PROGRESS"}, + {1116, L"ERROR_NO_SHUTDOWN_IN_PROGRESS"}, + {1117, L"ERROR_IO_DEVICE"}, + {1118, L"ERROR_SERIAL_NO_DEVICE"}, + {1119, L"ERROR_IRQ_BUSY"}, + {1120, L"ERROR_MORE_WRITES"}, + {1121, L"ERROR_COUNTER_TIMEOUT"}, + {1122, L"ERROR_FLOPPY_ID_MARK_NOT_FOUND"}, + {1123, L"ERROR_FLOPPY_WRONG_CYLINDER"}, + {1124, L"ERROR_FLOPPY_UNKNOWN_ERROR"}, + {1125, L"ERROR_FLOPPY_BAD_REGISTERS"}, + {1126, L"ERROR_DISK_RECALIBRATE_FAILED"}, + {1127, L"ERROR_DISK_OPERATION_FAILED"}, + {1128, L"ERROR_DISK_RESET_FAILED"}, + {1129, L"ERROR_EOM_OVERFLOW"}, + {1130, L"ERROR_NOT_ENOUGH_SERVER_MEMORY"}, + {1131, L"ERROR_POSSIBLE_DEADLOCK"}, + {1132, L"ERROR_MAPPED_ALIGNMENT"}, + {1140, L"ERROR_SET_POWER_STATE_VETOED"}, + {1141, L"ERROR_SET_POWER_STATE_FAILED"}, + {1142, L"ERROR_TOO_MANY_LINKS"}, + {1150, L"ERROR_OLD_WIN_VERSION"}, + {1151, L"ERROR_APP_WRONG_OS"}, + {1152, L"ERROR_SINGLE_INSTANCE_APP"}, + {1153, L"ERROR_RMODE_APP"}, + {1154, L"ERROR_INVALID_DLL"}, + {1155, L"ERROR_NO_ASSOCIATION"}, + {1156, L"ERROR_DDE_FAIL"}, + {1157, L"ERROR_DLL_NOT_FOUND"}, + {1158, L"ERROR_NO_MORE_USER_HANDLES"}, + {1159, L"ERROR_MESSAGE_SYNC_ONLY"}, + {1160, L"ERROR_SOURCE_ELEMENT_EMPTY"}, + {1161, L"ERROR_DESTINATION_ELEMENT_FULL"}, + {1162, L"ERROR_ILLEGAL_ELEMENT_ADDRESS"}, + {1163, L"ERROR_MAGAZINE_NOT_PRESENT"}, + {1164, L"ERROR_DEVICE_REINITIALIZATION_NEEDED"}, + {1165, L"ERROR_DEVICE_REQUIRES_CLEANING"}, + {1166, L"ERROR_DEVICE_DOOR_OPEN"}, + {1167, L"ERROR_DEVICE_NOT_CONNECTED"}, + {1168, L"ERROR_NOT_FOUND"}, + {1169, L"ERROR_NO_MATCH"}, + {1170, L"ERROR_SET_NOT_FOUND"}, + {1171, L"ERROR_POINT_NOT_FOUND"}, + {1172, L"ERROR_NO_TRACKING_SERVICE"}, + {1173, L"ERROR_NO_VOLUME_ID"}, + {1175, L"ERROR_UNABLE_TO_REMOVE_REPLACED"}, + {1176, L"ERROR_UNABLE_TO_MOVE_REPLACEMENT"}, + {1177, L"ERROR_UNABLE_TO_MOVE_REPLACEMENT_2"}, + {1178, L"ERROR_JOURNAL_DELETE_IN_PROGRESS"}, + {1179, L"ERROR_JOURNAL_NOT_ACTIVE"}, + {1180, L"ERROR_POTENTIAL_FILE_FOUND"}, + {1181, L"ERROR_JOURNAL_ENTRY_DELETED"}, + {1190, L"ERROR_SHUTDOWN_IS_SCHEDULED"}, + {1191, L"ERROR_SHUTDOWN_USERS_LOGGED_ON"}, + {1200, L"ERROR_BAD_DEVICE"}, + {1201, L"ERROR_CONNECTION_UNAVAIL"}, + {1202, L"ERROR_DEVICE_ALREADY_REMEMBERED"}, + {1203, L"ERROR_NO_NET_OR_BAD_PATH"}, + {1204, L"ERROR_BAD_PROVIDER"}, + {1205, L"ERROR_CANNOT_OPEN_PROFILE"}, + {1206, L"ERROR_BAD_PROFILE"}, + {1207, L"ERROR_NOT_CONTAINER"}, + {1208, L"ERROR_EXTENDED_ERROR"}, + {1209, L"ERROR_INVALID_GROUPNAME"}, + {1210, L"ERROR_INVALID_COMPUTERNAME"}, + {1211, L"ERROR_INVALID_EVENTNAME"}, + {1212, L"ERROR_INVALID_DOMAINNAME"}, + {1213, L"ERROR_INVALID_SERVICENAME"}, + {1214, L"ERROR_INVALID_NETNAME"}, + {1215, L"ERROR_INVALID_SHARENAME"}, + {1216, L"ERROR_INVALID_PASSWORDNAME"}, + {1217, L"ERROR_INVALID_MESSAGENAME"}, + {1218, L"ERROR_INVALID_MESSAGEDEST"}, + {1219, L"ERROR_SESSION_CREDENTIAL_CONFLICT"}, + {1220, L"ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"}, + {1221, L"ERROR_DUP_DOMAINNAME"}, + {1222, L"ERROR_NO_NETWORK"}, + {1223, L"ERROR_CANCELLED"}, + {1224, L"ERROR_USER_MAPPED_FILE"}, + {1225, L"ERROR_CONNECTION_REFUSED"}, + {1226, L"ERROR_GRACEFUL_DISCONNECT"}, + {1227, L"ERROR_ADDRESS_ALREADY_ASSOCIATED"}, + {1228, L"ERROR_ADDRESS_NOT_ASSOCIATED"}, + {1229, L"ERROR_CONNECTION_INVALID"}, + {1230, L"ERROR_CONNECTION_ACTIVE"}, + {1231, L"ERROR_NETWORK_UNREACHABLE"}, + {1232, L"ERROR_HOST_UNREACHABLE"}, + {1233, L"ERROR_PROTOCOL_UNREACHABLE"}, + {1234, L"ERROR_PORT_UNREACHABLE"}, + {1235, L"ERROR_REQUEST_ABORTED"}, + {1236, L"ERROR_CONNECTION_ABORTED"}, + {1237, L"ERROR_RETRY"}, + {1238, L"ERROR_CONNECTION_COUNT_LIMIT"}, + {1239, L"ERROR_LOGIN_TIME_RESTRICTION"}, + {1240, L"ERROR_LOGIN_WKSTA_RESTRICTION"}, + {1241, L"ERROR_INCORRECT_ADDRESS"}, + {1242, L"ERROR_ALREADY_REGISTERED"}, + {1243, L"ERROR_SERVICE_NOT_FOUND"}, + {1244, L"ERROR_NOT_AUTHENTICATED"}, + {1245, L"ERROR_NOT_LOGGED_ON"}, + {1246, L"ERROR_CONTINUE"}, + {1247, L"ERROR_ALREADY_INITIALIZED"}, + {1248, L"ERROR_NO_MORE_DEVICES"}, + {1249, L"ERROR_NO_SUCH_SITE"}, + {1250, L"ERROR_DOMAIN_CONTROLLER_EXISTS"}, + {1251, L"ERROR_ONLY_IF_CONNECTED"}, + {1252, L"ERROR_OVERRIDE_NOCHANGES"}, + {1253, L"ERROR_BAD_USER_PROFILE"}, + {1254, L"ERROR_NOT_SUPPORTED_ON_SBS"}, + {1255, L"ERROR_SERVER_SHUTDOWN_IN_PROGRESS"}, + {1256, L"ERROR_HOST_DOWN"}, + {1257, L"ERROR_NON_ACCOUNT_SID"}, + {1258, L"ERROR_NON_DOMAIN_SID"}, + {1259, L"ERROR_APPHELP_BLOCK"}, + {1260, L"ERROR_ACCESS_DISABLED_BY_POLICY"}, + {1261, L"ERROR_REG_NAT_CONSUMPTION"}, + {1262, L"ERROR_CSCSHARE_OFFLINE"}, + {1263, L"ERROR_PKINIT_FAILURE"}, + {1264, L"ERROR_SMARTCARD_SUBSYSTEM_FAILURE"}, + {1265, L"ERROR_DOWNGRADE_DETECTED"}, + {1271, L"ERROR_MACHINE_LOCKED"}, + {1273, L"ERROR_CALLBACK_SUPPLIED_INVALID_DATA"}, + {1274, L"ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED"}, + {1275, L"ERROR_DRIVER_BLOCKED"}, + {1276, L"ERROR_INVALID_IMPORT_OF_NON_DLL"}, + {1277, L"ERROR_ACCESS_DISABLED_WEBBLADE"}, + {1278, L"ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER"}, + {1279, L"ERROR_RECOVERY_FAILURE"}, + {1280, L"ERROR_ALREADY_FIBER"}, + {1281, L"ERROR_ALREADY_THREAD"}, + {1282, L"ERROR_STACK_BUFFER_OVERRUN"}, + {1283, L"ERROR_PARAMETER_QUOTA_EXCEEDED"}, + {1284, L"ERROR_DEBUGGER_INACTIVE"}, + {1285, L"ERROR_DELAY_LOAD_FAILED"}, + {1286, L"ERROR_VDM_DISALLOWED"}, + {1287, L"ERROR_UNIDENTIFIED_ERROR"}, + {1288, L"ERROR_INVALID_CRUNTIME_PARAMETER"}, + {1289, L"ERROR_BEYOND_VDL"}, + {1290, L"ERROR_INCOMPATIBLE_SERVICE_SID_TYPE"}, + {1291, L"ERROR_DRIVER_PROCESS_TERMINATED"}, + {1292, L"ERROR_IMPLEMENTATION_LIMIT"}, + {1293, L"ERROR_PROCESS_IS_PROTECTED"}, + {1294, L"ERROR_SERVICE_NOTIFY_CLIENT_LAGGING"}, + {1295, L"ERROR_DISK_QUOTA_EXCEEDED"}, + {1296, L"ERROR_CONTENT_BLOCKED"}, + {1297, L"ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE"}, + {1298, L"ERROR_APP_HANG"}, + {1299, L"ERROR_INVALID_LABEL"}, + {1300, L"ERROR_NOT_ALL_ASSIGNED"}, + {1301, L"ERROR_SOME_NOT_MAPPED"}, + {1302, L"ERROR_NO_QUOTAS_FOR_ACCOUNT"}, + {1303, L"ERROR_LOCAL_USER_SESSION_KEY"}, + {1304, L"ERROR_NULL_LM_PASSWORD"}, + {1305, L"ERROR_UNKNOWN_REVISION"}, + {1306, L"ERROR_REVISION_MISMATCH"}, + {1307, L"ERROR_INVALID_OWNER"}, + {1308, L"ERROR_INVALID_PRIMARY_GROUP"}, + {1309, L"ERROR_NO_IMPERSONATION_TOKEN"}, + {1310, L"ERROR_CANT_DISABLE_MANDATORY"}, + {1311, L"ERROR_NO_LOGON_SERVERS"}, + {1312, L"ERROR_NO_SUCH_LOGON_SESSION"}, + {1313, L"ERROR_NO_SUCH_PRIVILEGE"}, + {1314, L"ERROR_PRIVILEGE_NOT_HELD"}, + {1315, L"ERROR_INVALID_ACCOUNT_NAME"}, + {1316, L"ERROR_USER_EXISTS"}, + {1317, L"ERROR_NO_SUCH_USER"}, + {1318, L"ERROR_GROUP_EXISTS"}, + {1319, L"ERROR_NO_SUCH_GROUP"}, + {1320, L"ERROR_MEMBER_IN_GROUP"}, + {1321, L"ERROR_MEMBER_NOT_IN_GROUP"}, + {1322, L"ERROR_LAST_ADMIN"}, + {1323, L"ERROR_WRONG_PASSWORD"}, + {1324, L"ERROR_ILL_FORMED_PASSWORD"}, + {1325, L"ERROR_PASSWORD_RESTRICTION"}, + {1326, L"ERROR_LOGON_FAILURE"}, + {1327, L"ERROR_ACCOUNT_RESTRICTION"}, + {1328, L"ERROR_INVALID_LOGON_HOURS"}, + {1329, L"ERROR_INVALID_WORKSTATION"}, + {1330, L"ERROR_PASSWORD_EXPIRED"}, + {1331, L"ERROR_ACCOUNT_DISABLED"}, + {1332, L"ERROR_NONE_MAPPED"}, + {1333, L"ERROR_TOO_MANY_LUIDS_REQUESTED"}, + {1334, L"ERROR_LUIDS_EXHAUSTED"}, + {1335, L"ERROR_INVALID_SUB_AUTHORITY"}, + {1336, L"ERROR_INVALID_ACL"}, + {1337, L"ERROR_INVALID_SID"}, + {1338, L"ERROR_INVALID_SECURITY_DESCR"}, + {1340, L"ERROR_BAD_INHERITANCE_ACL"}, + {1341, L"ERROR_SERVER_DISABLED"}, + {1342, L"ERROR_SERVER_NOT_DISABLED"}, + {1343, L"ERROR_INVALID_ID_AUTHORITY"}, + {1344, L"ERROR_ALLOTTED_SPACE_EXCEEDED"}, + {1345, L"ERROR_INVALID_GROUP_ATTRIBUTES"}, + {1346, L"ERROR_BAD_IMPERSONATION_LEVEL"}, + {1347, L"ERROR_CANT_OPEN_ANONYMOUS"}, + {1348, L"ERROR_BAD_VALIDATION_CLASS"}, + {1349, L"ERROR_BAD_TOKEN_TYPE"}, + {1350, L"ERROR_NO_SECURITY_ON_OBJECT"}, + {1351, L"ERROR_CANT_ACCESS_DOMAIN_INFO"}, + {1352, L"ERROR_INVALID_SERVER_STATE"}, + {1353, L"ERROR_INVALID_DOMAIN_STATE"}, + {1354, L"ERROR_INVALID_DOMAIN_ROLE"}, + {1355, L"ERROR_NO_SUCH_DOMAIN"}, + {1356, L"ERROR_DOMAIN_EXISTS"}, + {1357, L"ERROR_DOMAIN_LIMIT_EXCEEDED"}, + {1358, L"ERROR_INTERNAL_DB_CORRUPTION"}, + {1359, L"ERROR_INTERNAL_ERROR"}, + {1360, L"ERROR_GENERIC_NOT_MAPPED"}, + {1361, L"ERROR_BAD_DESCRIPTOR_FORMAT"}, + {1362, L"ERROR_NOT_LOGON_PROCESS"}, + {1363, L"ERROR_LOGON_SESSION_EXISTS"}, + {1364, L"ERROR_NO_SUCH_PACKAGE"}, + {1365, L"ERROR_BAD_LOGON_SESSION_STATE"}, + {1366, L"ERROR_LOGON_SESSION_COLLISION"}, + {1367, L"ERROR_INVALID_LOGON_TYPE"}, + {1368, L"ERROR_CANNOT_IMPERSONATE"}, + {1369, L"ERROR_RXACT_INVALID_STATE"}, + {1370, L"ERROR_RXACT_COMMIT_FAILURE"}, + {1371, L"ERROR_SPECIAL_ACCOUNT"}, + {1372, L"ERROR_SPECIAL_GROUP"}, + {1373, L"ERROR_SPECIAL_USER"}, + {1374, L"ERROR_MEMBERS_PRIMARY_GROUP"}, + {1375, L"ERROR_TOKEN_ALREADY_IN_USE"}, + {1376, L"ERROR_NO_SUCH_ALIAS"}, + {1377, L"ERROR_MEMBER_NOT_IN_ALIAS"}, + {1378, L"ERROR_MEMBER_IN_ALIAS"}, + {1379, L"ERROR_ALIAS_EXISTS"}, + {1380, L"ERROR_LOGON_NOT_GRANTED"}, + {1381, L"ERROR_TOO_MANY_SECRETS"}, + {1382, L"ERROR_SECRET_TOO_LONG"}, + {1383, L"ERROR_INTERNAL_DB_ERROR"}, + {1384, L"ERROR_TOO_MANY_CONTEXT_IDS"}, + {1385, L"ERROR_LOGON_TYPE_NOT_GRANTED"}, + {1386, L"ERROR_NT_CROSS_ENCRYPTION_REQUIRED"}, + {1387, L"ERROR_NO_SUCH_MEMBER"}, + {1388, L"ERROR_INVALID_MEMBER"}, + {1389, L"ERROR_TOO_MANY_SIDS"}, + {1390, L"ERROR_LM_CROSS_ENCRYPTION_REQUIRED"}, + {1391, L"ERROR_NO_INHERITANCE"}, + {1392, L"ERROR_FILE_CORRUPT"}, + {1393, L"ERROR_DISK_CORRUPT"}, + {1394, L"ERROR_NO_USER_SESSION_KEY"}, + {1395, L"ERROR_LICENSE_QUOTA_EXCEEDED"}, + {1396, L"ERROR_WRONG_TARGET_NAME"}, + {1397, L"ERROR_MUTUAL_AUTH_FAILED"}, + {1398, L"ERROR_TIME_SKEW"}, + {1399, L"ERROR_CURRENT_DOMAIN_NOT_ALLOWED"}, + {1400, L"ERROR_INVALID_WINDOW_HANDLE"}, + {1401, L"ERROR_INVALID_MENU_HANDLE"}, + {1402, L"ERROR_INVALID_CURSOR_HANDLE"}, + {1403, L"ERROR_INVALID_ACCEL_HANDLE"}, + {1404, L"ERROR_INVALID_HOOK_HANDLE"}, + {1405, L"ERROR_INVALID_DWP_HANDLE"}, + {1406, L"ERROR_TLW_WITH_WSCHILD"}, + {1407, L"ERROR_CANNOT_FIND_WND_CLASS"}, + {1408, L"ERROR_WINDOW_OF_OTHER_THREAD"}, + {1409, L"ERROR_HOTKEY_ALREADY_REGISTERED"}, + {1410, L"ERROR_CLASS_ALREADY_EXISTS"}, + {1411, L"ERROR_CLASS_DOES_NOT_EXIST"}, + {1412, L"ERROR_CLASS_HAS_WINDOWS"}, + {1413, L"ERROR_INVALID_INDEX"}, + {1414, L"ERROR_INVALID_ICON_HANDLE"}, + {1415, L"ERROR_PRIVATE_DIALOG_INDEX"}, + {1416, L"ERROR_LISTBOX_ID_NOT_FOUND"}, + {1417, L"ERROR_NO_WILDCARD_CHARACTERS"}, + {1418, L"ERROR_CLIPBOARD_NOT_OPEN"}, + {1419, L"ERROR_HOTKEY_NOT_REGISTERED"}, + {1420, L"ERROR_WINDOW_NOT_DIALOG"}, + {1421, L"ERROR_CONTROL_ID_NOT_FOUND"}, + {1422, L"ERROR_INVALID_COMBOBOX_MESSAGE"}, + {1423, L"ERROR_WINDOW_NOT_COMBOBOX"}, + {1424, L"ERROR_INVALID_EDIT_HEIGHT"}, + {1425, L"ERROR_DC_NOT_FOUND"}, + {1426, L"ERROR_INVALID_HOOK_FILTER"}, + {1427, L"ERROR_INVALID_FILTER_PROC"}, + {1428, L"ERROR_HOOK_NEEDS_HMOD"}, + {1429, L"ERROR_GLOBAL_ONLY_HOOK"}, + {1430, L"ERROR_JOURNAL_HOOK_SET"}, + {1431, L"ERROR_HOOK_NOT_INSTALLED"}, + {1432, L"ERROR_INVALID_LB_MESSAGE"}, + {1433, L"ERROR_SETCOUNT_ON_BAD_LB"}, + {1434, L"ERROR_LB_WITHOUT_TABSTOPS"}, + {1435, L"ERROR_DESTROY_OBJECT_OF_OTHER_THREAD"}, + {1436, L"ERROR_CHILD_WINDOW_MENU"}, + {1437, L"ERROR_NO_SYSTEM_MENU"}, + {1438, L"ERROR_INVALID_MSGBOX_STYLE"}, + {1439, L"ERROR_INVALID_SPI_VALUE"}, + {1440, L"ERROR_SCREEN_ALREADY_LOCKED"}, + {1441, L"ERROR_HWNDS_HAVE_DIFF_PARENT"}, + {1442, L"ERROR_NOT_CHILD_WINDOW"}, + {1443, L"ERROR_INVALID_GW_COMMAND"}, + {1444, L"ERROR_INVALID_THREAD_ID"}, + {1445, L"ERROR_NON_MDICHILD_WINDOW"}, + {1446, L"ERROR_POPUP_ALREADY_ACTIVE"}, + {1447, L"ERROR_NO_SCROLLBARS"}, + {1448, L"ERROR_INVALID_SCROLLBAR_RANGE"}, + {1449, L"ERROR_INVALID_SHOWWIN_COMMAND"}, + {1450, L"ERROR_NO_SYSTEM_RESOURCES"}, + {1451, L"ERROR_NONPAGED_SYSTEM_RESOURCES"}, + {1452, L"ERROR_PAGED_SYSTEM_RESOURCES"}, + {1453, L"ERROR_WORKING_SET_QUOTA"}, + {1454, L"ERROR_PAGEFILE_QUOTA"}, + {1455, L"ERROR_COMMITMENT_LIMIT"}, + {1456, L"ERROR_MENU_ITEM_NOT_FOUND"}, + {1457, L"ERROR_INVALID_KEYBOARD_HANDLE"}, + {1458, L"ERROR_HOOK_TYPE_NOT_ALLOWED"}, + {1459, L"ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION"}, + {1460, L"ERROR_TIMEOUT"}, + {1461, L"ERROR_INVALID_MONITOR_HANDLE"}, + {1462, L"ERROR_INCORRECT_SIZE"}, + {1463, L"ERROR_SYMLINK_CLASS_DISABLED"}, + {1464, L"ERROR_SYMLINK_NOT_SUPPORTED"}, + {1465, L"ERROR_XML_PARSE_ERROR"}, + {1466, L"ERROR_XMLDSIG_ERROR"}, + {1467, L"ERROR_RESTART_APPLICATION"}, + {1468, L"ERROR_WRONG_COMPARTMENT"}, + {1469, L"ERROR_AUTHIP_FAILURE"}, + {1470, L"ERROR_NO_NVRAM_RESOURCES"}, + {1471, L"ERROR_NOT_GUI_PROCESS"}, + {1500, L"ERROR_EVENTLOG_FILE_CORRUPT"}, + {1501, L"ERROR_EVENTLOG_CANT_START"}, + {1502, L"ERROR_LOG_FILE_FULL"}, + {1503, L"ERROR_EVENTLOG_FILE_CHANGED"}, + {1550, L"ERROR_INVALID_TASK_NAME"}, + {1551, L"ERROR_INVALID_TASK_INDEX"}, + {1552, L"ERROR_THREAD_ALREADY_IN_TASK"}, + {1601, L"ERROR_INSTALL_SERVICE_FAILURE"}, + {1602, L"ERROR_INSTALL_USEREXIT"}, + {1603, L"ERROR_INSTALL_FAILURE"}, + {1604, L"ERROR_INSTALL_SUSPEND"}, + {1605, L"ERROR_UNKNOWN_PRODUCT"}, + {1606, L"ERROR_UNKNOWN_FEATURE"}, + {1607, L"ERROR_UNKNOWN_COMPONENT"}, + {1608, L"ERROR_UNKNOWN_PROPERTY"}, + {1609, L"ERROR_INVALID_HANDLE_STATE"}, + {1610, L"ERROR_BAD_CONFIGURATION"}, + {1611, L"ERROR_INDEX_ABSENT"}, + {1612, L"ERROR_INSTALL_SOURCE_ABSENT"}, + {1613, L"ERROR_INSTALL_PACKAGE_VERSION"}, + {1614, L"ERROR_PRODUCT_UNINSTALLED"}, + {1615, L"ERROR_BAD_QUERY_SYNTAX"}, + {1616, L"ERROR_INVALID_FIELD"}, + {1617, L"ERROR_DEVICE_REMOVED"}, + {1618, L"ERROR_INSTALL_ALREADY_RUNNING"}, + {1619, L"ERROR_INSTALL_PACKAGE_OPEN_FAILED"}, + {1620, L"ERROR_INSTALL_PACKAGE_INVALID"}, + {1621, L"ERROR_INSTALL_UI_FAILURE"}, + {1622, L"ERROR_INSTALL_LOG_FAILURE"}, + {1623, L"ERROR_INSTALL_LANGUAGE_UNSUPPORTED"}, + {1624, L"ERROR_INSTALL_TRANSFORM_FAILURE"}, + {1625, L"ERROR_INSTALL_PACKAGE_REJECTED"}, + {1626, L"ERROR_FUNCTION_NOT_CALLED"}, + {1627, L"ERROR_FUNCTION_FAILED"}, + {1628, L"ERROR_INVALID_TABLE"}, + {1629, L"ERROR_DATATYPE_MISMATCH"}, + {1630, L"ERROR_UNSUPPORTED_TYPE"}, + {1631, L"ERROR_CREATE_FAILED"}, + {1632, L"ERROR_INSTALL_TEMP_UNWRITABLE"}, + {1633, L"ERROR_INSTALL_PLATFORM_UNSUPPORTED"}, + {1634, L"ERROR_INSTALL_NOTUSED"}, + {1635, L"ERROR_PATCH_PACKAGE_OPEN_FAILED"}, + {1636, L"ERROR_PATCH_PACKAGE_INVALID"}, + {1637, L"ERROR_PATCH_PACKAGE_UNSUPPORTED"}, + {1638, L"ERROR_PRODUCT_VERSION"}, + {1639, L"ERROR_INVALID_COMMAND_LINE"}, + {1640, L"ERROR_INSTALL_REMOTE_DISALLOWED"}, + {1641, L"ERROR_SUCCESS_REBOOT_INITIATED"}, + {1642, L"ERROR_PATCH_TARGET_NOT_FOUND"}, + {1643, L"ERROR_PATCH_PACKAGE_REJECTED"}, + {1644, L"ERROR_INSTALL_TRANSFORM_REJECTED"}, + {1645, L"ERROR_INSTALL_REMOTE_PROHIBITED"}, + {1646, L"ERROR_PATCH_REMOVAL_UNSUPPORTED"}, + {1647, L"ERROR_UNKNOWN_PATCH"}, + {1648, L"ERROR_PATCH_NO_SEQUENCE"}, + {1649, L"ERROR_PATCH_REMOVAL_DISALLOWED"}, + {1650, L"ERROR_INVALID_PATCH_XML"}, + {1651, L"ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT"}, + {1652, L"ERROR_INSTALL_SERVICE_SAFEBOOT"}, + {1653, L"ERROR_FAIL_FAST_EXCEPTION"}, + {1654, L"ERROR_INSTALL_REJECTED"}, + {1700, L"RPC_S_INVALID_STRING_BINDING"}, + {1701, L"RPC_S_WRONG_KIND_OF_BINDING"}, + {1702, L"RPC_S_INVALID_BINDING"}, + {1703, L"RPC_S_PROTSEQ_NOT_SUPPORTED"}, + {1704, L"RPC_S_INVALID_RPC_PROTSEQ"}, + {1705, L"RPC_S_INVALID_STRING_UUID"}, + {1706, L"RPC_S_INVALID_ENDPOINT_FORMAT"}, + {1707, L"RPC_S_INVALID_NET_ADDR"}, + {1708, L"RPC_S_NO_ENDPOINT_FOUND"}, + {1709, L"RPC_S_INVALID_TIMEOUT"}, + {1710, L"RPC_S_OBJECT_NOT_FOUND"}, + {1711, L"RPC_S_ALREADY_REGISTERED"}, + {1712, L"RPC_S_TYPE_ALREADY_REGISTERED"}, + {1713, L"RPC_S_ALREADY_LISTENING"}, + {1714, L"RPC_S_NO_PROTSEQS_REGISTERED"}, + {1715, L"RPC_S_NOT_LISTENING"}, + {1716, L"RPC_S_UNKNOWN_MGR_TYPE"}, + {1717, L"RPC_S_UNKNOWN_IF"}, + {1718, L"RPC_S_NO_BINDINGS"}, + {1719, L"RPC_S_NO_PROTSEQS"}, + {1720, L"RPC_S_CANT_CREATE_ENDPOINT"}, + {1721, L"RPC_S_OUT_OF_RESOURCES"}, + {1722, L"RPC_S_SERVER_UNAVAILABLE"}, + {1723, L"RPC_S_SERVER_TOO_BUSY"}, + {1724, L"RPC_S_INVALID_NETWORK_OPTIONS"}, + {1725, L"RPC_S_NO_CALL_ACTIVE"}, + {1726, L"RPC_S_CALL_FAILED"}, + {1727, L"RPC_S_CALL_FAILED_DNE"}, + {1728, L"RPC_S_PROTOCOL_ERROR"}, + {1729, L"RPC_S_PROXY_ACCESS_DENIED"}, + {1730, L"RPC_S_UNSUPPORTED_TRANS_SYN"}, + {1732, L"RPC_S_UNSUPPORTED_TYPE"}, + {1733, L"RPC_S_INVALID_TAG"}, + {1734, L"RPC_S_INVALID_BOUND"}, + {1735, L"RPC_S_NO_ENTRY_NAME"}, + {1736, L"RPC_S_INVALID_NAME_SYNTAX"}, + {1737, L"RPC_S_UNSUPPORTED_NAME_SYNTAX"}, + {1739, L"RPC_S_UUID_NO_ADDRESS"}, + {1740, L"RPC_S_DUPLICATE_ENDPOINT"}, + {1741, L"RPC_S_UNKNOWN_AUTHN_TYPE"}, + {1742, L"RPC_S_MAX_CALLS_TOO_SMALL"}, + {1743, L"RPC_S_STRING_TOO_LONG"}, + {1744, L"RPC_S_PROTSEQ_NOT_FOUND"}, + {1745, L"RPC_S_PROCNUM_OUT_OF_RANGE"}, + {1746, L"RPC_S_BINDING_HAS_NO_AUTH"}, + {1747, L"RPC_S_UNKNOWN_AUTHN_SERVICE"}, + {1748, L"RPC_S_UNKNOWN_AUTHN_LEVEL"}, + {1749, L"RPC_S_INVALID_AUTH_IDENTITY"}, + {1750, L"RPC_S_UNKNOWN_AUTHZ_SERVICE"}, + {1751, L"EPT_S_INVALID_ENTRY"}, + {1752, L"EPT_S_CANT_PERFORM_OP"}, + {1753, L"EPT_S_NOT_REGISTERED"}, + {1754, L"RPC_S_NOTHING_TO_EXPORT"}, + {1755, L"RPC_S_INCOMPLETE_NAME"}, + {1756, L"RPC_S_INVALID_VERS_OPTION"}, + {1757, L"RPC_S_NO_MORE_MEMBERS"}, + {1758, L"RPC_S_NOT_ALL_OBJS_UNEXPORTED"}, + {1759, L"RPC_S_INTERFACE_NOT_FOUND"}, + {1760, L"RPC_S_ENTRY_ALREADY_EXISTS"}, + {1761, L"RPC_S_ENTRY_NOT_FOUND"}, + {1762, L"RPC_S_NAME_SERVICE_UNAVAILABLE"}, + {1763, L"RPC_S_INVALID_NAF_ID"}, + {1764, L"RPC_S_CANNOT_SUPPORT"}, + {1765, L"RPC_S_NO_CONTEXT_AVAILABLE"}, + {1766, L"RPC_S_INTERNAL_ERROR"}, + {1767, L"RPC_S_ZERO_DIVIDE"}, + {1768, L"RPC_S_ADDRESS_ERROR"}, + {1769, L"RPC_S_FP_DIV_ZERO"}, + {1770, L"RPC_S_FP_UNDERFLOW"}, + {1771, L"RPC_S_FP_OVERFLOW"}, + {1772, L"RPC_X_NO_MORE_ENTRIES"}, + {1773, L"RPC_X_SS_CHAR_TRANS_OPEN_FAIL"}, + {1774, L"RPC_X_SS_CHAR_TRANS_SHORT_FILE"}, + {1775, L"RPC_X_SS_IN_NULL_CONTEXT"}, + {1777, L"RPC_X_SS_CONTEXT_DAMAGED"}, + {1778, L"RPC_X_SS_HANDLES_MISMATCH"}, + {1779, L"RPC_X_SS_CANNOT_GET_CALL_HANDLE"}, + {1780, L"RPC_X_NULL_REF_POINTER"}, + {1781, L"RPC_X_ENUM_VALUE_OUT_OF_RANGE"}, + {1782, L"RPC_X_BYTE_COUNT_TOO_SMALL"}, + {1783, L"RPC_X_BAD_STUB_DATA"}, + {1784, L"ERROR_INVALID_USER_BUFFER"}, + {1785, L"ERROR_UNRECOGNIZED_MEDIA"}, + {1786, L"ERROR_NO_TRUST_LSA_SECRET"}, + {1787, L"ERROR_NO_TRUST_SAM_ACCOUNT"}, + {1788, L"ERROR_TRUSTED_DOMAIN_FAILURE"}, + {1789, L"ERROR_TRUSTED_RELATIONSHIP_FAILURE"}, + {1790, L"ERROR_TRUST_FAILURE"}, + {1791, L"RPC_S_CALL_IN_PROGRESS"}, + {1792, L"ERROR_NETLOGON_NOT_STARTED"}, + {1793, L"ERROR_ACCOUNT_EXPIRED"}, + {1794, L"ERROR_REDIRECTOR_HAS_OPEN_HANDLES"}, + {1795, L"ERROR_PRINTER_DRIVER_ALREADY_INSTALLED"}, + {1796, L"ERROR_UNKNOWN_PORT"}, + {1797, L"ERROR_UNKNOWN_PRINTER_DRIVER"}, + {1798, L"ERROR_UNKNOWN_PRINTPROCESSOR"}, + {1799, L"ERROR_INVALID_SEPARATOR_FILE"}, + {1800, L"ERROR_INVALID_PRIORITY"}, + {1801, L"ERROR_INVALID_PRINTER_NAME"}, + {1802, L"ERROR_PRINTER_ALREADY_EXISTS"}, + {1803, L"ERROR_INVALID_PRINTER_COMMAND"}, + {1804, L"ERROR_INVALID_DATATYPE"}, + {1805, L"ERROR_INVALID_ENVIRONMENT"}, + {1806, L"RPC_S_NO_MORE_BINDINGS"}, + {1807, L"ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"}, + {1808, L"ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT"}, + {1809, L"ERROR_NOLOGON_SERVER_TRUST_ACCOUNT"}, + {1810, L"ERROR_DOMAIN_TRUST_INCONSISTENT"}, + {1811, L"ERROR_SERVER_HAS_OPEN_HANDLES"}, + {1812, L"ERROR_RESOURCE_DATA_NOT_FOUND"}, + {1813, L"ERROR_RESOURCE_TYPE_NOT_FOUND"}, + {1814, L"ERROR_RESOURCE_NAME_NOT_FOUND"}, + {1815, L"ERROR_RESOURCE_LANG_NOT_FOUND"}, + {1816, L"ERROR_NOT_ENOUGH_QUOTA"}, + {1817, L"RPC_S_NO_INTERFACES"}, + {1818, L"RPC_S_CALL_CANCELLED"}, + {1819, L"RPC_S_BINDING_INCOMPLETE"}, + {1820, L"RPC_S_COMM_FAILURE"}, + {1821, L"RPC_S_UNSUPPORTED_AUTHN_LEVEL"}, + {1822, L"RPC_S_NO_PRINC_NAME"}, + {1823, L"RPC_S_NOT_RPC_ERROR"}, + {1824, L"RPC_S_UUID_LOCAL_ONLY"}, + {1825, L"RPC_S_SEC_PKG_ERROR"}, + {1826, L"RPC_S_NOT_CANCELLED"}, + {1827, L"RPC_X_INVALID_ES_ACTION"}, + {1828, L"RPC_X_WRONG_ES_VERSION"}, + {1829, L"RPC_X_WRONG_STUB_VERSION"}, + {1830, L"RPC_X_INVALID_PIPE_OBJECT"}, + {1831, L"RPC_X_WRONG_PIPE_ORDER"}, + {1832, L"RPC_X_WRONG_PIPE_VERSION"}, + {1833, L"RPC_S_COOKIE_AUTH_FAILED"}, + {1898, L"RPC_S_GROUP_MEMBER_NOT_FOUND"}, + {1899, L"EPT_S_CANT_CREATE"}, + {1900, L"RPC_S_INVALID_OBJECT"}, + {1901, L"ERROR_INVALID_TIME"}, + {1902, L"ERROR_INVALID_FORM_NAME"}, + {1903, L"ERROR_INVALID_FORM_SIZE"}, + {1904, L"ERROR_ALREADY_WAITING"}, + {1905, L"ERROR_PRINTER_DELETED"}, + {1906, L"ERROR_INVALID_PRINTER_STATE"}, + {1907, L"ERROR_PASSWORD_MUST_CHANGE"}, + {1908, L"ERROR_DOMAIN_CONTROLLER_NOT_FOUND"}, + {1909, L"ERROR_ACCOUNT_LOCKED_OUT"}, + {1910, L"OR_INVALID_OXID"}, + {1911, L"OR_INVALID_OID"}, + {1912, L"OR_INVALID_SET"}, + {1913, L"RPC_S_SEND_INCOMPLETE"}, + {1914, L"RPC_S_INVALID_ASYNC_HANDLE"}, + {1915, L"RPC_S_INVALID_ASYNC_CALL"}, + {1916, L"RPC_X_PIPE_CLOSED"}, + {1917, L"RPC_X_PIPE_DISCIPLINE_ERROR"}, + {1918, L"RPC_X_PIPE_EMPTY"}, + {1919, L"ERROR_NO_SITENAME"}, + {1920, L"ERROR_CANT_ACCESS_FILE"}, + {1921, L"ERROR_CANT_RESOLVE_FILENAME"}, + {1922, L"RPC_S_ENTRY_TYPE_MISMATCH"}, + {1923, L"RPC_S_NOT_ALL_OBJS_EXPORTED"}, + {1924, L"RPC_S_INTERFACE_NOT_EXPORTED"}, + {1925, L"RPC_S_PROFILE_NOT_ADDED"}, + {1926, L"RPC_S_PRF_ELT_NOT_ADDED"}, + {1927, L"RPC_S_PRF_ELT_NOT_REMOVED"}, + {1928, L"RPC_S_GRP_ELT_NOT_ADDED"}, + {1929, L"RPC_S_GRP_ELT_NOT_REMOVED"}, + {1930, L"ERROR_KM_DRIVER_BLOCKED"}, + {1931, L"ERROR_CONTEXT_EXPIRED"}, + {1932, L"ERROR_PER_USER_TRUST_QUOTA_EXCEEDED"}, + {1933, L"ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED"}, + {1934, L"ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED"}, + {1935, L"ERROR_AUTHENTICATION_FIREWALL_FAILED"}, + {1936, L"ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED"}, + {1937, L"ERROR_NTLM_BLOCKED"}, + {1938, L"ERROR_PASSWORD_CHANGE_REQUIRED"}, + {2000, L"ERROR_INVALID_PIXEL_FORMAT"}, + {2001, L"ERROR_BAD_DRIVER"}, + {2002, L"ERROR_INVALID_WINDOW_STYLE"}, + {2003, L"ERROR_METAFILE_NOT_SUPPORTED"}, + {2004, L"ERROR_TRANSFORM_NOT_SUPPORTED"}, + {2005, L"ERROR_CLIPPING_NOT_SUPPORTED"}, + {2010, L"ERROR_INVALID_CMM"}, + {2011, L"ERROR_INVALID_PROFILE"}, + {2012, L"ERROR_TAG_NOT_FOUND"}, + {2013, L"ERROR_TAG_NOT_PRESENT"}, + {2014, L"ERROR_DUPLICATE_TAG"}, + {2015, L"ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE"}, + {2016, L"ERROR_PROFILE_NOT_FOUND"}, + {2017, L"ERROR_INVALID_COLORSPACE"}, + {2018, L"ERROR_ICM_NOT_ENABLED"}, + {2019, L"ERROR_DELETING_ICM_XFORM"}, + {2020, L"ERROR_INVALID_TRANSFORM"}, + {2021, L"ERROR_COLORSPACE_MISMATCH"}, + {2022, L"ERROR_INVALID_COLORINDEX"}, + {2023, L"ERROR_PROFILE_DOES_NOT_MATCH_DEVICE"}, + {2108, L"ERROR_CONNECTED_OTHER_PASSWORD"}, + {2109, L"ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT"}, + {2202, L"ERROR_BAD_USERNAME"}, + {2250, L"ERROR_NOT_CONNECTED"}, + {2401, L"ERROR_OPEN_FILES"}, + {2402, L"ERROR_ACTIVE_CONNECTIONS"}, + {2404, L"ERROR_DEVICE_IN_USE"}, + {3000, L"ERROR_UNKNOWN_PRINT_MONITOR"}, + {3001, L"ERROR_PRINTER_DRIVER_IN_USE"}, + {3002, L"ERROR_SPOOL_FILE_NOT_FOUND"}, + {3003, L"ERROR_SPL_NO_STARTDOC"}, + {3004, L"ERROR_SPL_NO_ADDJOB"}, + {3005, L"ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED"}, + {3006, L"ERROR_PRINT_MONITOR_ALREADY_INSTALLED"}, + {3007, L"ERROR_INVALID_PRINT_MONITOR"}, + {3008, L"ERROR_PRINT_MONITOR_IN_USE"}, + {3009, L"ERROR_PRINTER_HAS_JOBS_QUEUED"}, + {3010, L"ERROR_SUCCESS_REBOOT_REQUIRED"}, + {3011, L"ERROR_SUCCESS_RESTART_REQUIRED"}, + {3012, L"ERROR_PRINTER_NOT_FOUND"}, + {3013, L"ERROR_PRINTER_DRIVER_WARNED"}, + {3014, L"ERROR_PRINTER_DRIVER_BLOCKED"}, + {3015, L"ERROR_PRINTER_DRIVER_PACKAGE_IN_USE"}, + {3016, L"ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND"}, + {3017, L"ERROR_FAIL_REBOOT_REQUIRED"}, + {3018, L"ERROR_FAIL_REBOOT_INITIATED"}, + {3019, L"ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED"}, + {3020, L"ERROR_PRINT_JOB_RESTART_REQUIRED"}, + {3021, L"ERROR_INVALID_PRINTER_DRIVER_MANIFEST"}, + {3022, L"ERROR_PRINTER_NOT_SHAREABLE"}, + {3050, L"ERROR_REQUEST_PAUSED"}, + {3950, L"ERROR_IO_REISSUE_AS_CACHED"}, + {4000, L"ERROR_WINS_INTERNAL"}, + {4001, L"ERROR_CAN_NOT_DEL_LOCAL_WINS"}, + {4002, L"ERROR_STATIC_INIT"}, + {4003, L"ERROR_INC_BACKUP"}, + {4004, L"ERROR_FULL_BACKUP"}, + {4005, L"ERROR_REC_NON_EXISTENT"}, + {4006, L"ERROR_RPL_NOT_ALLOWED"}, + {4050, L"PEERDIST_ERROR_CONTENTINFO_VERSION_UNSUPPORTED"}, + {4051, L"PEERDIST_ERROR_CANNOT_PARSE_CONTENTINFO"}, + {4052, L"PEERDIST_ERROR_MISSING_DATA"}, + {4053, L"PEERDIST_ERROR_NO_MORE"}, + {4054, L"PEERDIST_ERROR_NOT_INITIALIZED"}, + {4055, L"PEERDIST_ERROR_ALREADY_INITIALIZED"}, + {4056, L"PEERDIST_ERROR_SHUTDOWN_IN_PROGRESS"}, + {4057, L"PEERDIST_ERROR_INVALIDATED"}, + {4058, L"PEERDIST_ERROR_ALREADY_EXISTS"}, + {4059, L"PEERDIST_ERROR_OPERATION_NOTFOUND"}, + {4060, L"PEERDIST_ERROR_ALREADY_COMPLETED"}, + {4061, L"PEERDIST_ERROR_OUT_OF_BOUNDS"}, + {4062, L"PEERDIST_ERROR_VERSION_UNSUPPORTED"}, + {4063, L"PEERDIST_ERROR_INVALID_CONFIGURATION"}, + {4064, L"PEERDIST_ERROR_NOT_LICENSED"}, + {4065, L"PEERDIST_ERROR_SERVICE_UNAVAILABLE"}, + {4066, L"PEERDIST_ERROR_TRUST_FAILURE"}, + {4100, L"ERROR_DHCP_ADDRESS_CONFLICT"}, + {4200, L"ERROR_WMI_GUID_NOT_FOUND"}, + {4201, L"ERROR_WMI_INSTANCE_NOT_FOUND"}, + {4202, L"ERROR_WMI_ITEMID_NOT_FOUND"}, + {4203, L"ERROR_WMI_TRY_AGAIN"}, + {4204, L"ERROR_WMI_DP_NOT_FOUND"}, + {4205, L"ERROR_WMI_UNRESOLVED_INSTANCE_REF"}, + {4206, L"ERROR_WMI_ALREADY_ENABLED"}, + {4207, L"ERROR_WMI_GUID_DISCONNECTED"}, + {4208, L"ERROR_WMI_SERVER_UNAVAILABLE"}, + {4209, L"ERROR_WMI_DP_FAILED"}, + {4210, L"ERROR_WMI_INVALID_MOF"}, + {4211, L"ERROR_WMI_INVALID_REGINFO"}, + {4212, L"ERROR_WMI_ALREADY_DISABLED"}, + {4213, L"ERROR_WMI_READ_ONLY"}, + {4214, L"ERROR_WMI_SET_FAILURE"}, + {4250, L"ERROR_NOT_APPCONTAINER"}, + {4251, L"ERROR_APPCONTAINER_REQUIRED"}, + {4252, L"ERROR_NOT_SUPPORTED_IN_APPCONTAINER"}, + {4253, L"ERROR_INVALID_PACKAGE_SID_LENGTH"}, + {4300, L"ERROR_INVALID_MEDIA"}, + {4301, L"ERROR_INVALID_LIBRARY"}, + {4302, L"ERROR_INVALID_MEDIA_POOL"}, + {4303, L"ERROR_DRIVE_MEDIA_MISMATCH"}, + {4304, L"ERROR_MEDIA_OFFLINE"}, + {4305, L"ERROR_LIBRARY_OFFLINE"}, + {4306, L"ERROR_EMPTY"}, + {4307, L"ERROR_NOT_EMPTY"}, + {4308, L"ERROR_MEDIA_UNAVAILABLE"}, + {4309, L"ERROR_RESOURCE_DISABLED"}, + {4310, L"ERROR_INVALID_CLEANER"}, + {4311, L"ERROR_UNABLE_TO_CLEAN"}, + {4312, L"ERROR_OBJECT_NOT_FOUND"}, + {4313, L"ERROR_DATABASE_FAILURE"}, + {4314, L"ERROR_DATABASE_FULL"}, + {4315, L"ERROR_MEDIA_INCOMPATIBLE"}, + {4316, L"ERROR_RESOURCE_NOT_PRESENT"}, + {4317, L"ERROR_INVALID_OPERATION"}, + {4318, L"ERROR_MEDIA_NOT_AVAILABLE"}, + {4319, L"ERROR_DEVICE_NOT_AVAILABLE"}, + {4320, L"ERROR_REQUEST_REFUSED"}, + {4321, L"ERROR_INVALID_DRIVE_OBJECT"}, + {4322, L"ERROR_LIBRARY_FULL"}, + {4323, L"ERROR_MEDIUM_NOT_ACCESSIBLE"}, + {4324, L"ERROR_UNABLE_TO_LOAD_MEDIUM"}, + {4325, L"ERROR_UNABLE_TO_INVENTORY_DRIVE"}, + {4326, L"ERROR_UNABLE_TO_INVENTORY_SLOT"}, + {4327, L"ERROR_UNABLE_TO_INVENTORY_TRANSPORT"}, + {4328, L"ERROR_TRANSPORT_FULL"}, + {4329, L"ERROR_CONTROLLING_IEPORT"}, + {4330, L"ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA"}, + {4331, L"ERROR_CLEANER_SLOT_SET"}, + {4332, L"ERROR_CLEANER_SLOT_NOT_SET"}, + {4333, L"ERROR_CLEANER_CARTRIDGE_SPENT"}, + {4334, L"ERROR_UNEXPECTED_OMID"}, + {4335, L"ERROR_CANT_DELETE_LAST_ITEM"}, + {4336, L"ERROR_MESSAGE_EXCEEDS_MAX_SIZE"}, + {4337, L"ERROR_VOLUME_CONTAINS_SYS_FILES"}, + {4338, L"ERROR_INDIGENOUS_TYPE"}, + {4339, L"ERROR_NO_SUPPORTING_DRIVES"}, + {4340, L"ERROR_CLEANER_CARTRIDGE_INSTALLED"}, + {4341, L"ERROR_IEPORT_FULL"}, + {4350, L"ERROR_FILE_OFFLINE"}, + {4351, L"ERROR_REMOTE_STORAGE_NOT_ACTIVE"}, + {4352, L"ERROR_REMOTE_STORAGE_MEDIA_ERROR"}, + {4390, L"ERROR_NOT_A_REPARSE_POINT"}, + {4391, L"ERROR_REPARSE_ATTRIBUTE_CONFLICT"}, + {4392, L"ERROR_INVALID_REPARSE_DATA"}, + {4393, L"ERROR_REPARSE_TAG_INVALID"}, + {4394, L"ERROR_REPARSE_TAG_MISMATCH"}, + {4400, L"ERROR_APP_DATA_NOT_FOUND"}, + {4401, L"ERROR_APP_DATA_EXPIRED"}, + {4402, L"ERROR_APP_DATA_CORRUPT"}, + {4403, L"ERROR_APP_DATA_LIMIT_EXCEEDED"}, + {4404, L"ERROR_APP_DATA_REBOOT_REQUIRED"}, + {4420, L"ERROR_SECUREBOOT_ROLLBACK_DETECTED"}, + {4421, L"ERROR_SECUREBOOT_POLICY_VIOLATION"}, + {4422, L"ERROR_SECUREBOOT_INVALID_POLICY"}, + {4423, L"ERROR_SECUREBOOT_POLICY_PUBLISHER_NOT_FOUND"}, + {4424, L"ERROR_SECUREBOOT_POLICY_NOT_SIGNED"}, + {4425, L"ERROR_SECUREBOOT_NOT_ENABLED"}, + {4426, L"ERROR_SECUREBOOT_FILE_REPLACED"}, + {4440, L"ERROR_OFFLOAD_READ_FLT_NOT_SUPPORTED"}, + {4441, L"ERROR_OFFLOAD_WRITE_FLT_NOT_SUPPORTED"}, + {4442, L"ERROR_OFFLOAD_READ_FILE_NOT_SUPPORTED"}, + {4443, L"ERROR_OFFLOAD_WRITE_FILE_NOT_SUPPORTED"}, + {4500, L"ERROR_VOLUME_NOT_SIS_ENABLED"}, + {5001, L"ERROR_DEPENDENT_RESOURCE_EXISTS"}, + {5002, L"ERROR_DEPENDENCY_NOT_FOUND"}, + {5003, L"ERROR_DEPENDENCY_ALREADY_EXISTS"}, + {5004, L"ERROR_RESOURCE_NOT_ONLINE"}, + {5005, L"ERROR_HOST_NODE_NOT_AVAILABLE"}, + {5006, L"ERROR_RESOURCE_NOT_AVAILABLE"}, + {5007, L"ERROR_RESOURCE_NOT_FOUND"}, + {5008, L"ERROR_SHUTDOWN_CLUSTER"}, + {5009, L"ERROR_CANT_EVICT_ACTIVE_NODE"}, + {5010, L"ERROR_OBJECT_ALREADY_EXISTS"}, + {5011, L"ERROR_OBJECT_IN_LIST"}, + {5012, L"ERROR_GROUP_NOT_AVAILABLE"}, + {5013, L"ERROR_GROUP_NOT_FOUND"}, + {5014, L"ERROR_GROUP_NOT_ONLINE"}, + {5015, L"ERROR_HOST_NODE_NOT_RESOURCE_OWNER"}, + {5016, L"ERROR_HOST_NODE_NOT_GROUP_OWNER"}, + {5017, L"ERROR_RESMON_CREATE_FAILED"}, + {5018, L"ERROR_RESMON_ONLINE_FAILED"}, + {5019, L"ERROR_RESOURCE_ONLINE"}, + {5020, L"ERROR_QUORUM_RESOURCE"}, + {5021, L"ERROR_NOT_QUORUM_CAPABLE"}, + {5022, L"ERROR_CLUSTER_SHUTTING_DOWN"}, + {5023, L"ERROR_INVALID_STATE"}, + {5024, L"ERROR_RESOURCE_PROPERTIES_STORED"}, + {5025, L"ERROR_NOT_QUORUM_CLASS"}, + {5026, L"ERROR_CORE_RESOURCE"}, + {5027, L"ERROR_QUORUM_RESOURCE_ONLINE_FAILED"}, + {5028, L"ERROR_QUORUMLOG_OPEN_FAILED"}, + {5029, L"ERROR_CLUSTERLOG_CORRUPT"}, + {5030, L"ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE"}, + {5031, L"ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE"}, + {5032, L"ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND"}, + {5033, L"ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE"}, + {5034, L"ERROR_QUORUM_OWNER_ALIVE"}, + {5035, L"ERROR_NETWORK_NOT_AVAILABLE"}, + {5036, L"ERROR_NODE_NOT_AVAILABLE"}, + {5037, L"ERROR_ALL_NODES_NOT_AVAILABLE"}, + {5038, L"ERROR_RESOURCE_FAILED"}, + {5039, L"ERROR_CLUSTER_INVALID_NODE"}, + {5040, L"ERROR_CLUSTER_NODE_EXISTS"}, + {5041, L"ERROR_CLUSTER_JOIN_IN_PROGRESS"}, + {5042, L"ERROR_CLUSTER_NODE_NOT_FOUND"}, + {5043, L"ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND"}, + {5044, L"ERROR_CLUSTER_NETWORK_EXISTS"}, + {5045, L"ERROR_CLUSTER_NETWORK_NOT_FOUND"}, + {5046, L"ERROR_CLUSTER_NETINTERFACE_EXISTS"}, + {5047, L"ERROR_CLUSTER_NETINTERFACE_NOT_FOUND"}, + {5048, L"ERROR_CLUSTER_INVALID_REQUEST"}, + {5049, L"ERROR_CLUSTER_INVALID_NETWORK_PROVIDER"}, + {5050, L"ERROR_CLUSTER_NODE_DOWN"}, + {5051, L"ERROR_CLUSTER_NODE_UNREACHABLE"}, + {5052, L"ERROR_CLUSTER_NODE_NOT_MEMBER"}, + {5053, L"ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS"}, + {5054, L"ERROR_CLUSTER_INVALID_NETWORK"}, + {5056, L"ERROR_CLUSTER_NODE_UP"}, + {5057, L"ERROR_CLUSTER_IPADDR_IN_USE"}, + {5058, L"ERROR_CLUSTER_NODE_NOT_PAUSED"}, + {5059, L"ERROR_CLUSTER_NO_SECURITY_CONTEXT"}, + {5060, L"ERROR_CLUSTER_NETWORK_NOT_INTERNAL"}, + {5061, L"ERROR_CLUSTER_NODE_ALREADY_UP"}, + {5062, L"ERROR_CLUSTER_NODE_ALREADY_DOWN"}, + {5063, L"ERROR_CLUSTER_NETWORK_ALREADY_ONLINE"}, + {5064, L"ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE"}, + {5065, L"ERROR_CLUSTER_NODE_ALREADY_MEMBER"}, + {5066, L"ERROR_CLUSTER_LAST_INTERNAL_NETWORK"}, + {5067, L"ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS"}, + {5068, L"ERROR_INVALID_OPERATION_ON_QUORUM"}, + {5069, L"ERROR_DEPENDENCY_NOT_ALLOWED"}, + {5070, L"ERROR_CLUSTER_NODE_PAUSED"}, + {5071, L"ERROR_NODE_CANT_HOST_RESOURCE"}, + {5072, L"ERROR_CLUSTER_NODE_NOT_READY"}, + {5073, L"ERROR_CLUSTER_NODE_SHUTTING_DOWN"}, + {5074, L"ERROR_CLUSTER_JOIN_ABORTED"}, + {5075, L"ERROR_CLUSTER_INCOMPATIBLE_VERSIONS"}, + {5076, L"ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED"}, + {5077, L"ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED"}, + {5078, L"ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND"}, + {5079, L"ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED"}, + {5080, L"ERROR_CLUSTER_RESNAME_NOT_FOUND"}, + {5081, L"ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED"}, + {5082, L"ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST"}, + {5083, L"ERROR_CLUSTER_DATABASE_SEQMISMATCH"}, + {5084, L"ERROR_RESMON_INVALID_STATE"}, + {5085, L"ERROR_CLUSTER_GUM_NOT_LOCKER"}, + {5086, L"ERROR_QUORUM_DISK_NOT_FOUND"}, + {5087, L"ERROR_DATABASE_BACKUP_CORRUPT"}, + {5088, L"ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT"}, + {5089, L"ERROR_RESOURCE_PROPERTY_UNCHANGEABLE"}, + {5890, L"ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE"}, + {5891, L"ERROR_CLUSTER_QUORUMLOG_NOT_FOUND"}, + {5892, L"ERROR_CLUSTER_MEMBERSHIP_HALT"}, + {5893, L"ERROR_CLUSTER_INSTANCE_ID_MISMATCH"}, + {5894, L"ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP"}, + {5895, L"ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH"}, + {5896, L"ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP"}, + {5897, L"ERROR_CLUSTER_PARAMETER_MISMATCH"}, + {5898, L"ERROR_NODE_CANNOT_BE_CLUSTERED"}, + {5899, L"ERROR_CLUSTER_WRONG_OS_VERSION"}, + {5900, L"ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME"}, + {5901, L"ERROR_CLUSCFG_ALREADY_COMMITTED"}, + {5902, L"ERROR_CLUSCFG_ROLLBACK_FAILED"}, + {5903, L"ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT"}, + {5904, L"ERROR_CLUSTER_OLD_VERSION"}, + {5905, L"ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME"}, + {5906, L"ERROR_CLUSTER_NO_NET_ADAPTERS"}, + {5907, L"ERROR_CLUSTER_POISONED"}, + {5908, L"ERROR_CLUSTER_GROUP_MOVING"}, + {5909, L"ERROR_CLUSTER_RESOURCE_TYPE_BUSY"}, + {5910, L"ERROR_RESOURCE_CALL_TIMED_OUT"}, + {5911, L"ERROR_INVALID_CLUSTER_IPV6_ADDRESS"}, + {5912, L"ERROR_CLUSTER_INTERNAL_INVALID_FUNCTION"}, + {5913, L"ERROR_CLUSTER_PARAMETER_OUT_OF_BOUNDS"}, + {5914, L"ERROR_CLUSTER_PARTIAL_SEND"}, + {5915, L"ERROR_CLUSTER_REGISTRY_INVALID_FUNCTION"}, + {5916, L"ERROR_CLUSTER_INVALID_STRING_TERMINATION"}, + {5917, L"ERROR_CLUSTER_INVALID_STRING_FORMAT"}, + {5918, L"ERROR_CLUSTER_DATABASE_TRANSACTION_IN_PROGRESS"}, + {5919, L"ERROR_CLUSTER_DATABASE_TRANSACTION_NOT_IN_PROGRESS"}, + {5920, L"ERROR_CLUSTER_NULL_DATA"}, + {5921, L"ERROR_CLUSTER_PARTIAL_READ"}, + {5922, L"ERROR_CLUSTER_PARTIAL_WRITE"}, + {5923, L"ERROR_CLUSTER_CANT_DESERIALIZE_DATA"}, + {5924, L"ERROR_DEPENDENT_RESOURCE_PROPERTY_CONFLICT"}, + {5925, L"ERROR_CLUSTER_NO_QUORUM"}, + {5926, L"ERROR_CLUSTER_INVALID_IPV6_NETWORK"}, + {5927, L"ERROR_CLUSTER_INVALID_IPV6_TUNNEL_NETWORK"}, + {5928, L"ERROR_QUORUM_NOT_ALLOWED_IN_THIS_GROUP"}, + {5929, L"ERROR_DEPENDENCY_TREE_TOO_COMPLEX"}, + {5930, L"ERROR_EXCEPTION_IN_RESOURCE_CALL"}, + {5931, L"ERROR_CLUSTER_RHS_FAILED_INITIALIZATION"}, + {5932, L"ERROR_CLUSTER_NOT_INSTALLED"}, + {5933, L"ERROR_CLUSTER_RESOURCES_MUST_BE_ONLINE_ON_THE_SAME_NODE"}, + {5934, L"ERROR_CLUSTER_MAX_NODES_IN_CLUSTER"}, + {5935, L"ERROR_CLUSTER_TOO_MANY_NODES"}, + {5936, L"ERROR_CLUSTER_OBJECT_ALREADY_USED"}, + {5937, L"ERROR_NONCORE_GROUPS_FOUND"}, + {5938, L"ERROR_FILE_SHARE_RESOURCE_CONFLICT"}, + {5939, L"ERROR_CLUSTER_EVICT_INVALID_REQUEST"}, + {5940, L"ERROR_CLUSTER_SINGLETON_RESOURCE"}, + {5941, L"ERROR_CLUSTER_GROUP_SINGLETON_RESOURCE"}, + {5942, L"ERROR_CLUSTER_RESOURCE_PROVIDER_FAILED"}, + {5943, L"ERROR_CLUSTER_RESOURCE_CONFIGURATION_ERROR"}, + {5944, L"ERROR_CLUSTER_GROUP_BUSY"}, + {5945, L"ERROR_CLUSTER_NOT_SHARED_VOLUME"}, + {5946, L"ERROR_CLUSTER_INVALID_SECURITY_DESCRIPTOR"}, + {5947, L"ERROR_CLUSTER_SHARED_VOLUMES_IN_USE"}, + {5948, L"ERROR_CLUSTER_USE_SHARED_VOLUMES_API"}, + {5949, L"ERROR_CLUSTER_BACKUP_IN_PROGRESS"}, + {5950, L"ERROR_NON_CSV_PATH"}, + {5951, L"ERROR_CSV_VOLUME_NOT_LOCAL"}, + {5952, L"ERROR_CLUSTER_WATCHDOG_TERMINATING"}, + {5953, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_INCOMPATIBLE_NODES"}, + {5954, L"ERROR_CLUSTER_INVALID_NODE_WEIGHT"}, + {5955, L"ERROR_CLUSTER_RESOURCE_VETOED_CALL"}, + {5956, L"ERROR_RESMON_SYSTEM_RESOURCES_LACKING"}, + {5957, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_DESTINATION"}, + {5958, L"ERROR_CLUSTER_RESOURCE_VETOED_MOVE_NOT_ENOUGH_RESOURCES_ON_SOURCE"}, + {5959, L"ERROR_CLUSTER_GROUP_QUEUED"}, + {5960, L"ERROR_CLUSTER_RESOURCE_LOCKED_STATUS"}, + {5961, L"ERROR_CLUSTER_SHARED_VOLUME_FAILOVER_NOT_ALLOWED"}, + {5962, L"ERROR_CLUSTER_NODE_DRAIN_IN_PROGRESS"}, + {5963, L"ERROR_CLUSTER_DISK_NOT_CONNECTED"}, + {5964, L"ERROR_DISK_NOT_CSV_CAPABLE"}, + {5965, L"ERROR_RESOURCE_NOT_IN_AVAILABLE_STORAGE"}, + {5966, L"ERROR_CLUSTER_SHARED_VOLUME_REDIRECTED"}, + {5967, L"ERROR_CLUSTER_SHARED_VOLUME_NOT_REDIRECTED"}, + {5968, L"ERROR_CLUSTER_CANNOT_RETURN_PROPERTIES"}, + {5969, L"ERROR_CLUSTER_RESOURCE_CONTAINS_UNSUPPORTED_DIFF_AREA_FOR_SHARED_VOLUMES"}, + {5970, L"ERROR_CLUSTER_RESOURCE_IS_IN_MAINTENANCE_MODE"}, + {5971, L"ERROR_CLUSTER_AFFINITY_CONFLICT"}, + {5972, L"ERROR_CLUSTER_RESOURCE_IS_REPLICA_VIRTUAL_MACHINE"}, + {6000, L"ERROR_ENCRYPTION_FAILED"}, + {6001, L"ERROR_DECRYPTION_FAILED"}, + {6002, L"ERROR_FILE_ENCRYPTED"}, + {6003, L"ERROR_NO_RECOVERY_POLICY"}, + {6004, L"ERROR_NO_EFS"}, + {6005, L"ERROR_WRONG_EFS"}, + {6006, L"ERROR_NO_USER_KEYS"}, + {6007, L"ERROR_FILE_NOT_ENCRYPTED"}, + {6008, L"ERROR_NOT_EXPORT_FORMAT"}, + {6009, L"ERROR_FILE_READ_ONLY"}, + {6010, L"ERROR_DIR_EFS_DISALLOWED"}, + {6011, L"ERROR_EFS_SERVER_NOT_TRUSTED"}, + {6012, L"ERROR_BAD_RECOVERY_POLICY"}, + {6013, L"ERROR_EFS_ALG_BLOB_TOO_BIG"}, + {6014, L"ERROR_VOLUME_NOT_SUPPORT_EFS"}, + {6015, L"ERROR_EFS_DISABLED"}, + {6016, L"ERROR_EFS_VERSION_NOT_SUPPORT"}, + {6017, L"ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE"}, + {6018, L"ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER"}, + {6019, L"ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE"}, + {6020, L"ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE"}, + {6021, L"ERROR_CS_ENCRYPTION_FILE_NOT_CSE"}, + {6022, L"ERROR_ENCRYPTION_POLICY_DENIES_OPERATION"}, + {6118, L"ERROR_NO_BROWSER_SERVERS_FOUND"}, + {6200, L"SCHED_E_SERVICE_NOT_LOCALSYSTEM"}, + {6600, L"ERROR_LOG_SECTOR_INVALID"}, + {6601, L"ERROR_LOG_SECTOR_PARITY_INVALID"}, + {6602, L"ERROR_LOG_SECTOR_REMAPPED"}, + {6603, L"ERROR_LOG_BLOCK_INCOMPLETE"}, + {6604, L"ERROR_LOG_INVALID_RANGE"}, + {6605, L"ERROR_LOG_BLOCKS_EXHAUSTED"}, + {6606, L"ERROR_LOG_READ_CONTEXT_INVALID"}, + {6607, L"ERROR_LOG_RESTART_INVALID"}, + {6608, L"ERROR_LOG_BLOCK_VERSION"}, + {6609, L"ERROR_LOG_BLOCK_INVALID"}, + {6610, L"ERROR_LOG_READ_MODE_INVALID"}, + {6611, L"ERROR_LOG_NO_RESTART"}, + {6612, L"ERROR_LOG_METADATA_CORRUPT"}, + {6613, L"ERROR_LOG_METADATA_INVALID"}, + {6614, L"ERROR_LOG_METADATA_INCONSISTENT"}, + {6615, L"ERROR_LOG_RESERVATION_INVALID"}, + {6616, L"ERROR_LOG_CANT_DELETE"}, + {6617, L"ERROR_LOG_CONTAINER_LIMIT_EXCEEDED"}, + {6618, L"ERROR_LOG_START_OF_LOG"}, + {6619, L"ERROR_LOG_POLICY_ALREADY_INSTALLED"}, + {6620, L"ERROR_LOG_POLICY_NOT_INSTALLED"}, + {6621, L"ERROR_LOG_POLICY_INVALID"}, + {6622, L"ERROR_LOG_POLICY_CONFLICT"}, + {6623, L"ERROR_LOG_PINNED_ARCHIVE_TAIL"}, + {6624, L"ERROR_LOG_RECORD_NONEXISTENT"}, + {6625, L"ERROR_LOG_RECORDS_RESERVED_INVALID"}, + {6626, L"ERROR_LOG_SPACE_RESERVED_INVALID"}, + {6627, L"ERROR_LOG_TAIL_INVALID"}, + {6628, L"ERROR_LOG_FULL"}, + {6629, L"ERROR_COULD_NOT_RESIZE_LOG"}, + {6630, L"ERROR_LOG_MULTIPLEXED"}, + {6631, L"ERROR_LOG_DEDICATED"}, + {6632, L"ERROR_LOG_ARCHIVE_NOT_IN_PROGRESS"}, + {6633, L"ERROR_LOG_ARCHIVE_IN_PROGRESS"}, + {6634, L"ERROR_LOG_EPHEMERAL"}, + {6635, L"ERROR_LOG_NOT_ENOUGH_CONTAINERS"}, + {6636, L"ERROR_LOG_CLIENT_ALREADY_REGISTERED"}, + {6637, L"ERROR_LOG_CLIENT_NOT_REGISTERED"}, + {6638, L"ERROR_LOG_FULL_HANDLER_IN_PROGRESS"}, + {6639, L"ERROR_LOG_CONTAINER_READ_FAILED"}, + {6640, L"ERROR_LOG_CONTAINER_WRITE_FAILED"}, + {6641, L"ERROR_LOG_CONTAINER_OPEN_FAILED"}, + {6642, L"ERROR_LOG_CONTAINER_STATE_INVALID"}, + {6643, L"ERROR_LOG_STATE_INVALID"}, + {6644, L"ERROR_LOG_PINNED"}, + {6645, L"ERROR_LOG_METADATA_FLUSH_FAILED"}, + {6646, L"ERROR_LOG_INCONSISTENT_SECURITY"}, + {6647, L"ERROR_LOG_APPENDED_FLUSH_FAILED"}, + {6648, L"ERROR_LOG_PINNED_RESERVATION"}, + {6700, L"ERROR_INVALID_TRANSACTION"}, + {6701, L"ERROR_TRANSACTION_NOT_ACTIVE"}, + {6702, L"ERROR_TRANSACTION_REQUEST_NOT_VALID"}, + {6703, L"ERROR_TRANSACTION_NOT_REQUESTED"}, + {6704, L"ERROR_TRANSACTION_ALREADY_ABORTED"}, + {6705, L"ERROR_TRANSACTION_ALREADY_COMMITTED"}, + {6706, L"ERROR_TM_INITIALIZATION_FAILED"}, + {6707, L"ERROR_RESOURCEMANAGER_READ_ONLY"}, + {6708, L"ERROR_TRANSACTION_NOT_JOINED"}, + {6709, L"ERROR_TRANSACTION_SUPERIOR_EXISTS"}, + {6710, L"ERROR_CRM_PROTOCOL_ALREADY_EXISTS"}, + {6711, L"ERROR_TRANSACTION_PROPAGATION_FAILED"}, + {6712, L"ERROR_CRM_PROTOCOL_NOT_FOUND"}, + {6713, L"ERROR_TRANSACTION_INVALID_MARSHALL_BUFFER"}, + {6714, L"ERROR_CURRENT_TRANSACTION_NOT_VALID"}, + {6715, L"ERROR_TRANSACTION_NOT_FOUND"}, + {6716, L"ERROR_RESOURCEMANAGER_NOT_FOUND"}, + {6717, L"ERROR_ENLISTMENT_NOT_FOUND"}, + {6718, L"ERROR_TRANSACTIONMANAGER_NOT_FOUND"}, + {6719, L"ERROR_TRANSACTIONMANAGER_NOT_ONLINE"}, + {6720, L"ERROR_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION"}, + {6721, L"ERROR_TRANSACTION_NOT_ROOT"}, + {6722, L"ERROR_TRANSACTION_OBJECT_EXPIRED"}, + {6723, L"ERROR_TRANSACTION_RESPONSE_NOT_ENLISTED"}, + {6724, L"ERROR_TRANSACTION_RECORD_TOO_LONG"}, + {6725, L"ERROR_IMPLICIT_TRANSACTION_NOT_SUPPORTED"}, + {6726, L"ERROR_TRANSACTION_INTEGRITY_VIOLATED"}, + {6727, L"ERROR_TRANSACTIONMANAGER_IDENTITY_MISMATCH"}, + {6728, L"ERROR_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT"}, + {6729, L"ERROR_TRANSACTION_MUST_WRITETHROUGH"}, + {6730, L"ERROR_TRANSACTION_NO_SUPERIOR"}, + {6731, L"ERROR_HEURISTIC_DAMAGE_POSSIBLE"}, + {6800, L"ERROR_TRANSACTIONAL_CONFLICT"}, + {6801, L"ERROR_RM_NOT_ACTIVE"}, + {6802, L"ERROR_RM_METADATA_CORRUPT"}, + {6803, L"ERROR_DIRECTORY_NOT_RM"}, + {6805, L"ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE"}, + {6806, L"ERROR_LOG_RESIZE_INVALID_SIZE"}, + {6807, L"ERROR_OBJECT_NO_LONGER_EXISTS"}, + {6808, L"ERROR_STREAM_MINIVERSION_NOT_FOUND"}, + {6809, L"ERROR_STREAM_MINIVERSION_NOT_VALID"}, + {6810, L"ERROR_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION"}, + {6811, L"ERROR_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT"}, + {6812, L"ERROR_CANT_CREATE_MORE_STREAM_MINIVERSIONS"}, + {6814, L"ERROR_REMOTE_FILE_VERSION_MISMATCH"}, + {6815, L"ERROR_HANDLE_NO_LONGER_VALID"}, + {6816, L"ERROR_NO_TXF_METADATA"}, + {6817, L"ERROR_LOG_CORRUPTION_DETECTED"}, + {6818, L"ERROR_CANT_RECOVER_WITH_HANDLE_OPEN"}, + {6819, L"ERROR_RM_DISCONNECTED"}, + {6820, L"ERROR_ENLISTMENT_NOT_SUPERIOR"}, + {6821, L"ERROR_RECOVERY_NOT_NEEDED"}, + {6822, L"ERROR_RM_ALREADY_STARTED"}, + {6823, L"ERROR_FILE_IDENTITY_NOT_PERSISTENT"}, + {6824, L"ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCY"}, + {6825, L"ERROR_CANT_CROSS_RM_BOUNDARY"}, + {6826, L"ERROR_TXF_DIR_NOT_EMPTY"}, + {6827, L"ERROR_INDOUBT_TRANSACTIONS_EXIST"}, + {6828, L"ERROR_TM_VOLATILE"}, + {6829, L"ERROR_ROLLBACK_TIMER_EXPIRED"}, + {6830, L"ERROR_TXF_ATTRIBUTE_CORRUPT"}, + {6831, L"ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION"}, + {6832, L"ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED"}, + {6833, L"ERROR_LOG_GROWTH_FAILED"}, + {6834, L"ERROR_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE"}, + {6835, L"ERROR_TXF_METADATA_ALREADY_PRESENT"}, + {6836, L"ERROR_TRANSACTION_SCOPE_CALLBACKS_NOT_SET"}, + {6837, L"ERROR_TRANSACTION_REQUIRED_PROMOTION"}, + {6838, L"ERROR_CANNOT_EXECUTE_FILE_IN_TRANSACTION"}, + {6839, L"ERROR_TRANSACTIONS_NOT_FROZEN"}, + {6840, L"ERROR_TRANSACTION_FREEZE_IN_PROGRESS"}, + {6841, L"ERROR_NOT_SNAPSHOT_VOLUME"}, + {6842, L"ERROR_NO_SAVEPOINT_WITH_OPEN_FILES"}, + {6843, L"ERROR_DATA_LOST_REPAIR"}, + {6844, L"ERROR_SPARSE_NOT_ALLOWED_IN_TRANSACTION"}, + {6845, L"ERROR_TM_IDENTITY_MISMATCH"}, + {6846, L"ERROR_FLOATED_SECTION"}, + {6847, L"ERROR_CANNOT_ACCEPT_TRANSACTED_WORK"}, + {6848, L"ERROR_CANNOT_ABORT_TRANSACTIONS"}, + {6849, L"ERROR_BAD_CLUSTERS"}, + {6850, L"ERROR_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION"}, + {6851, L"ERROR_VOLUME_DIRTY"}, + {6852, L"ERROR_NO_LINK_TRACKING_IN_TRANSACTION"}, + {6853, L"ERROR_OPERATION_NOT_SUPPORTED_IN_TRANSACTION"}, + {6854, L"ERROR_EXPIRED_HANDLE"}, + {6855, L"ERROR_TRANSACTION_NOT_ENLISTED"}, + {7001, L"ERROR_CTX_WINSTATION_NAME_INVALID"}, + {7002, L"ERROR_CTX_INVALID_PD"}, + {7003, L"ERROR_CTX_PD_NOT_FOUND"}, + {7004, L"ERROR_CTX_WD_NOT_FOUND"}, + {7005, L"ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY"}, + {7006, L"ERROR_CTX_SERVICE_NAME_COLLISION"}, + {7007, L"ERROR_CTX_CLOSE_PENDING"}, + {7008, L"ERROR_CTX_NO_OUTBUF"}, + {7009, L"ERROR_CTX_MODEM_INF_NOT_FOUND"}, + {7010, L"ERROR_CTX_INVALID_MODEMNAME"}, + {7011, L"ERROR_CTX_MODEM_RESPONSE_ERROR"}, + {7012, L"ERROR_CTX_MODEM_RESPONSE_TIMEOUT"}, + {7013, L"ERROR_CTX_MODEM_RESPONSE_NO_CARRIER"}, + {7014, L"ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE"}, + {7015, L"ERROR_CTX_MODEM_RESPONSE_BUSY"}, + {7016, L"ERROR_CTX_MODEM_RESPONSE_VOICE"}, + {7017, L"ERROR_CTX_TD_ERROR"}, + {7022, L"ERROR_CTX_WINSTATION_NOT_FOUND"}, + {7023, L"ERROR_CTX_WINSTATION_ALREADY_EXISTS"}, + {7024, L"ERROR_CTX_WINSTATION_BUSY"}, + {7025, L"ERROR_CTX_BAD_VIDEO_MODE"}, + {7035, L"ERROR_CTX_GRAPHICS_INVALID"}, + {7037, L"ERROR_CTX_LOGON_DISABLED"}, + {7038, L"ERROR_CTX_NOT_CONSOLE"}, + {7040, L"ERROR_CTX_CLIENT_QUERY_TIMEOUT"}, + {7041, L"ERROR_CTX_CONSOLE_DISCONNECT"}, + {7042, L"ERROR_CTX_CONSOLE_CONNECT"}, + {7044, L"ERROR_CTX_SHADOW_DENIED"}, + {7045, L"ERROR_CTX_WINSTATION_ACCESS_DENIED"}, + {7049, L"ERROR_CTX_INVALID_WD"}, + {7050, L"ERROR_CTX_SHADOW_INVALID"}, + {7051, L"ERROR_CTX_SHADOW_DISABLED"}, + {7052, L"ERROR_CTX_CLIENT_LICENSE_IN_USE"}, + {7053, L"ERROR_CTX_CLIENT_LICENSE_NOT_SET"}, + {7054, L"ERROR_CTX_LICENSE_NOT_AVAILABLE"}, + {7055, L"ERROR_CTX_LICENSE_CLIENT_INVALID"}, + {7056, L"ERROR_CTX_LICENSE_EXPIRED"}, + {7057, L"ERROR_CTX_SHADOW_NOT_RUNNING"}, + {7058, L"ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE"}, + {7059, L"ERROR_ACTIVATION_COUNT_EXCEEDED"}, + {7060, L"ERROR_CTX_WINSTATIONS_DISABLED"}, + {7061, L"ERROR_CTX_ENCRYPTION_LEVEL_REQUIRED"}, + {7062, L"ERROR_CTX_SESSION_IN_USE"}, + {7063, L"ERROR_CTX_NO_FORCE_LOGOFF"}, + {7064, L"ERROR_CTX_ACCOUNT_RESTRICTION"}, + {7065, L"ERROR_RDP_PROTOCOL_ERROR"}, + {7066, L"ERROR_CTX_CDM_CONNECT"}, + {7067, L"ERROR_CTX_CDM_DISCONNECT"}, + {7068, L"ERROR_CTX_SECURITY_LAYER_ERROR"}, + {7069, L"ERROR_TS_INCOMPATIBLE_SESSIONS"}, + {7070, L"ERROR_TS_VIDEO_SUBSYSTEM_ERROR"}, + {8001, L"FRS_ERR_INVALID_API_SEQUENCE"}, + {8002, L"FRS_ERR_STARTING_SERVICE"}, + {8003, L"FRS_ERR_STOPPING_SERVICE"}, + {8004, L"FRS_ERR_INTERNAL_API"}, + {8005, L"FRS_ERR_INTERNAL"}, + {8006, L"FRS_ERR_SERVICE_COMM"}, + {8007, L"FRS_ERR_INSUFFICIENT_PRIV"}, + {8008, L"FRS_ERR_AUTHENTICATION"}, + {8009, L"FRS_ERR_PARENT_INSUFFICIENT_PRIV"}, + {8010, L"FRS_ERR_PARENT_AUTHENTICATION"}, + {8011, L"FRS_ERR_CHILD_TO_PARENT_COMM"}, + {8012, L"FRS_ERR_PARENT_TO_CHILD_COMM"}, + {8013, L"FRS_ERR_SYSVOL_POPULATE"}, + {8014, L"FRS_ERR_SYSVOL_POPULATE_TIMEOUT"}, + {8015, L"FRS_ERR_SYSVOL_IS_BUSY"}, + {8016, L"FRS_ERR_SYSVOL_DEMOTE"}, + {8017, L"FRS_ERR_INVALID_SERVICE_PARAMETER"}, + {8200, L"ERROR_DS_NOT_INSTALLED"}, + {8201, L"ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY"}, + {8202, L"ERROR_DS_NO_ATTRIBUTE_OR_VALUE"}, + {8203, L"ERROR_DS_INVALID_ATTRIBUTE_SYNTAX"}, + {8204, L"ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED"}, + {8205, L"ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS"}, + {8206, L"ERROR_DS_BUSY"}, + {8207, L"ERROR_DS_UNAVAILABLE"}, + {8208, L"ERROR_DS_NO_RIDS_ALLOCATED"}, + {8209, L"ERROR_DS_NO_MORE_RIDS"}, + {8210, L"ERROR_DS_INCORRECT_ROLE_OWNER"}, + {8211, L"ERROR_DS_RIDMGR_INIT_ERROR"}, + {8212, L"ERROR_DS_OBJ_CLASS_VIOLATION"}, + {8213, L"ERROR_DS_CANT_ON_NON_LEAF"}, + {8214, L"ERROR_DS_CANT_ON_RDN"}, + {8215, L"ERROR_DS_CANT_MOD_OBJ_CLASS"}, + {8216, L"ERROR_DS_CROSS_DOM_MOVE_ERROR"}, + {8217, L"ERROR_DS_GC_NOT_AVAILABLE"}, + {8218, L"ERROR_SHARED_POLICY"}, + {8219, L"ERROR_POLICY_OBJECT_NOT_FOUND"}, + {8220, L"ERROR_POLICY_ONLY_IN_DS"}, + {8221, L"ERROR_PROMOTION_ACTIVE"}, + {8222, L"ERROR_NO_PROMOTION_ACTIVE"}, + {8224, L"ERROR_DS_OPERATIONS_ERROR"}, + {8225, L"ERROR_DS_PROTOCOL_ERROR"}, + {8226, L"ERROR_DS_TIMELIMIT_EXCEEDED"}, + {8227, L"ERROR_DS_SIZELIMIT_EXCEEDED"}, + {8228, L"ERROR_DS_ADMIN_LIMIT_EXCEEDED"}, + {8229, L"ERROR_DS_COMPARE_FALSE"}, + {8230, L"ERROR_DS_COMPARE_TRUE"}, + {8231, L"ERROR_DS_AUTH_METHOD_NOT_SUPPORTED"}, + {8232, L"ERROR_DS_STRONG_AUTH_REQUIRED"}, + {8233, L"ERROR_DS_INAPPROPRIATE_AUTH"}, + {8234, L"ERROR_DS_AUTH_UNKNOWN"}, + {8235, L"ERROR_DS_REFERRAL"}, + {8236, L"ERROR_DS_UNAVAILABLE_CRIT_EXTENSION"}, + {8237, L"ERROR_DS_CONFIDENTIALITY_REQUIRED"}, + {8238, L"ERROR_DS_INAPPROPRIATE_MATCHING"}, + {8239, L"ERROR_DS_CONSTRAINT_VIOLATION"}, + {8240, L"ERROR_DS_NO_SUCH_OBJECT"}, + {8241, L"ERROR_DS_ALIAS_PROBLEM"}, + {8242, L"ERROR_DS_INVALID_DN_SYNTAX"}, + {8243, L"ERROR_DS_IS_LEAF"}, + {8244, L"ERROR_DS_ALIAS_DEREF_PROBLEM"}, + {8245, L"ERROR_DS_UNWILLING_TO_PERFORM"}, + {8246, L"ERROR_DS_LOOP_DETECT"}, + {8247, L"ERROR_DS_NAMING_VIOLATION"}, + {8248, L"ERROR_DS_OBJECT_RESULTS_TOO_LARGE"}, + {8249, L"ERROR_DS_AFFECTS_MULTIPLE_DSAS"}, + {8250, L"ERROR_DS_SERVER_DOWN"}, + {8251, L"ERROR_DS_LOCAL_ERROR"}, + {8252, L"ERROR_DS_ENCODING_ERROR"}, + {8253, L"ERROR_DS_DECODING_ERROR"}, + {8254, L"ERROR_DS_FILTER_UNKNOWN"}, + {8255, L"ERROR_DS_PARAM_ERROR"}, + {8256, L"ERROR_DS_NOT_SUPPORTED"}, + {8257, L"ERROR_DS_NO_RESULTS_RETURNED"}, + {8258, L"ERROR_DS_CONTROL_NOT_FOUND"}, + {8259, L"ERROR_DS_CLIENT_LOOP"}, + {8260, L"ERROR_DS_REFERRAL_LIMIT_EXCEEDED"}, + {8261, L"ERROR_DS_SORT_CONTROL_MISSING"}, + {8262, L"ERROR_DS_OFFSET_RANGE_ERROR"}, + {8263, L"ERROR_DS_RIDMGR_DISABLED"}, + {8301, L"ERROR_DS_ROOT_MUST_BE_NC"}, + {8302, L"ERROR_DS_ADD_REPLICA_INHIBITED"}, + {8303, L"ERROR_DS_ATT_NOT_DEF_IN_SCHEMA"}, + {8304, L"ERROR_DS_MAX_OBJ_SIZE_EXCEEDED"}, + {8305, L"ERROR_DS_OBJ_STRING_NAME_EXISTS"}, + {8306, L"ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA"}, + {8307, L"ERROR_DS_RDN_DOESNT_MATCH_SCHEMA"}, + {8308, L"ERROR_DS_NO_REQUESTED_ATTS_FOUND"}, + {8309, L"ERROR_DS_USER_BUFFER_TO_SMALL"}, + {8310, L"ERROR_DS_ATT_IS_NOT_ON_OBJ"}, + {8311, L"ERROR_DS_ILLEGAL_MOD_OPERATION"}, + {8312, L"ERROR_DS_OBJ_TOO_LARGE"}, + {8313, L"ERROR_DS_BAD_INSTANCE_TYPE"}, + {8314, L"ERROR_DS_MASTERDSA_REQUIRED"}, + {8315, L"ERROR_DS_OBJECT_CLASS_REQUIRED"}, + {8316, L"ERROR_DS_MISSING_REQUIRED_ATT"}, + {8317, L"ERROR_DS_ATT_NOT_DEF_FOR_CLASS"}, + {8318, L"ERROR_DS_ATT_ALREADY_EXISTS"}, + {8320, L"ERROR_DS_CANT_ADD_ATT_VALUES"}, + {8321, L"ERROR_DS_SINGLE_VALUE_CONSTRAINT"}, + {8322, L"ERROR_DS_RANGE_CONSTRAINT"}, + {8323, L"ERROR_DS_ATT_VAL_ALREADY_EXISTS"}, + {8324, L"ERROR_DS_CANT_REM_MISSING_ATT"}, + {8325, L"ERROR_DS_CANT_REM_MISSING_ATT_VAL"}, + {8326, L"ERROR_DS_ROOT_CANT_BE_SUBREF"}, + {8327, L"ERROR_DS_NO_CHAINING"}, + {8328, L"ERROR_DS_NO_CHAINED_EVAL"}, + {8329, L"ERROR_DS_NO_PARENT_OBJECT"}, + {8330, L"ERROR_DS_PARENT_IS_AN_ALIAS"}, + {8331, L"ERROR_DS_CANT_MIX_MASTER_AND_REPS"}, + {8332, L"ERROR_DS_CHILDREN_EXIST"}, + {8333, L"ERROR_DS_OBJ_NOT_FOUND"}, + {8334, L"ERROR_DS_ALIASED_OBJ_MISSING"}, + {8335, L"ERROR_DS_BAD_NAME_SYNTAX"}, + {8336, L"ERROR_DS_ALIAS_POINTS_TO_ALIAS"}, + {8337, L"ERROR_DS_CANT_DEREF_ALIAS"}, + {8338, L"ERROR_DS_OUT_OF_SCOPE"}, + {8339, L"ERROR_DS_OBJECT_BEING_REMOVED"}, + {8340, L"ERROR_DS_CANT_DELETE_DSA_OBJ"}, + {8341, L"ERROR_DS_GENERIC_ERROR"}, + {8342, L"ERROR_DS_DSA_MUST_BE_INT_MASTER"}, + {8343, L"ERROR_DS_CLASS_NOT_DSA"}, + {8344, L"ERROR_DS_INSUFF_ACCESS_RIGHTS"}, + {8345, L"ERROR_DS_ILLEGAL_SUPERIOR"}, + {8346, L"ERROR_DS_ATTRIBUTE_OWNED_BY_SAM"}, + {8347, L"ERROR_DS_NAME_TOO_MANY_PARTS"}, + {8348, L"ERROR_DS_NAME_TOO_LONG"}, + {8349, L"ERROR_DS_NAME_VALUE_TOO_LONG"}, + {8350, L"ERROR_DS_NAME_UNPARSEABLE"}, + {8351, L"ERROR_DS_NAME_TYPE_UNKNOWN"}, + {8352, L"ERROR_DS_NOT_AN_OBJECT"}, + {8353, L"ERROR_DS_SEC_DESC_TOO_SHORT"}, + {8354, L"ERROR_DS_SEC_DESC_INVALID"}, + {8355, L"ERROR_DS_NO_DELETED_NAME"}, + {8356, L"ERROR_DS_SUBREF_MUST_HAVE_PARENT"}, + {8357, L"ERROR_DS_NCNAME_MUST_BE_NC"}, + {8358, L"ERROR_DS_CANT_ADD_SYSTEM_ONLY"}, + {8359, L"ERROR_DS_CLASS_MUST_BE_CONCRETE"}, + {8360, L"ERROR_DS_INVALID_DMD"}, + {8361, L"ERROR_DS_OBJ_GUID_EXISTS"}, + {8362, L"ERROR_DS_NOT_ON_BACKLINK"}, + {8363, L"ERROR_DS_NO_CROSSREF_FOR_NC"}, + {8364, L"ERROR_DS_SHUTTING_DOWN"}, + {8365, L"ERROR_DS_UNKNOWN_OPERATION"}, + {8366, L"ERROR_DS_INVALID_ROLE_OWNER"}, + {8367, L"ERROR_DS_COULDNT_CONTACT_FSMO"}, + {8368, L"ERROR_DS_CROSS_NC_DN_RENAME"}, + {8369, L"ERROR_DS_CANT_MOD_SYSTEM_ONLY"}, + {8370, L"ERROR_DS_REPLICATOR_ONLY"}, + {8371, L"ERROR_DS_OBJ_CLASS_NOT_DEFINED"}, + {8372, L"ERROR_DS_OBJ_CLASS_NOT_SUBCLASS"}, + {8373, L"ERROR_DS_NAME_REFERENCE_INVALID"}, + {8374, L"ERROR_DS_CROSS_REF_EXISTS"}, + {8375, L"ERROR_DS_CANT_DEL_MASTER_CROSSREF"}, + {8376, L"ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD"}, + {8377, L"ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX"}, + {8378, L"ERROR_DS_DUP_RDN"}, + {8379, L"ERROR_DS_DUP_OID"}, + {8380, L"ERROR_DS_DUP_MAPI_ID"}, + {8381, L"ERROR_DS_DUP_SCHEMA_ID_GUID"}, + {8382, L"ERROR_DS_DUP_LDAP_DISPLAY_NAME"}, + {8383, L"ERROR_DS_SEMANTIC_ATT_TEST"}, + {8384, L"ERROR_DS_SYNTAX_MISMATCH"}, + {8385, L"ERROR_DS_EXISTS_IN_MUST_HAVE"}, + {8386, L"ERROR_DS_EXISTS_IN_MAY_HAVE"}, + {8387, L"ERROR_DS_NONEXISTENT_MAY_HAVE"}, + {8388, L"ERROR_DS_NONEXISTENT_MUST_HAVE"}, + {8389, L"ERROR_DS_AUX_CLS_TEST_FAIL"}, + {8390, L"ERROR_DS_NONEXISTENT_POSS_SUP"}, + {8391, L"ERROR_DS_SUB_CLS_TEST_FAIL"}, + {8392, L"ERROR_DS_BAD_RDN_ATT_ID_SYNTAX"}, + {8393, L"ERROR_DS_EXISTS_IN_AUX_CLS"}, + {8394, L"ERROR_DS_EXISTS_IN_SUB_CLS"}, + {8395, L"ERROR_DS_EXISTS_IN_POSS_SUP"}, + {8396, L"ERROR_DS_RECALCSCHEMA_FAILED"}, + {8397, L"ERROR_DS_TREE_DELETE_NOT_FINISHED"}, + {8398, L"ERROR_DS_CANT_DELETE"}, + {8399, L"ERROR_DS_ATT_SCHEMA_REQ_ID"}, + {8400, L"ERROR_DS_BAD_ATT_SCHEMA_SYNTAX"}, + {8401, L"ERROR_DS_CANT_CACHE_ATT"}, + {8402, L"ERROR_DS_CANT_CACHE_CLASS"}, + {8403, L"ERROR_DS_CANT_REMOVE_ATT_CACHE"}, + {8404, L"ERROR_DS_CANT_REMOVE_CLASS_CACHE"}, + {8405, L"ERROR_DS_CANT_RETRIEVE_DN"}, + {8406, L"ERROR_DS_MISSING_SUPREF"}, + {8407, L"ERROR_DS_CANT_RETRIEVE_INSTANCE"}, + {8408, L"ERROR_DS_CODE_INCONSISTENCY"}, + {8409, L"ERROR_DS_DATABASE_ERROR"}, + {8410, L"ERROR_DS_GOVERNSID_MISSING"}, + {8411, L"ERROR_DS_MISSING_EXPECTED_ATT"}, + {8412, L"ERROR_DS_NCNAME_MISSING_CR_REF"}, + {8413, L"ERROR_DS_SECURITY_CHECKING_ERROR"}, + {8414, L"ERROR_DS_SCHEMA_NOT_LOADED"}, + {8415, L"ERROR_DS_SCHEMA_ALLOC_FAILED"}, + {8416, L"ERROR_DS_ATT_SCHEMA_REQ_SYNTAX"}, + {8417, L"ERROR_DS_GCVERIFY_ERROR"}, + {8418, L"ERROR_DS_DRA_SCHEMA_MISMATCH"}, + {8419, L"ERROR_DS_CANT_FIND_DSA_OBJ"}, + {8420, L"ERROR_DS_CANT_FIND_EXPECTED_NC"}, + {8421, L"ERROR_DS_CANT_FIND_NC_IN_CACHE"}, + {8422, L"ERROR_DS_CANT_RETRIEVE_CHILD"}, + {8423, L"ERROR_DS_SECURITY_ILLEGAL_MODIFY"}, + {8424, L"ERROR_DS_CANT_REPLACE_HIDDEN_REC"}, + {8425, L"ERROR_DS_BAD_HIERARCHY_FILE"}, + {8426, L"ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED"}, + {8427, L"ERROR_DS_CONFIG_PARAM_MISSING"}, + {8428, L"ERROR_DS_COUNTING_AB_INDICES_FAILED"}, + {8429, L"ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED"}, + {8430, L"ERROR_DS_INTERNAL_FAILURE"}, + {8431, L"ERROR_DS_UNKNOWN_ERROR"}, + {8432, L"ERROR_DS_ROOT_REQUIRES_CLASS_TOP"}, + {8433, L"ERROR_DS_REFUSING_FSMO_ROLES"}, + {8434, L"ERROR_DS_MISSING_FSMO_SETTINGS"}, + {8435, L"ERROR_DS_UNABLE_TO_SURRENDER_ROLES"}, + {8436, L"ERROR_DS_DRA_GENERIC"}, + {8437, L"ERROR_DS_DRA_INVALID_PARAMETER"}, + {8438, L"ERROR_DS_DRA_BUSY"}, + {8439, L"ERROR_DS_DRA_BAD_DN"}, + {8440, L"ERROR_DS_DRA_BAD_NC"}, + {8441, L"ERROR_DS_DRA_DN_EXISTS"}, + {8442, L"ERROR_DS_DRA_INTERNAL_ERROR"}, + {8443, L"ERROR_DS_DRA_INCONSISTENT_DIT"}, + {8444, L"ERROR_DS_DRA_CONNECTION_FAILED"}, + {8445, L"ERROR_DS_DRA_BAD_INSTANCE_TYPE"}, + {8446, L"ERROR_DS_DRA_OUT_OF_MEM"}, + {8447, L"ERROR_DS_DRA_MAIL_PROBLEM"}, + {8448, L"ERROR_DS_DRA_REF_ALREADY_EXISTS"}, + {8449, L"ERROR_DS_DRA_REF_NOT_FOUND"}, + {8450, L"ERROR_DS_DRA_OBJ_IS_REP_SOURCE"}, + {8451, L"ERROR_DS_DRA_DB_ERROR"}, + {8452, L"ERROR_DS_DRA_NO_REPLICA"}, + {8453, L"ERROR_DS_DRA_ACCESS_DENIED"}, + {8454, L"ERROR_DS_DRA_NOT_SUPPORTED"}, + {8455, L"ERROR_DS_DRA_RPC_CANCELLED"}, + {8456, L"ERROR_DS_DRA_SOURCE_DISABLED"}, + {8457, L"ERROR_DS_DRA_SINK_DISABLED"}, + {8458, L"ERROR_DS_DRA_NAME_COLLISION"}, + {8459, L"ERROR_DS_DRA_SOURCE_REINSTALLED"}, + {8460, L"ERROR_DS_DRA_MISSING_PARENT"}, + {8461, L"ERROR_DS_DRA_PREEMPTED"}, + {8462, L"ERROR_DS_DRA_ABANDON_SYNC"}, + {8463, L"ERROR_DS_DRA_SHUTDOWN"}, + {8464, L"ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET"}, + {8465, L"ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA"}, + {8466, L"ERROR_DS_DRA_EXTN_CONNECTION_FAILED"}, + {8467, L"ERROR_DS_INSTALL_SCHEMA_MISMATCH"}, + {8468, L"ERROR_DS_DUP_LINK_ID"}, + {8469, L"ERROR_DS_NAME_ERROR_RESOLVING"}, + {8470, L"ERROR_DS_NAME_ERROR_NOT_FOUND"}, + {8471, L"ERROR_DS_NAME_ERROR_NOT_UNIQUE"}, + {8472, L"ERROR_DS_NAME_ERROR_NO_MAPPING"}, + {8473, L"ERROR_DS_NAME_ERROR_DOMAIN_ONLY"}, + {8474, L"ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING"}, + {8475, L"ERROR_DS_CONSTRUCTED_ATT_MOD"}, + {8476, L"ERROR_DS_WRONG_OM_OBJ_CLASS"}, + {8477, L"ERROR_DS_DRA_REPL_PENDING"}, + {8478, L"ERROR_DS_DS_REQUIRED"}, + {8479, L"ERROR_DS_INVALID_LDAP_DISPLAY_NAME"}, + {8480, L"ERROR_DS_NON_BASE_SEARCH"}, + {8481, L"ERROR_DS_CANT_RETRIEVE_ATTS"}, + {8482, L"ERROR_DS_BACKLINK_WITHOUT_LINK"}, + {8483, L"ERROR_DS_EPOCH_MISMATCH"}, + {8484, L"ERROR_DS_SRC_NAME_MISMATCH"}, + {8485, L"ERROR_DS_SRC_AND_DST_NC_IDENTICAL"}, + {8486, L"ERROR_DS_DST_NC_MISMATCH"}, + {8487, L"ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC"}, + {8488, L"ERROR_DS_SRC_GUID_MISMATCH"}, + {8489, L"ERROR_DS_CANT_MOVE_DELETED_OBJECT"}, + {8490, L"ERROR_DS_PDC_OPERATION_IN_PROGRESS"}, + {8491, L"ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD"}, + {8492, L"ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION"}, + {8493, L"ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS"}, + {8494, L"ERROR_DS_NC_MUST_HAVE_NC_PARENT"}, + {8495, L"ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE"}, + {8496, L"ERROR_DS_DST_DOMAIN_NOT_NATIVE"}, + {8497, L"ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER"}, + {8498, L"ERROR_DS_CANT_MOVE_ACCOUNT_GROUP"}, + {8499, L"ERROR_DS_CANT_MOVE_RESOURCE_GROUP"}, + {8500, L"ERROR_DS_INVALID_SEARCH_FLAG"}, + {8501, L"ERROR_DS_NO_TREE_DELETE_ABOVE_NC"}, + {8502, L"ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE"}, + {8503, L"ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE"}, + {8504, L"ERROR_DS_SAM_INIT_FAILURE"}, + {8505, L"ERROR_DS_SENSITIVE_GROUP_VIOLATION"}, + {8506, L"ERROR_DS_CANT_MOD_PRIMARYGROUPID"}, + {8507, L"ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD"}, + {8508, L"ERROR_DS_NONSAFE_SCHEMA_CHANGE"}, + {8509, L"ERROR_DS_SCHEMA_UPDATE_DISALLOWED"}, + {8510, L"ERROR_DS_CANT_CREATE_UNDER_SCHEMA"}, + {8511, L"ERROR_DS_INSTALL_NO_SRC_SCH_VERSION"}, + {8512, L"ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE"}, + {8513, L"ERROR_DS_INVALID_GROUP_TYPE"}, + {8514, L"ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN"}, + {8515, L"ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN"}, + {8516, L"ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER"}, + {8517, L"ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER"}, + {8518, L"ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER"}, + {8519, L"ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER"}, + {8520, L"ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER"}, + {8521, L"ERROR_DS_HAVE_PRIMARY_MEMBERS"}, + {8522, L"ERROR_DS_STRING_SD_CONVERSION_FAILED"}, + {8523, L"ERROR_DS_NAMING_MASTER_GC"}, + {8524, L"ERROR_DS_DNS_LOOKUP_FAILURE"}, + {8525, L"ERROR_DS_COULDNT_UPDATE_SPNS"}, + {8526, L"ERROR_DS_CANT_RETRIEVE_SD"}, + {8527, L"ERROR_DS_KEY_NOT_UNIQUE"}, + {8528, L"ERROR_DS_WRONG_LINKED_ATT_SYNTAX"}, + {8529, L"ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD"}, + {8530, L"ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY"}, + {8531, L"ERROR_DS_CANT_START"}, + {8532, L"ERROR_DS_INIT_FAILURE"}, + {8533, L"ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION"}, + {8534, L"ERROR_DS_SOURCE_DOMAIN_IN_FOREST"}, + {8535, L"ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST"}, + {8536, L"ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED"}, + {8537, L"ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN"}, + {8538, L"ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER"}, + {8539, L"ERROR_DS_SRC_SID_EXISTS_IN_FOREST"}, + {8540, L"ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH"}, + {8541, L"ERROR_SAM_INIT_FAILURE"}, + {8542, L"ERROR_DS_DRA_SCHEMA_INFO_SHIP"}, + {8543, L"ERROR_DS_DRA_SCHEMA_CONFLICT"}, + {8544, L"ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT"}, + {8545, L"ERROR_DS_DRA_OBJ_NC_MISMATCH"}, + {8546, L"ERROR_DS_NC_STILL_HAS_DSAS"}, + {8547, L"ERROR_DS_GC_REQUIRED"}, + {8548, L"ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY"}, + {8549, L"ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS"}, + {8550, L"ERROR_DS_CANT_ADD_TO_GC"}, + {8551, L"ERROR_DS_NO_CHECKPOINT_WITH_PDC"}, + {8552, L"ERROR_DS_SOURCE_AUDITING_NOT_ENABLED"}, + {8553, L"ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC"}, + {8554, L"ERROR_DS_INVALID_NAME_FOR_SPN"}, + {8555, L"ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS"}, + {8556, L"ERROR_DS_UNICODEPWD_NOT_IN_QUOTES"}, + {8557, L"ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED"}, + {8558, L"ERROR_DS_MUST_BE_RUN_ON_DST_DC"}, + {8559, L"ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER"}, + {8560, L"ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ"}, + {8561, L"ERROR_DS_INIT_FAILURE_CONSOLE"}, + {8562, L"ERROR_DS_SAM_INIT_FAILURE_CONSOLE"}, + {8563, L"ERROR_DS_FOREST_VERSION_TOO_HIGH"}, + {8564, L"ERROR_DS_DOMAIN_VERSION_TOO_HIGH"}, + {8565, L"ERROR_DS_FOREST_VERSION_TOO_LOW"}, + {8566, L"ERROR_DS_DOMAIN_VERSION_TOO_LOW"}, + {8567, L"ERROR_DS_INCOMPATIBLE_VERSION"}, + {8568, L"ERROR_DS_LOW_DSA_VERSION"}, + {8569, L"ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN"}, + {8570, L"ERROR_DS_NOT_SUPPORTED_SORT_ORDER"}, + {8571, L"ERROR_DS_NAME_NOT_UNIQUE"}, + {8572, L"ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4"}, + {8573, L"ERROR_DS_OUT_OF_VERSION_STORE"}, + {8574, L"ERROR_DS_INCOMPATIBLE_CONTROLS_USED"}, + {8575, L"ERROR_DS_NO_REF_DOMAIN"}, + {8576, L"ERROR_DS_RESERVED_LINK_ID"}, + {8577, L"ERROR_DS_LINK_ID_NOT_AVAILABLE"}, + {8578, L"ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER"}, + {8579, L"ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE"}, + {8580, L"ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC"}, + {8581, L"ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG"}, + {8582, L"ERROR_DS_MODIFYDN_WRONG_GRANDPARENT"}, + {8583, L"ERROR_DS_NAME_ERROR_TRUST_REFERRAL"}, + {8584, L"ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER"}, + {8585, L"ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD"}, + {8586, L"ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2"}, + {8587, L"ERROR_DS_THREAD_LIMIT_EXCEEDED"}, + {8588, L"ERROR_DS_NOT_CLOSEST"}, + {8589, L"ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF"}, + {8590, L"ERROR_DS_SINGLE_USER_MODE_FAILED"}, + {8591, L"ERROR_DS_NTDSCRIPT_SYNTAX_ERROR"}, + {8592, L"ERROR_DS_NTDSCRIPT_PROCESS_ERROR"}, + {8593, L"ERROR_DS_DIFFERENT_REPL_EPOCHS"}, + {8594, L"ERROR_DS_DRS_EXTENSIONS_CHANGED"}, + {8595, L"ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR"}, + {8596, L"ERROR_DS_NO_MSDS_INTID"}, + {8597, L"ERROR_DS_DUP_MSDS_INTID"}, + {8598, L"ERROR_DS_EXISTS_IN_RDNATTID"}, + {8599, L"ERROR_DS_AUTHORIZATION_FAILED"}, + {8600, L"ERROR_DS_INVALID_SCRIPT"}, + {8601, L"ERROR_DS_REMOTE_CROSSREF_OP_FAILED"}, + {8602, L"ERROR_DS_CROSS_REF_BUSY"}, + {8603, L"ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN"}, + {8604, L"ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC"}, + {8605, L"ERROR_DS_DUPLICATE_ID_FOUND"}, + {8606, L"ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT"}, + {8607, L"ERROR_DS_GROUP_CONVERSION_ERROR"}, + {8608, L"ERROR_DS_CANT_MOVE_APP_BASIC_GROUP"}, + {8609, L"ERROR_DS_CANT_MOVE_APP_QUERY_GROUP"}, + {8610, L"ERROR_DS_ROLE_NOT_VERIFIED"}, + {8611, L"ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL"}, + {8612, L"ERROR_DS_DOMAIN_RENAME_IN_PROGRESS"}, + {8613, L"ERROR_DS_EXISTING_AD_CHILD_NC"}, + {8614, L"ERROR_DS_REPL_LIFETIME_EXCEEDED"}, + {8615, L"ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER"}, + {8616, L"ERROR_DS_LDAP_SEND_QUEUE_FULL"}, + {8617, L"ERROR_DS_DRA_OUT_SCHEDULE_WINDOW"}, + {8618, L"ERROR_DS_POLICY_NOT_KNOWN"}, + {8619, L"ERROR_NO_SITE_SETTINGS_OBJECT"}, + {8620, L"ERROR_NO_SECRETS"}, + {8621, L"ERROR_NO_WRITABLE_DC_FOUND"}, + {8622, L"ERROR_DS_NO_SERVER_OBJECT"}, + {8623, L"ERROR_DS_NO_NTDSA_OBJECT"}, + {8624, L"ERROR_DS_NON_ASQ_SEARCH"}, + {8625, L"ERROR_DS_AUDIT_FAILURE"}, + {8626, L"ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE"}, + {8627, L"ERROR_DS_INVALID_SEARCH_FLAG_TUPLE"}, + {8628, L"ERROR_DS_HIERARCHY_TABLE_TOO_DEEP"}, + {8629, L"ERROR_DS_DRA_CORRUPT_UTD_VECTOR"}, + {8630, L"ERROR_DS_DRA_SECRETS_DENIED"}, + {8631, L"ERROR_DS_RESERVED_MAPI_ID"}, + {8632, L"ERROR_DS_MAPI_ID_NOT_AVAILABLE"}, + {8633, L"ERROR_DS_DRA_MISSING_KRBTGT_SECRET"}, + {8634, L"ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST"}, + {8635, L"ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST"}, + {8636, L"ERROR_INVALID_USER_PRINCIPAL_NAME"}, + {8637, L"ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS"}, + {8638, L"ERROR_DS_OID_NOT_FOUND"}, + {8639, L"ERROR_DS_DRA_RECYCLED_TARGET"}, + {8640, L"ERROR_DS_DISALLOWED_NC_REDIRECT"}, + {8641, L"ERROR_DS_HIGH_ADLDS_FFL"}, + {8642, L"ERROR_DS_HIGH_DSA_VERSION"}, + {8643, L"ERROR_DS_LOW_ADLDS_FFL"}, + {8644, L"ERROR_DOMAIN_SID_SAME_AS_LOCAL_WORKSTATION"}, + {8645, L"ERROR_DS_UNDELETE_SAM_VALIDATION_FAILED"}, + {8646, L"ERROR_INCORRECT_ACCOUNT_TYPE"}, + {9001, L"DNS_ERROR_RCODE_FORMAT_ERROR"}, + {9002, L"DNS_ERROR_RCODE_SERVER_FAILURE"}, + {9003, L"DNS_ERROR_RCODE_NAME_ERROR"}, + {9004, L"DNS_ERROR_RCODE_NOT_IMPLEMENTED"}, + {9005, L"DNS_ERROR_RCODE_REFUSED"}, + {9006, L"DNS_ERROR_RCODE_YXDOMAIN"}, + {9007, L"DNS_ERROR_RCODE_YXRRSET"}, + {9008, L"DNS_ERROR_RCODE_NXRRSET"}, + {9009, L"DNS_ERROR_RCODE_NOTAUTH"}, + {9010, L"DNS_ERROR_RCODE_NOTZONE"}, + {9016, L"DNS_ERROR_RCODE_BADSIG"}, + {9017, L"DNS_ERROR_RCODE_BADKEY"}, + {9018, L"DNS_ERROR_RCODE_BADTIME"}, + {9101, L"DNS_ERROR_KEYMASTER_REQUIRED"}, + {9102, L"DNS_ERROR_NOT_ALLOWED_ON_SIGNED_ZONE"}, + {9103, L"DNS_ERROR_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1"}, + {9104, L"DNS_ERROR_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS"}, + {9105, L"DNS_ERROR_UNSUPPORTED_ALGORITHM"}, + {9106, L"DNS_ERROR_INVALID_KEY_SIZE"}, + {9107, L"DNS_ERROR_SIGNING_KEY_NOT_ACCESSIBLE"}, + {9108, L"DNS_ERROR_KSP_DOES_NOT_SUPPORT_PROTECTION"}, + {9109, L"DNS_ERROR_UNEXPECTED_DATA_PROTECTION_ERROR"}, + {9110, L"DNS_ERROR_UNEXPECTED_CNG_ERROR"}, + {9111, L"DNS_ERROR_UNKNOWN_SIGNING_PARAMETER_VERSION"}, + {9112, L"DNS_ERROR_KSP_NOT_ACCESSIBLE"}, + {9113, L"DNS_ERROR_TOO_MANY_SKDS"}, + {9114, L"DNS_ERROR_INVALID_ROLLOVER_PERIOD"}, + {9115, L"DNS_ERROR_INVALID_INITIAL_ROLLOVER_OFFSET"}, + {9116, L"DNS_ERROR_ROLLOVER_IN_PROGRESS"}, + {9117, L"DNS_ERROR_STANDBY_KEY_NOT_PRESENT"}, + {9118, L"DNS_ERROR_NOT_ALLOWED_ON_ZSK"}, + {9119, L"DNS_ERROR_NOT_ALLOWED_ON_ACTIVE_SKD"}, + {9120, L"DNS_ERROR_ROLLOVER_ALREADY_QUEUED"}, + {9121, L"DNS_ERROR_NOT_ALLOWED_ON_UNSIGNED_ZONE"}, + {9122, L"DNS_ERROR_BAD_KEYMASTER"}, + {9123, L"DNS_ERROR_INVALID_SIGNATURE_VALIDITY_PERIOD"}, + {9124, L"DNS_ERROR_INVALID_NSEC3_ITERATION_COUNT"}, + {9125, L"DNS_ERROR_DNSSEC_IS_DISABLED"}, + {9126, L"DNS_ERROR_INVALID_XML"}, + {9127, L"DNS_ERROR_NO_VALID_TRUST_ANCHORS"}, + {9128, L"DNS_ERROR_ROLLOVER_NOT_POKEABLE"}, + {9129, L"DNS_ERROR_NSEC3_NAME_COLLISION"}, + {9130, L"DNS_ERROR_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1"}, + {9501, L"DNS_INFO_NO_RECORDS"}, + {9502, L"DNS_ERROR_BAD_PACKET"}, + {9503, L"DNS_ERROR_NO_PACKET"}, + {9504, L"DNS_ERROR_RCODE"}, + {9505, L"DNS_ERROR_UNSECURE_PACKET"}, + {9506, L"DNS_REQUEST_PENDING"}, + {9551, L"DNS_ERROR_INVALID_TYPE"}, + {9552, L"DNS_ERROR_INVALID_IP_ADDRESS"}, + {9553, L"DNS_ERROR_INVALID_PROPERTY"}, + {9554, L"DNS_ERROR_TRY_AGAIN_LATER"}, + {9555, L"DNS_ERROR_NOT_UNIQUE"}, + {9556, L"DNS_ERROR_NON_RFC_NAME"}, + {9557, L"DNS_STATUS_FQDN"}, + {9558, L"DNS_STATUS_DOTTED_NAME"}, + {9559, L"DNS_STATUS_SINGLE_PART_NAME"}, + {9560, L"DNS_ERROR_INVALID_NAME_CHAR"}, + {9561, L"DNS_ERROR_NUMERIC_NAME"}, + {9562, L"DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER"}, + {9563, L"DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION"}, + {9564, L"DNS_ERROR_CANNOT_FIND_ROOT_HINTS"}, + {9565, L"DNS_ERROR_INCONSISTENT_ROOT_HINTS"}, + {9566, L"DNS_ERROR_DWORD_VALUE_TOO_SMALL"}, + {9567, L"DNS_ERROR_DWORD_VALUE_TOO_LARGE"}, + {9568, L"DNS_ERROR_BACKGROUND_LOADING"}, + {9569, L"DNS_ERROR_NOT_ALLOWED_ON_RODC"}, + {9570, L"DNS_ERROR_NOT_ALLOWED_UNDER_DNAME"}, + {9571, L"DNS_ERROR_DELEGATION_REQUIRED"}, + {9572, L"DNS_ERROR_INVALID_POLICY_TABLE"}, + {9601, L"DNS_ERROR_ZONE_DOES_NOT_EXIST"}, + {9602, L"DNS_ERROR_NO_ZONE_INFO"}, + {9603, L"DNS_ERROR_INVALID_ZONE_OPERATION"}, + {9604, L"DNS_ERROR_ZONE_CONFIGURATION_ERROR"}, + {9605, L"DNS_ERROR_ZONE_HAS_NO_SOA_RECORD"}, + {9606, L"DNS_ERROR_ZONE_HAS_NO_NS_RECORDS"}, + {9607, L"DNS_ERROR_ZONE_LOCKED"}, + {9608, L"DNS_ERROR_ZONE_CREATION_FAILED"}, + {9609, L"DNS_ERROR_ZONE_ALREADY_EXISTS"}, + {9610, L"DNS_ERROR_AUTOZONE_ALREADY_EXISTS"}, + {9611, L"DNS_ERROR_INVALID_ZONE_TYPE"}, + {9612, L"DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP"}, + {9613, L"DNS_ERROR_ZONE_NOT_SECONDARY"}, + {9614, L"DNS_ERROR_NEED_SECONDARY_ADDRESSES"}, + {9615, L"DNS_ERROR_WINS_INIT_FAILED"}, + {9616, L"DNS_ERROR_NEED_WINS_SERVERS"}, + {9617, L"DNS_ERROR_NBSTAT_INIT_FAILED"}, + {9618, L"DNS_ERROR_SOA_DELETE_INVALID"}, + {9619, L"DNS_ERROR_FORWARDER_ALREADY_EXISTS"}, + {9620, L"DNS_ERROR_ZONE_REQUIRES_MASTER_IP"}, + {9621, L"DNS_ERROR_ZONE_IS_SHUTDOWN"}, + {9622, L"DNS_ERROR_ZONE_LOCKED_FOR_SIGNING"}, + {9651, L"DNS_ERROR_PRIMARY_REQUIRES_DATAFILE"}, + {9652, L"DNS_ERROR_INVALID_DATAFILE_NAME"}, + {9653, L"DNS_ERROR_DATAFILE_OPEN_FAILURE"}, + {9654, L"DNS_ERROR_FILE_WRITEBACK_FAILED"}, + {9655, L"DNS_ERROR_DATAFILE_PARSING"}, + {9701, L"DNS_ERROR_RECORD_DOES_NOT_EXIST"}, + {9702, L"DNS_ERROR_RECORD_FORMAT"}, + {9703, L"DNS_ERROR_NODE_CREATION_FAILED"}, + {9704, L"DNS_ERROR_UNKNOWN_RECORD_TYPE"}, + {9705, L"DNS_ERROR_RECORD_TIMED_OUT"}, + {9706, L"DNS_ERROR_NAME_NOT_IN_ZONE"}, + {9707, L"DNS_ERROR_CNAME_LOOP"}, + {9708, L"DNS_ERROR_NODE_IS_CNAME"}, + {9709, L"DNS_ERROR_CNAME_COLLISION"}, + {9710, L"DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT"}, + {9711, L"DNS_ERROR_RECORD_ALREADY_EXISTS"}, + {9712, L"DNS_ERROR_SECONDARY_DATA"}, + {9713, L"DNS_ERROR_NO_CREATE_CACHE_DATA"}, + {9714, L"DNS_ERROR_NAME_DOES_NOT_EXIST"}, + {9715, L"DNS_WARNING_PTR_CREATE_FAILED"}, + {9716, L"DNS_WARNING_DOMAIN_UNDELETED"}, + {9717, L"DNS_ERROR_DS_UNAVAILABLE"}, + {9718, L"DNS_ERROR_DS_ZONE_ALREADY_EXISTS"}, + {9719, L"DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE"}, + {9720, L"DNS_ERROR_NODE_IS_DNAME"}, + {9721, L"DNS_ERROR_DNAME_COLLISION"}, + {9722, L"DNS_ERROR_ALIAS_LOOP"}, + {9751, L"DNS_INFO_AXFR_COMPLETE"}, + {9752, L"DNS_ERROR_AXFR"}, + {9753, L"DNS_INFO_ADDED_LOCAL_WINS"}, + {9801, L"DNS_STATUS_CONTINUE_NEEDED"}, + {9851, L"DNS_ERROR_NO_TCPIP"}, + {9852, L"DNS_ERROR_NO_DNS_SERVERS"}, + {9901, L"DNS_ERROR_DP_DOES_NOT_EXIST"}, + {9902, L"DNS_ERROR_DP_ALREADY_EXISTS"}, + {9903, L"DNS_ERROR_DP_NOT_ENLISTED"}, + {9904, L"DNS_ERROR_DP_ALREADY_ENLISTED"}, + {9905, L"DNS_ERROR_DP_NOT_AVAILABLE"}, + {9906, L"DNS_ERROR_DP_FSMO_ERROR"}, + {10004, L"WSAEINTR"}, + {10009, L"WSAEBADF"}, + {10013, L"WSAEACCES"}, + {10014, L"WSAEFAULT"}, + {10022, L"WSAEINVAL"}, + {10024, L"WSAEMFILE"}, + {10035, L"WSAEWOULDBLOCK"}, + {10036, L"WSAEINPROGRESS"}, + {10037, L"WSAEALREADY"}, + {10038, L"WSAENOTSOCK"}, + {10039, L"WSAEDESTADDRREQ"}, + {10040, L"WSAEMSGSIZE"}, + {10041, L"WSAEPROTOTYPE"}, + {10042, L"WSAENOPROTOOPT"}, + {10043, L"WSAEPROTONOSUPPORT"}, + {10044, L"WSAESOCKTNOSUPPORT"}, + {10045, L"WSAEOPNOTSUPP"}, + {10046, L"WSAEPFNOSUPPORT"}, + {10047, L"WSAEAFNOSUPPORT"}, + {10048, L"WSAEADDRINUSE"}, + {10049, L"WSAEADDRNOTAVAIL"}, + {10050, L"WSAENETDOWN"}, + {10051, L"WSAENETUNREACH"}, + {10052, L"WSAENETRESET"}, + {10053, L"WSAECONNABORTED"}, + {10054, L"WSAECONNRESET"}, + {10055, L"WSAENOBUFS"}, + {10056, L"WSAEISCONN"}, + {10057, L"WSAENOTCONN"}, + {10058, L"WSAESHUTDOWN"}, + {10059, L"WSAETOOMANYREFS"}, + {10060, L"WSAETIMEDOUT"}, + {10061, L"WSAECONNREFUSED"}, + {10062, L"WSAELOOP"}, + {10063, L"WSAENAMETOOLONG"}, + {10064, L"WSAEHOSTDOWN"}, + {10065, L"WSAEHOSTUNREACH"}, + {10066, L"WSAENOTEMPTY"}, + {10067, L"WSAEPROCLIM"}, + {10068, L"WSAEUSERS"}, + {10069, L"WSAEDQUOT"}, + {10070, L"WSAESTALE"}, + {10071, L"WSAEREMOTE"}, + {10091, L"WSASYSNOTREADY"}, + {10092, L"WSAVERNOTSUPPORTED"}, + {10093, L"WSANOTINITIALISED"}, + {10101, L"WSAEDISCON"}, + {10102, L"WSAENOMORE"}, + {10103, L"WSAECANCELLED"}, + {10104, L"WSAEINVALIDPROCTABLE"}, + {10105, L"WSAEINVALIDPROVIDER"}, + {10106, L"WSAEPROVIDERFAILEDINIT"}, + {10107, L"WSASYSCALLFAILURE"}, + {10108, L"WSASERVICE_NOT_FOUND"}, + {10109, L"WSATYPE_NOT_FOUND"}, + {10110, L"WSA_E_NO_MORE"}, + {10111, L"WSA_E_CANCELLED"}, + {10112, L"WSAEREFUSED"}, + {11001, L"WSAHOST_NOT_FOUND"}, + {11002, L"WSATRY_AGAIN"}, + {11003, L"WSANO_RECOVERY"}, + {11004, L"WSANO_DATA"}, + {11005, L"WSA_QOS_RECEIVERS"}, + {11006, L"WSA_QOS_SENDERS"}, + {11007, L"WSA_QOS_NO_SENDERS"}, + {11008, L"WSA_QOS_NO_RECEIVERS"}, + {11009, L"WSA_QOS_REQUEST_CONFIRMED"}, + {11010, L"WSA_QOS_ADMISSION_FAILURE"}, + {11011, L"WSA_QOS_POLICY_FAILURE"}, + {11012, L"WSA_QOS_BAD_STYLE"}, + {11013, L"WSA_QOS_BAD_OBJECT"}, + {11014, L"WSA_QOS_TRAFFIC_CTRL_ERROR"}, + {11015, L"WSA_QOS_GENERIC_ERROR"}, + {11016, L"WSA_QOS_ESERVICETYPE"}, + {11017, L"WSA_QOS_EFLOWSPEC"}, + {11018, L"WSA_QOS_EPROVSPECBUF"}, + {11019, L"WSA_QOS_EFILTERSTYLE"}, + {11020, L"WSA_QOS_EFILTERTYPE"}, + {11021, L"WSA_QOS_EFILTERCOUNT"}, + {11022, L"WSA_QOS_EOBJLENGTH"}, + {11023, L"WSA_QOS_EFLOWCOUNT"}, + {11024, L"WSA_QOS_EUNKOWNPSOBJ"}, + {11025, L"WSA_QOS_EPOLICYOBJ"}, + {11026, L"WSA_QOS_EFLOWDESC"}, + {11027, L"WSA_QOS_EPSFLOWSPEC"}, + {11028, L"WSA_QOS_EPSFILTERSPEC"}, + {11029, L"WSA_QOS_ESDMODEOBJ"}, + {11030, L"WSA_QOS_ESHAPERATEOBJ"}, + {11031, L"WSA_QOS_RESERVED_PETYPE"}, + {11032, L"WSA_SECURE_HOST_NOT_FOUND"}, + {11033, L"WSA_IPSEC_NAME_POLICY_ERROR"}}; const wchar_t* errorCodeName(DWORD code) { static const wchar_t* NotFound = L"unknown error"; - auto itor = std::lower_bound( - std::begin(g_codes), std::end(g_codes), CodeName{code}, - [](auto&& a, auto&& b) { - return (a.code < b.code); - }); + auto itor = std::lower_bound(std::begin(g_codes), std::end(g_codes), CodeName{code}, + [](auto&& a, auto&& b) { + return (a.code < b.code); + }); if (itor != std::end(g_codes)) { return itor->name; @@ -2359,4 +2357,4 @@ const wchar_t* errorCodeName(DWORD code) return NotFound; } -} // namespace +} // namespace MOBase diff --git a/src/errorcodes.h b/src/errorcodes.h index 735c36c8..b6175a20 100644 --- a/src/errorcodes.h +++ b/src/errorcodes.h @@ -9,6 +9,6 @@ namespace MOBase QDLLEXPORT const wchar_t* errorCodeName(DWORD code); -} // namespace +} // namespace MOBase #endif UIBASE_ERRORCODES_H diff --git a/src/eventfilter.cpp b/src/eventfilter.cpp index a901a5b9..f154e759 100644 --- a/src/eventfilter.cpp +++ b/src/eventfilter.cpp @@ -17,21 +17,18 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ - #include "eventfilter.h" -namespace MOBase { - -EventFilter::EventFilter(QObject *parent, - const EventFilter::HandlerFunc &handler) - : QObject(parent) - , m_Handler(handler) +namespace MOBase { -} -bool EventFilter::eventFilter(QObject *obj, QEvent *event) +EventFilter::EventFilter(QObject* parent, const EventFilter::HandlerFunc& handler) + : QObject(parent), m_Handler(handler) +{} + +bool EventFilter::eventFilter(QObject* obj, QEvent* event) { return m_Handler(obj, event); } -} // namespace +} // namespace MOBase diff --git a/src/eventfilter.h b/src/eventfilter.h index f3e3ed29..3878a507 100644 --- a/src/eventfilter.h +++ b/src/eventfilter.h @@ -23,24 +23,23 @@ along with Mod Organizer. If not, see . #include #include -namespace MOBase { +namespace MOBase +{ -class QDLLEXPORT EventFilter : public QObject { +class QDLLEXPORT EventFilter : public QObject +{ Q_OBJECT - typedef std::function HandlerFunc; + typedef std::function HandlerFunc; public: + EventFilter(QObject* parent, const HandlerFunc& handler); - EventFilter(QObject *parent, const HandlerFunc &handler); - - virtual bool eventFilter(QObject *obj , QEvent *event) override; + virtual bool eventFilter(QObject* obj, QEvent* event) override; private: - HandlerFunc m_Handler; - }; -} // namespace +} // namespace MOBase diff --git a/src/exceptions.h b/src/exceptions.h index 1526de47..433b9be7 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -7,22 +7,21 @@ #include "dllimport.h" -namespace MOBase { +namespace MOBase +{ #pragma warning(push) -#pragma warning(disable: 4275) // non-dll interface +#pragma warning(disable : 4275) // non-dll interface /** - * @brief exception class that takes a QString as the parameter - **/ -class QDLLEXPORT Exception : public std::exception { + * @brief exception class that takes a QString as the parameter + **/ +class QDLLEXPORT Exception : public std::exception +{ public: + Exception(const QString& text) : m_Message(text.toUtf8()) {} - Exception(const QString& text) : m_Message(text.toUtf8()) { } - - virtual const char* what() const noexcept override { - return m_Message.constData(); - } + virtual const char* what() const noexcept override { return m_Message.constData(); } private: QByteArray m_Message; @@ -30,23 +29,25 @@ class QDLLEXPORT Exception : public std::exception { #pragma warning(pop) - // Exception thrown in case of incompatibilities, i.e. between plugins. -class QDLLEXPORT IncompatibilityException : public Exception { +class QDLLEXPORT IncompatibilityException : public Exception +{ public: using Exception::Exception; }; // Exception thrown for invalid NXM links. -class QDLLEXPORT InvalidNXMLinkException : public Exception { +class QDLLEXPORT InvalidNXMLinkException : public Exception +{ public: - InvalidNXMLinkException(const QString& link) : - Exception(QObject::tr("invalid nxm-link: %1").arg(link)) { } + InvalidNXMLinkException(const QString& link) + : Exception(QObject::tr("invalid nxm-link: %1").arg(link)) + {} }; // alias for backward-compatibility, should be removed when possible using MyException = Exception; -} +} // namespace MOBase -#endif \ No newline at end of file +#endif diff --git a/src/executableinfo.cpp b/src/executableinfo.cpp index 5726a8bf..c31ff070 100644 --- a/src/executableinfo.cpp +++ b/src/executableinfo.cpp @@ -1,112 +1,105 @@ -#include "executableinfo.h" - -using namespace MOBase; - -ExecutableForcedLoadSetting::ExecutableForcedLoadSetting( - const QString &process, - const QString &library) - : m_Enabled(false) - , m_Process(process) - , m_Library(library) - , m_Forced(false) -{ -} - -ExecutableForcedLoadSetting &ExecutableForcedLoadSetting::withEnabled(bool enabled) -{ - m_Enabled = enabled; - return *this; -} - -ExecutableForcedLoadSetting &ExecutableForcedLoadSetting::withForced(bool forced) -{ - m_Forced = forced; - return *this; -} - -bool ExecutableForcedLoadSetting::enabled() const -{ - return m_Enabled; -} - -bool ExecutableForcedLoadSetting::forced() const -{ - return m_Forced; -} - -QString ExecutableForcedLoadSetting::library() const -{ - return m_Library; -} - -QString ExecutableForcedLoadSetting::process() const -{ - return m_Process; -} - -MOBase::ExecutableInfo::ExecutableInfo(const QString &title, const QFileInfo &binary) - : m_Title(title) - , m_Binary(binary) - , m_WorkingDirectory(binary.exists() ? binary.absoluteDir() : QString()) - , m_SteamAppID() -{ -} - -ExecutableInfo &ExecutableInfo::withArgument(const QString &argument) -{ - m_Arguments.append(argument); - return *this; -} - -ExecutableInfo &ExecutableInfo::withWorkingDirectory(const QDir &workingDirectory) -{ - m_WorkingDirectory = workingDirectory; - return *this; -} - -ExecutableInfo &MOBase::ExecutableInfo::withSteamAppId(const QString &appId) -{ - m_SteamAppID = appId; - return *this; -} - -ExecutableInfo &ExecutableInfo::asCustom() -{ - m_Custom = true; - return *this; -} - -bool ExecutableInfo::isValid() const -{ - return m_Binary.exists(); -} - -QString ExecutableInfo::title() const -{ - return m_Title; -} - -QFileInfo ExecutableInfo::binary() const -{ - return m_Binary; -} - -QStringList ExecutableInfo::arguments() const -{ - return m_Arguments; -} - -QDir ExecutableInfo::workingDirectory() const -{ - return m_WorkingDirectory; -} - -QString ExecutableInfo::steamAppID() const -{ - return m_SteamAppID; -} - -bool ExecutableInfo::isCustom() const -{ - return m_Custom; -} +#include "executableinfo.h" + +using namespace MOBase; + +ExecutableForcedLoadSetting::ExecutableForcedLoadSetting(const QString& process, + const QString& library) + : m_Enabled(false), m_Process(process), m_Library(library), m_Forced(false) +{} + +ExecutableForcedLoadSetting& ExecutableForcedLoadSetting::withEnabled(bool enabled) +{ + m_Enabled = enabled; + return *this; +} + +ExecutableForcedLoadSetting& ExecutableForcedLoadSetting::withForced(bool forced) +{ + m_Forced = forced; + return *this; +} + +bool ExecutableForcedLoadSetting::enabled() const +{ + return m_Enabled; +} + +bool ExecutableForcedLoadSetting::forced() const +{ + return m_Forced; +} + +QString ExecutableForcedLoadSetting::library() const +{ + return m_Library; +} + +QString ExecutableForcedLoadSetting::process() const +{ + return m_Process; +} + +MOBase::ExecutableInfo::ExecutableInfo(const QString& title, const QFileInfo& binary) + : m_Title(title), m_Binary(binary), + m_WorkingDirectory(binary.exists() ? binary.absoluteDir() : QString()), + m_SteamAppID() +{} + +ExecutableInfo& ExecutableInfo::withArgument(const QString& argument) +{ + m_Arguments.append(argument); + return *this; +} + +ExecutableInfo& ExecutableInfo::withWorkingDirectory(const QDir& workingDirectory) +{ + m_WorkingDirectory = workingDirectory; + return *this; +} + +ExecutableInfo& MOBase::ExecutableInfo::withSteamAppId(const QString& appId) +{ + m_SteamAppID = appId; + return *this; +} + +ExecutableInfo& ExecutableInfo::asCustom() +{ + m_Custom = true; + return *this; +} + +bool ExecutableInfo::isValid() const +{ + return m_Binary.exists(); +} + +QString ExecutableInfo::title() const +{ + return m_Title; +} + +QFileInfo ExecutableInfo::binary() const +{ + return m_Binary; +} + +QStringList ExecutableInfo::arguments() const +{ + return m_Arguments; +} + +QDir ExecutableInfo::workingDirectory() const +{ + return m_WorkingDirectory; +} + +QString ExecutableInfo::steamAppID() const +{ + return m_SteamAppID; +} + +bool ExecutableInfo::isCustom() const +{ + return m_Custom; +} diff --git a/src/executableinfo.h b/src/executableinfo.h index 44389862..1fe52b39 100644 --- a/src/executableinfo.h +++ b/src/executableinfo.h @@ -1,71 +1,67 @@ -#ifndef EXECUTABLEINFO_H -#define EXECUTABLEINFO_H - - -#include "dllimport.h" -#include -#include -#include -#include - - -namespace MOBase { - -class QDLLEXPORT ExecutableForcedLoadSetting -{ -public: - ExecutableForcedLoadSetting(const QString &process, const QString &library); - - ExecutableForcedLoadSetting &withForced(bool forced=true); - - ExecutableForcedLoadSetting &withEnabled(bool enabled=true); - - bool enabled() const; - bool forced() const; - QString library() const; - QString process() const; - -private: - bool m_Enabled; - QString m_Process; - QString m_Library; - bool m_Forced; -}; - -class QDLLEXPORT ExecutableInfo -{ -public: - - ExecutableInfo(const QString &title, const QFileInfo &binary); - - ExecutableInfo &withArgument(const QString &argument); - - ExecutableInfo &withWorkingDirectory(const QDir &workingDirectory); - - ExecutableInfo &withSteamAppId(const QString &appId); - - ExecutableInfo &asCustom(); - - bool isValid() const; - - QString title() const; - QFileInfo binary() const; - QStringList arguments() const; - QDir workingDirectory() const; - QString steamAppID() const; - bool isCustom() const; - -private: - - QString m_Title; - QFileInfo m_Binary; - QStringList m_Arguments; - QDir m_WorkingDirectory; - QString m_SteamAppID; - bool m_Custom { false }; - -}; - -} // namespace MOBase - -#endif // EXECUTABLEINFO_H +#ifndef EXECUTABLEINFO_H +#define EXECUTABLEINFO_H + +#include "dllimport.h" +#include +#include +#include +#include + +namespace MOBase +{ + +class QDLLEXPORT ExecutableForcedLoadSetting +{ +public: + ExecutableForcedLoadSetting(const QString& process, const QString& library); + + ExecutableForcedLoadSetting& withForced(bool forced = true); + + ExecutableForcedLoadSetting& withEnabled(bool enabled = true); + + bool enabled() const; + bool forced() const; + QString library() const; + QString process() const; + +private: + bool m_Enabled; + QString m_Process; + QString m_Library; + bool m_Forced; +}; + +class QDLLEXPORT ExecutableInfo +{ +public: + ExecutableInfo(const QString& title, const QFileInfo& binary); + + ExecutableInfo& withArgument(const QString& argument); + + ExecutableInfo& withWorkingDirectory(const QDir& workingDirectory); + + ExecutableInfo& withSteamAppId(const QString& appId); + + ExecutableInfo& asCustom(); + + bool isValid() const; + + QString title() const; + QFileInfo binary() const; + QStringList arguments() const; + QDir workingDirectory() const; + QString steamAppID() const; + bool isCustom() const; + +private: + QString m_Title; + QFileInfo m_Binary; + QStringList m_Arguments; + QDir m_WorkingDirectory; + QString m_SteamAppID; + bool m_Custom{false}; +}; + +} // namespace MOBase + +#endif // EXECUTABLEINFO_H diff --git a/src/expanderwidget.cpp b/src/expanderwidget.cpp index 2b0f3501..20c79673 100644 --- a/src/expanderwidget.cpp +++ b/src/expanderwidget.cpp @@ -1,25 +1,25 @@ #include "expanderwidget.h" -namespace MOBase { - -ExpanderWidget::ExpanderWidget() - : m_button(nullptr), m_content(nullptr), opened_(false) +namespace MOBase { -} -ExpanderWidget::ExpanderWidget(QToolButton* button, QWidget* content) - : ExpanderWidget() +ExpanderWidget::ExpanderWidget() : m_button(nullptr), m_content(nullptr), opened_(false) +{} + +ExpanderWidget::ExpanderWidget(QToolButton* button, QWidget* content) : ExpanderWidget() { set(button, content); } void ExpanderWidget::set(QToolButton* button, QWidget* content, bool o) { - m_button = button; + m_button = button; m_content = content; m_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - QObject::connect(m_button, &QToolButton::clicked, [&]{ toggle(); }); + QObject::connect(m_button, &QToolButton::clicked, [&] { + toggle(); + }); toggle(o); } @@ -28,8 +28,7 @@ void ExpanderWidget::toggle() { if (opened()) { toggle(false); - } - else { + } else { toggle(true); } } @@ -90,4 +89,4 @@ QToolButton* ExpanderWidget::button() const return m_button; } -} // namespace +} // namespace MOBase diff --git a/src/expanderwidget.h b/src/expanderwidget.h index ad991224..0a5b07f8 100644 --- a/src/expanderwidget.h +++ b/src/expanderwidget.h @@ -4,42 +4,43 @@ #include "dllimport.h" #include -namespace MOBase { +namespace MOBase +{ /* Takes a QToolButton and a widget and creates an expandable widget. -**/ + **/ class QDLLEXPORT ExpanderWidget : public QObject { Q_OBJECT; public: /** empty expander, use set() - **/ + **/ ExpanderWidget(); /** see set() - **/ + **/ ExpanderWidget(QToolButton* button, QWidget* content); /** @brief sets the button and content widgets to use - * the button will be given an arrow icon, clicking it will toggle the - * visibility of the given widget - * @param button the button that toggles the content - * @param content the widget that will be shown or hidden - * @param opened initial state, defaults to closed - **/ - void set(QToolButton* button, QWidget* content, bool opened=false); + * the button will be given an arrow icon, clicking it will toggle the + * visibility of the given widget + * @param button the button that toggles the content + * @param content the widget that will be shown or hidden + * @param opened initial state, defaults to closed + **/ + void set(QToolButton* button, QWidget* content, bool opened = false); /** either opens or closes the expander depending on the current state - **/ + **/ void toggle(); /** sets the current state of the expander - **/ + **/ void toggle(bool b); /** returns whether the expander is currently opened - **/ + **/ bool opened() const; QByteArray saveState() const; @@ -57,6 +58,6 @@ class QDLLEXPORT ExpanderWidget : public QObject bool opened_; }; -} // namespace +} // namespace MOBase -#endif // EXPANDERWIDGET_H +#endif // EXPANDERWIDGET_H diff --git a/src/filemapping.h b/src/filemapping.h index 08aaf15d..2498c100 100644 --- a/src/filemapping.h +++ b/src/filemapping.h @@ -1,12 +1,11 @@ #ifndef FILEMAPPING_H #define FILEMAPPING_H - #include #include - -struct Mapping { +struct Mapping +{ QString source; QString destination; bool isDirectory; @@ -15,5 +14,4 @@ struct Mapping { typedef std::vector MappingType; - -#endif // FILEMAPPING_H +#endif // FILEMAPPING_H diff --git a/src/filesystemutilities.cpp b/src/filesystemutilities.cpp index f3b31ebf..e7a82d49 100644 --- a/src/filesystemutilities.cpp +++ b/src/filesystemutilities.cpp @@ -1,19 +1,22 @@ #include "filesystemutilities.h" -#include #include +#include namespace MOBase { -bool fixDirectoryName(QString &name) +bool fixDirectoryName(QString& name) { QString temp = name.simplified(); - while (temp.endsWith('.')) temp.chop(1); + while (temp.endsWith('.')) + temp.chop(1); temp.replace(QRegularExpression("[<>:\"/\\|?*]"), ""); - static QString invalidNames[] = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", - "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }; + static QString invalidNames[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", + "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", + "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", + "LPT6", "LPT7", "LPT8", "LPT9"}; for (unsigned int i = 0; i < sizeof(invalidNames) / sizeof(QString); ++i) { if (temp == invalidNames[i]) { temp = ""; @@ -36,7 +39,8 @@ QString sanitizeFileName(const QString& name, const QString& replacement) QString new_name = name; // Remove characters not allowed by Windows - new_name.replace(QRegularExpression("[\\x{00}-\\x{1f}\\\\/:\\*\\?\"<>|]"), replacement); + new_name.replace(QRegularExpression("[\\x{00}-\\x{1f}\\\\/:\\*\\?\"<>|]"), + replacement); // Don't end with a period or a space // Don't be "." or ".." @@ -54,12 +58,11 @@ bool validFileName(const QString& name) if (name.isEmpty()) { return false; } - if (name == "." || name == "..") - { + if (name == "." || name == "..") { return false; } return (name == sanitizeFileName(name)); } -} // namespace MOBase +} // namespace MOBase diff --git a/src/filesystemutilities.h b/src/filesystemutilities.h index ed15bb74..ae074c6b 100644 --- a/src/filesystemutilities.h +++ b/src/filesystemutilities.h @@ -11,7 +11,7 @@ namespace MOBase * @brief fix a directory name so it can be dealt with by windows explorer * @return false if there was no way to convert the name into a valid one **/ -QDLLEXPORT bool fixDirectoryName(QString &name); +QDLLEXPORT bool fixDirectoryName(QString& name); /** * @brief ensures a file name is valid @@ -20,7 +20,8 @@ QDLLEXPORT bool fixDirectoryName(QString &name); * @param replacement invalid characters are replaced with this string * @return the sanitized file name **/ -QDLLEXPORT QString sanitizeFileName(const QString& name, const QString& replacement = QString("")); +QDLLEXPORT QString sanitizeFileName(const QString& name, + const QString& replacement = QString("")); /** * @brief checks file name validity per sanitizeFileName @@ -30,6 +31,6 @@ QDLLEXPORT QString sanitizeFileName(const QString& name, const QString& replacem **/ QDLLEXPORT bool validFileName(const QString& name); -} // namespace MOBase +} // namespace MOBase -#endif // FILESYSTEM_H +#endif // FILESYSTEM_H diff --git a/src/filterwidget.cpp b/src/filterwidget.cpp index 2db3b8aa..cbde4f81 100644 --- a/src/filterwidget.cpp +++ b/src/filterwidget.cpp @@ -1,16 +1,17 @@ #include "filterwidget.h" #include "eventfilter.h" #include "log.h" -#include #include +#include -namespace MOBase { +namespace MOBase +{ void setStyleProperty(QWidget* w, const char* k, const QVariant& v) { w->setProperty(k, v); - if (auto* s=w->style()) { + if (auto* s = w->style()) { // changing properties doesn't repolish automatically s->unpolish(w); s->polish(w); @@ -24,15 +25,14 @@ void setStyleProperty(QWidget* w, const char* k, const QVariant& v) w->updateGeometry(); } - -FilterWidgetProxyModel::FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent) : - QSortFilterProxyModel(parent), m_filter(fw) +FilterWidgetProxyModel::FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent) + : QSortFilterProxyModel(parent), m_filter(fw) { setRecursiveFilteringEnabled(true); } -bool FilterWidgetProxyModel::filterAcceptsRow( - int sourceRow, const QModelIndex& sourceParent) const +bool FilterWidgetProxyModel::filterAcceptsRow(int sourceRow, + const QModelIndex& sourceParent) const { if (!m_filter.filteringEnabled()) { return true; @@ -42,7 +42,7 @@ bool FilterWidgetProxyModel::filterAcceptsRow( const auto m = m_filter.matches([&](auto&& regex) { if (m_filter.filterColumn() == -1) { - for (int c=0; cindex(sourceRow, c, sourceParent); - const auto text = sourceModel()->data(index, Qt::DisplayRole).toString(); + const auto text = sourceModel()->data(index, Qt::DisplayRole).toString(); return regex.match(text).hasMatch(); } @@ -81,30 +80,32 @@ void FilterWidgetProxyModel::sort(int column, Qt::SortOrder order) } } -bool FilterWidgetProxyModel::lessThan( - const QModelIndex& left, const QModelIndex& right) const +bool FilterWidgetProxyModel::lessThan(const QModelIndex& left, + const QModelIndex& right) const { - if (auto lt=m_filter.sortPredicate()) { + if (auto lt = m_filter.sortPredicate()) { return lt(left, right); } else { return QSortFilterProxyModel::lessThan(left, right); } } - - static FilterWidget::Options s_options; -FilterWidget::FilterWidget() : - m_edit(nullptr), m_list(nullptr), m_proxy(nullptr), - m_eventFilter(nullptr), m_clear(nullptr), m_timer(nullptr), - m_useDelay(false), m_valid(true), m_useSourceSort(false), m_filterColumn(-1), - m_filteringEnabled(true), m_filteredBorder(true) +FilterWidget::FilterWidget() + : m_edit(nullptr), m_list(nullptr), m_proxy(nullptr), m_eventFilter(nullptr), + m_clear(nullptr), m_timer(nullptr), m_useDelay(false), m_valid(true), + m_useSourceSort(false), m_filterColumn(-1), m_filteringEnabled(true), + m_filteredBorder(true) { m_timer = new QTimer(this); m_timer->setSingleShot(true); - QObject::connect(m_timer, &QTimer::timeout, this, [&] { set(); }, Qt::QueuedConnection); - + QObject::connect( + m_timer, &QTimer::timeout, this, + [&] { + set(); + }, + Qt::QueuedConnection); } void FilterWidget::setOptions(const Options& o) @@ -156,7 +157,8 @@ void FilterWidget::clear() void FilterWidget::scrollToSelection() { - if (options().scrollToSelection && m_list && m_list->selectionModel()->hasSelection()) { + if (options().scrollToSelection && m_list && + m_list->selectionModel()->hasSelection()) { m_list->scrollTo(m_list->selectionModel()->selectedIndexes()[0]); } } @@ -288,7 +290,7 @@ void FilterWidget::compile() if (s_options.useRegex) { QRegularExpression::PatternOptions flags = - QRegularExpression::DotMatchesEverythingOption; + QRegularExpression::DotMatchesEverythingOption; if (!s_options.regexCaseSensitive) { flags |= QRegularExpression::CaseInsensitiveOption; @@ -314,9 +316,8 @@ void FilterWidget::compile() for (const auto& keyword : keywords) { const QString escaped = QRegularExpression::escape(keyword); - const auto flags = - QRegularExpression::CaseInsensitiveOption | - QRegularExpression::DotMatchesEverythingOption; + const auto flags = QRegularExpression::CaseInsensitiveOption | + QRegularExpression::DotMatchesEverythingOption; regexes.push_back(QRegularExpression(escaped, flags)); } @@ -361,7 +362,7 @@ bool FilterWidget::matches(predFun pred) const // but it doesn't matter where. for (auto& currentKeyword : ANDKeywords) { if (!pred(currentKeyword)) { - segmentGood = false; + segmentGood = false; } } @@ -396,7 +397,9 @@ void FilterWidget::hookEdit() }); m_edit->installEventFilter(m_eventFilter); - QObject::connect(m_edit, &QLineEdit::textChanged, [&]{ onTextChanged(); }); + QObject::connect(m_edit, &QLineEdit::textChanged, [&] { + onTextChanged(); + }); } void FilterWidget::unhookEdit() @@ -483,12 +486,10 @@ void FilterWidget::setShortcuts() m_shortcuts.push_back(s); }; - // don't hook the escape key for reset when the filter is in a dialog, the // standard behaviour is to close the dialog - const bool inDialog = topLevelIsDialog( - m_list ? static_cast(m_list) : m_edit); - + const bool inDialog = + topLevelIsDialog(m_list ? static_cast(m_list) : m_edit); if (m_list) { hookActivate(m_list); @@ -535,7 +536,9 @@ void FilterWidget::createClear() m_clear->setStyleSheet("QToolButton { border: none; padding: 0px; }"); m_clear->hide(); - QObject::connect(m_clear, &QToolButton::clicked, [&]{ clear(); }); + QObject::connect(m_clear, &QToolButton::clicked, [&] { + clear(); + }); repositionClearButton(); } @@ -547,8 +550,7 @@ void FilterWidget::set() QString currentText; if (m_edit != nullptr) { currentText = m_edit->text(); - } - else { + } else { currentText = m_text; } @@ -590,8 +592,7 @@ void FilterWidget::onTextChanged() if (m_useDelay) { m_timer->start(500); - } - else { + } else { set(); } } @@ -613,18 +614,16 @@ void FilterWidget::onContextMenu(QObject*, QContextMenuEvent* e) f.setBold(true); title->setFont(f); - auto* regex = new QAction(tr("Use regular expressions"), m_edit); regex->setStatusTip(tr("Use regular expressions in filters")); regex->setCheckable(true); regex->setChecked(s_options.useRegex); - connect(regex, &QAction::triggered, [&]{ + connect(regex, &QAction::triggered, [&] { s_options.useRegex = regex->isChecked(); update(); }); - auto* cs = new QAction(tr("Case sensitive"), m_edit); //: leave "(/i)" verbatim cs->setStatusTip(tr("Make regular expressions case sensitive (/i)")); @@ -632,12 +631,11 @@ void FilterWidget::onContextMenu(QObject*, QContextMenuEvent* e) cs->setChecked(s_options.regexCaseSensitive); cs->setEnabled(s_options.useRegex); - connect(cs, &QAction::triggered, [&]{ + connect(cs, &QAction::triggered, [&] { s_options.regexCaseSensitive = cs->isChecked(); update(); }); - auto* x = new QAction(tr("Extended"), m_edit); //: leave "(/x)" verbatim x->setStatusTip(tr("Ignores unescaped whitespace in regular expressions (/x)")); @@ -645,7 +643,7 @@ void FilterWidget::onContextMenu(QObject*, QContextMenuEvent* e) x->setChecked(s_options.regexExtended); x->setEnabled(s_options.useRegex); - connect(x, &QAction::triggered, [&]{ + connect(x, &QAction::triggered, [&] { s_options.regexExtended = x->isChecked(); update(); }); @@ -658,8 +656,7 @@ void FilterWidget::onContextMenu(QObject*, QContextMenuEvent* e) connect(sts, &QAction::triggered, [&] { s_options.scrollToSelection = sts->isChecked(); update(); - }); - + }); m->insertSeparator(m->actions().first()); m->insertAction(m->actions().first(), x); @@ -677,9 +674,9 @@ void FilterWidget::repositionClearButton() return; } - const QSize sz = m_clear->sizeHint(); + const QSize sz = m_clear->sizeHint(); const int frame = m_edit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - const auto r = m_edit->rect(); + const auto r = m_edit->rect(); const auto x = r.right() - frame - sz.width(); const auto y = (r.bottom() + 1 - sz.height()) / 2; @@ -687,4 +684,4 @@ void FilterWidget::repositionClearButton() m_clear->move(x, y); } -} // namespace +} // namespace MOBase diff --git a/src/filterwidget.h b/src/filterwidget.h index 0bf39ffc..d4d14dcc 100644 --- a/src/filterwidget.h +++ b/src/filterwidget.h @@ -1,17 +1,18 @@ #ifndef FILTERWIDGET_H #define FILTERWIDGET_H -#include +#include "dllimport.h" +#include #include -#include #include -#include -#include +#include #include #include -#include "dllimport.h" +#include +#include -namespace MOBase { +namespace MOBase +{ class EventFilter; class FilterWidget; @@ -21,7 +22,7 @@ class QDLLEXPORT FilterWidgetProxyModel : public QSortFilterProxyModel Q_OBJECT; public: - FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent=nullptr); + FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent = nullptr); using QSortFilterProxyModel::invalidateFilter; protected: @@ -32,12 +33,10 @@ class QDLLEXPORT FilterWidgetProxyModel : public QSortFilterProxyModel private: FilterWidget& m_filter; - bool columnMatches( - int sourceRow, const QModelIndex& sourceParent, - int c, const QRegularExpression& what) const; + bool columnMatches(int sourceRow, const QModelIndex& sourceParent, int c, + const QRegularExpression& what) const; }; - class QDLLEXPORT FilterWidget : public QObject { Q_OBJECT; @@ -45,15 +44,14 @@ class QDLLEXPORT FilterWidget : public QObject public: struct Options { - bool useRegex = false; + bool useRegex = false; bool regexCaseSensitive = false; - bool regexExtended = false; - bool scrollToSelection = false; + bool regexExtended = false; + bool scrollToSelection = false; }; - using predFun = std::function; - using sortFun = std::function; - + using predFun = std::function; + using sortFun = std::function; FilterWidget(); @@ -140,6 +138,6 @@ class QDLLEXPORT FilterWidget : public QObject void compile(); }; -} // namespace +} // namespace MOBase -#endif // FILTERWIDGET_H +#endif // FILTERWIDGET_H diff --git a/src/finddialog.cpp b/src/finddialog.cpp index 6854d7fd..b1307e9b 100644 --- a/src/finddialog.cpp +++ b/src/finddialog.cpp @@ -1,52 +1,51 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "finddialog.h" -#include "ui_finddialog.h" - -namespace MOBase { - -FindDialog::FindDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::FindDialog) -{ - ui->setupUi(this); -} - -FindDialog::~FindDialog() -{ - delete ui; -} - -void FindDialog::on_nextBtn_clicked() -{ - emit findNext(); -} - -void FindDialog::on_patternEdit_textChanged(const QString &pattern) -{ - emit patternChanged(pattern); -} - -void FindDialog::on_closeBtn_clicked() -{ - this->close(); -} -} // namespace MOBase +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "finddialog.h" +#include "ui_finddialog.h" + +namespace MOBase +{ + +FindDialog::FindDialog(QWidget* parent) : QDialog(parent), ui(new Ui::FindDialog) +{ + ui->setupUi(this); +} + +FindDialog::~FindDialog() +{ + delete ui; +} + +void FindDialog::on_nextBtn_clicked() +{ + emit findNext(); +} + +void FindDialog::on_patternEdit_textChanged(const QString& pattern) +{ + emit patternChanged(pattern); +} + +void FindDialog::on_closeBtn_clicked() +{ + this->close(); +} +} // namespace MOBase diff --git a/src/finddialog.h b/src/finddialog.h index 77cae2ef..77a8ac30 100644 --- a/src/finddialog.h +++ b/src/finddialog.h @@ -1,79 +1,80 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef FINDDIALOG_H -#define FINDDIALOG_H - -#include - -namespace Ui { - class FindDialog; -} - -namespace MOBase { - -/** - * @brief Find dialog used in the TextView dialog - **/ -class FindDialog : public QDialog -{ - - Q_OBJECT - -public: - - /** - * @brief constructor - * - * @param parent parent widget - **/ - explicit FindDialog(QWidget *parent = 0); - - ~FindDialog(); - -signals: - - /** - * @brief emitted when the user wants to jump to the next location matching the pattern - **/ - void findNext(); - - /** - * @brief emitted when the user changes the pattern to search for - * - * @param pattern the new search pattern - **/ - void patternChanged(const QString &pattern); - -private slots: - void on_nextBtn_clicked(); - - void on_patternEdit_textChanged(const QString &arg1); - - void on_closeBtn_clicked(); - -private: - Ui::FindDialog *ui; -}; - -} // namespace MOBase - -#endif // FINDDIALOG_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef FINDDIALOG_H +#define FINDDIALOG_H + +#include + +namespace Ui +{ +class FindDialog; +} + +namespace MOBase +{ + +/** + * @brief Find dialog used in the TextView dialog + **/ +class FindDialog : public QDialog +{ + + Q_OBJECT + +public: + /** + * @brief constructor + * + * @param parent parent widget + **/ + explicit FindDialog(QWidget* parent = 0); + + ~FindDialog(); + +signals: + + /** + * @brief emitted when the user wants to jump to the next location matching the + *pattern + **/ + void findNext(); + + /** + * @brief emitted when the user changes the pattern to search for + * + * @param pattern the new search pattern + **/ + void patternChanged(const QString& pattern); + +private slots: + void on_nextBtn_clicked(); + + void on_patternEdit_textChanged(const QString& arg1); + + void on_closeBtn_clicked(); + +private: + Ui::FindDialog* ui; +}; + +} // namespace MOBase + +#endif // FINDDIALOG_H diff --git a/src/game_features/bsainvalidation.h b/src/game_features/bsainvalidation.h index 5d6aea8d..555c44ee 100644 --- a/src/game_features/bsainvalidation.h +++ b/src/game_features/bsainvalidation.h @@ -1,24 +1,25 @@ #ifndef BSAINVALIDATION_H #define BSAINVALIDATION_H -namespace MOBase { class IProfile; } +namespace MOBase +{ +class IProfile; +} class QString; class BSAInvalidation { public: - virtual ~BSAInvalidation() {} - virtual bool isInvalidationBSA(const QString &bsaName) = 0; - - virtual void deactivate(MOBase::IProfile *profile) = 0; + virtual bool isInvalidationBSA(const QString& bsaName) = 0; - virtual void activate(MOBase::IProfile *profile) = 0; + virtual void deactivate(MOBase::IProfile* profile) = 0; - virtual bool prepareProfile(MOBase::IProfile *profile) = 0; + virtual void activate(MOBase::IProfile* profile) = 0; + virtual bool prepareProfile(MOBase::IProfile* profile) = 0; }; -#endif // BSAINVALIDATION_H +#endif // BSAINVALIDATION_H diff --git a/src/game_features/dataarchives.h b/src/game_features/dataarchives.h index 04a4cf76..8fc00ba8 100644 --- a/src/game_features/dataarchives.h +++ b/src/game_features/dataarchives.h @@ -4,29 +4,32 @@ #include #include -namespace MOBase { class IProfile; } +namespace MOBase +{ +class IProfile; +} -class DataArchives { +class DataArchives +{ public: - virtual ~DataArchives() {} virtual QStringList vanillaArchives() const = 0; - virtual QStringList archives(const MOBase::IProfile *profile) const = 0; + virtual QStringList archives(const MOBase::IProfile* profile) const = 0; /** * @brief add an archive to the archive list * @param profile the profile for which to change the archive list - * @param index index to insert before. 0 is the beginning of the list, INT_MAX can be used for the end of the list + * @param index index to insert before. 0 is the beginning of the list, INT_MAX can be + * used for the end of the list * @param archiveName the archive to add */ - virtual void addArchive(MOBase::IProfile *profile, int index, const QString &archiveName) = 0; - - virtual void removeArchive(MOBase::IProfile *profile, const QString &archiveName) = 0; + virtual void addArchive(MOBase::IProfile* profile, int index, + const QString& archiveName) = 0; + virtual void removeArchive(MOBase::IProfile* profile, const QString& archiveName) = 0; }; -#endif // DATAARCHIVES - +#endif // DATAARCHIVES diff --git a/src/game_features/gameplugins.h b/src/game_features/gameplugins.h index aa41838b..397ad379 100644 --- a/src/game_features/gameplugins.h +++ b/src/game_features/gameplugins.h @@ -3,20 +3,21 @@ #include -namespace MOBase { class IPluginList; } +namespace MOBase +{ +class IPluginList; +} - -class GamePlugins { +class GamePlugins +{ public: - virtual ~GamePlugins() {} - virtual void writePluginLists(const MOBase::IPluginList *pluginList) = 0; - virtual void readPluginLists(MOBase::IPluginList *pluginList) = 0; - virtual QStringList getLoadOrder() = 0; - virtual bool lightPluginsAreSupported() = 0; - + virtual void writePluginLists(const MOBase::IPluginList* pluginList) = 0; + virtual void readPluginLists(MOBase::IPluginList* pluginList) = 0; + virtual QStringList getLoadOrder() = 0; + virtual bool lightPluginsAreSupported() = 0; }; -#endif // GAMEPLUGINS_H +#endif // GAMEPLUGINS_H diff --git a/src/game_features/localsavegames.h b/src/game_features/localsavegames.h index cc615f41..5b2d66fc 100644 --- a/src/game_features/localsavegames.h +++ b/src/game_features/localsavegames.h @@ -5,17 +5,19 @@ #include "filemapping.h" -namespace MOBase { class IProfile; } +namespace MOBase +{ +class IProfile; +} -class LocalSavegames { +class LocalSavegames +{ public: - virtual ~LocalSavegames() {} - virtual MappingType mappings(const QDir &profileSaveDir) const = 0; - virtual bool prepareProfile(MOBase::IProfile *profile) = 0; - + virtual MappingType mappings(const QDir& profileSaveDir) const = 0; + virtual bool prepareProfile(MOBase::IProfile* profile) = 0; }; -#endif // LOCALSAVEGAMES_H +#endif // LOCALSAVEGAMES_H diff --git a/src/game_features/moddatachecker.h b/src/game_features/moddatachecker.h index 0565a111..d466a07b 100644 --- a/src/game_features/moddatachecker.h +++ b/src/game_features/moddatachecker.h @@ -3,15 +3,19 @@ #include -namespace MOBase { class IFileTree; } +namespace MOBase +{ +class IFileTree; +} -class ModDataChecker { +class ModDataChecker +{ public: - /** * */ - enum class CheckReturn { + enum class CheckReturn + { INVALID, FIXABLE, VALID @@ -22,43 +26,45 @@ class ModDataChecker { * fixed. * * This method is mainly used during installation (to find which installer should - * be used or to recurse into multi-level archives), or to quickly indicates to a + * be used or to recurse into multi-level archives), or to quickly indicates to a * user if a mod looks valid. * * This method does not have to be exact, it only has to indicate if the given tree * looks like a valid mod or not by quickly checking the structure (heavy operations * should be avoided). * - * If the tree can be fixed by the `fix()` method, this method should return `FIXABLE`. - * `FIXABLE` should only be returned when it is guaranteed that `fix()` can fix the tree. + * If the tree can be fixed by the `fix()` method, this method should return + * `FIXABLE`. `FIXABLE` should only be returned when it is guaranteed that `fix()` can + * fix the tree. * * @param tree The tree starting at the root of the "data" folder. * * @return whether the tree is invalid, fixable or valid. */ - virtual CheckReturn dataLooksValid(std::shared_ptr fileTree) const = 0; + virtual CheckReturn + dataLooksValid(std::shared_ptr fileTree) const = 0; /** * @brief Try to fix the given tree. * - * This method is used during installation to try to fix invalid archives and will only be - * called if dataLooksValid returned `FIXABLE`. + * This method is used during installation to try to fix invalid archives and will + * only be called if dataLooksValid returned `FIXABLE`. * * @param tree The tree to try to fix. Can be modified during the process. * * @return the fixed tree, or a null pointer if the tree could not be fixed. */ - virtual std::shared_ptr fix(std::shared_ptr fileTree) const { + virtual std::shared_ptr + fix(std::shared_ptr fileTree) const + { return nullptr; } public: - /** * */ - virtual ~ModDataChecker() { } - + virtual ~ModDataChecker() {} }; -#endif \ No newline at end of file +#endif diff --git a/src/game_features/moddatacontent.h b/src/game_features/moddatacontent.h index 5ec3ba84..cf25ab30 100644 --- a/src/game_features/moddatacontent.h +++ b/src/game_features/moddatacontent.h @@ -7,75 +7,94 @@ #include -namespace MOBase { class IFileTree; } +namespace MOBase +{ +class IFileTree; +} /** * The ModDataContent feature is used (when available) to indicate to users the content * of mods in the "Content" column. * - * The feature exposes a list of possible content types, each associated with an ID, a name - * and an icon. The icon is the path to either: + * The feature exposes a list of possible content types, each associated with an ID, a + * name and an icon. The icon is the path to either: * - A Qt resource or; * - A file on the disk. * - * In order to facilitate the implementation, MO2 already provides a set of icons that can - * be used. Those icons are all under :/MO/gui/content (e.g. :/MO/gui/content/plugin or :/MO/gui/content/music). + * In order to facilitate the implementation, MO2 already provides a set of icons that + * can be used. Those icons are all under :/MO/gui/content (e.g. :/MO/gui/content/plugin + * or :/MO/gui/content/music). * * The list of available icons is: - * - plugin: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/jigsaw-piece.png - * - skyproc: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/hand-of-god.png - * - texture: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/empty-chessboard.png - * - music: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/double-quaver.png - * - sound: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/lyre.png - * - interface: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/usable.png - * - skse: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/checkbox-tree.png - * - script: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/tinker.png - * - mesh: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/breastplate.png - * - string: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/conversation.png - * - bsa: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/locked-chest.png - * - menu: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/config.png - * - inifile: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/feather-and-scroll.png - * - modgroup: https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/xedit.png + * - plugin: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/jigsaw-piece.png + * - skyproc: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/hand-of-god.png + * - texture: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/empty-chessboard.png + * - music: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/double-quaver.png + * - sound: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/lyre.png + * - interface: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/usable.png + * - skse: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/checkbox-tree.png + * - script: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/tinker.png + * - mesh: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/breastplate.png + * - string: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/conversation.png + * - bsa: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/locked-chest.png + * - menu: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/config.png + * - inifile: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/feather-and-scroll.png + * - modgroup: + * https://github.com/ModOrganizer2/modorganizer/blob/master/src/resources/contents/xedit.png */ -class ModDataContent { +class ModDataContent +{ public: - - struct Content { + struct Content + { /** * @param id ID of this content. * @param name Name of this content. * @param icon Path to the icon for this content. Can be either a path - * to an image on the disk, or to a resource. Can be an empty string if filterOnly - * is true. - * @param filterOnly Indicates if the content should only be show in the filter + * to an image on the disk, or to a resource. Can be an empty string if + * filterOnly is true. + * @param filterOnly Indicates if the content should only be show in the filter * criteria and not in the actual Content column. */ - Content(int id, QString name, QString icon, bool filterOnly = false) : - m_Id{ id }, m_Name{ name }, m_Icon{ icon }, m_FilterOnly{ filterOnly } { } + Content(int id, QString name, QString icon, bool filterOnly = false) + : m_Id{id}, m_Name{name}, m_Icon{icon}, m_FilterOnly{filterOnly} + {} /** * @return the ID of this content. */ int id() const { return m_Id; } - + /** * @return the name of this content. */ QString name() const { return m_Name; } - + /** * @return the path to the icon of this content (can be a Qt resource path). */ QString icon() const { return m_Icon; } - + /** * @return true if this content is only meant to be used as a filter criteria. */ bool isOnlyForFilter() const { return m_FilterOnly; } private: - int m_Id; QString m_Name; QString m_Icon; @@ -94,15 +113,14 @@ class ModDataContent { * * @return the IDs of the content in the given tree. */ - virtual std::vector getContentsFor(std::shared_ptr fileTree) const = 0; + virtual std::vector + getContentsFor(std::shared_ptr fileTree) const = 0; public: - /** * */ - virtual ~ModDataContent() { } - + virtual ~ModDataContent() {} }; -#endif \ No newline at end of file +#endif diff --git a/src/game_features/savegameinfo.h b/src/game_features/savegameinfo.h index 0b0dc29b..588f896b 100644 --- a/src/game_features/savegameinfo.h +++ b/src/game_features/savegameinfo.h @@ -1,8 +1,14 @@ #ifndef SAVEGAMEINFO_H #define SAVEGAMEINFO_H -namespace MOBase { class ISaveGame; } -namespace MOBase { class ISaveGameInfoWidget; } +namespace MOBase +{ +class ISaveGame; +} +namespace MOBase +{ +class ISaveGameInfoWidget; +} #include #include @@ -41,8 +47,7 @@ class SaveGameInfo * It is permitted to return a null pointer to indicate the plugin does not have a * nice visual way of displaying save game contents. */ - virtual MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *parent = 0) const = 0; + virtual MOBase::ISaveGameInfoWidget* getSaveGameWidget(QWidget* parent = 0) const = 0; }; -#endif // SAVEGAMEINFO_H - +#endif // SAVEGAMEINFO_H diff --git a/src/game_features/scriptextender.h b/src/game_features/scriptextender.h index 4e31e4d7..0eb148f6 100644 --- a/src/game_features/scriptextender.h +++ b/src/game_features/scriptextender.h @@ -6,10 +6,10 @@ #include #include -class ScriptExtender { +class ScriptExtender +{ public: - virtual ~ScriptExtender() {} /** Get the name of the script extender binary */ @@ -37,5 +37,4 @@ class ScriptExtender { virtual WORD getArch() const = 0; }; -#endif // SCRIPTEXTENDER - +#endif // SCRIPTEXTENDER diff --git a/src/game_features/unmanagedmods.h b/src/game_features/unmanagedmods.h index a15e661b..cc59d022 100644 --- a/src/game_features/unmanagedmods.h +++ b/src/game_features/unmanagedmods.h @@ -5,13 +5,11 @@ #include #include - -class UnmanagedMods { +class UnmanagedMods +{ public: - public: - virtual ~UnmanagedMods() {} /** @@ -24,21 +22,19 @@ class UnmanagedMods { * @param modName (internal) name of the mod being requested * @return display name of the mod */ - virtual QString displayName(const QString &modName) const = 0; + virtual QString displayName(const QString& modName) const = 0; /** * @param modName name of the mod being requested * @return reference file info */ - virtual QFileInfo referenceFile(const QString &modName) const = 0; + virtual QFileInfo referenceFile(const QString& modName) const = 0; /** * @param modName name of the mod being requested * @return list of file names (absolute paths) */ - virtual QStringList secondaryFiles(const QString &modName) const = 0; - + virtual QStringList secondaryFiles(const QString& modName) const = 0; }; -#endif // UNMANAGEDMODS_H - +#endif // UNMANAGEDMODS_H diff --git a/src/guessedvalue.cpp b/src/guessedvalue.cpp index ee6cd928..36866fcc 100644 --- a/src/guessedvalue.cpp +++ b/src/guessedvalue.cpp @@ -1 +1 @@ -#include "guessedvalue.h" +#include "guessedvalue.h" diff --git a/src/guessedvalue.h b/src/guessedvalue.h index c27a52cd..9c0be517 100644 --- a/src/guessedvalue.h +++ b/src/guessedvalue.h @@ -1,257 +1,252 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef GUESSEDVALUE_H -#define GUESSEDVALUE_H - - -#include -#include - - -namespace MOBase { - - -/** - * @brief describes how good the code considers a guess (i.e. for a mod name) - * this is used to determine if a name from another source should overwrite or not - */ -enum EGuessQuality { - GUESS_INVALID, /// no valid value has been set yet - GUESS_FALLBACK, /// the guess is very basic and should only be used if no other source is available - GUESS_GOOD, /// considered a good guess - GUESS_META, /// the value comes from meta data and is usually what the author intended - GUESS_PRESET, /// the value comes from a previous install of the same data and usually represents what the user chose before - GUESS_USER /// the user selection. Always overrules other sources -}; - - -/** - * Represents a value that may be set from different places. Each time the value is changed a "quality" is specified - * to say how probable it is the value is the best choice. Only the best choice should be used in the end but alternatives can be queried. - * This class also allows a filter to be set. If a "guess" doesn't pass the filter, it is ignored. - */ -template class GuessedValue -{ -public: - -public: - -/** - * @brief default constructor - */ - GuessedValue(); - -/** - * @brief constructor with initial value - * - * @param reference the initial value to set - * @param quality quality of the guess - */ - GuessedValue(const T &reference, EGuessQuality quality = GUESS_USER); - - /** - * @brief - * - * @param reference - * @return GuessedValue - */ - GuessedValue &operator=(const GuessedValue &reference); - - /** - * install a filter function. This filter is applied on every update and can - * refuse the update altogether or modify the value. - * @param filterFunction the filter to apply - */ - /** - * @brief - * - * @param filterFunction - */ - void setFilter(std::function filterFunction); - -/** - * @brief - * - * @return operator const T - */ - operator const T&() const { return m_Value; } - - /** - * @brief - * - * @return T *operator -> - */ - T *operator->() { return &m_Value; } - /** - * @brief - * - * @return const T *operator -> - */ - /** - * @brief - * - * @return const T *operator -> - */ - const T *operator->() const { return &m_Value; } - - /** - * @brief - * - * @param value - * @return GuessedValue - */ - GuessedValue &update(const T &value); - /** - * @brief - * - * @param value - * @param quality - * @return GuessedValue - */ - GuessedValue &update(const T &value, EGuessQuality quality); - - /** - * @brief - * - * @return const std::set - */ - const std::set &variants() const { return m_Variants; } - -private: - - T m_Value; /**< TODO */ - std::set m_Variants; /**< TODO */ - EGuessQuality m_Quality; /**< TODO */ - std::function m_Filter; - -}; - - -template -/** - * @brief - * - * @param - * @return bool - */ -bool nullFilter(T&) { - return true; -} - - - -/** - * @brief - * - */ -template -GuessedValue::GuessedValue() - : m_Value(), m_Quality(GUESS_INVALID), m_Filter(nullFilter) -{ -} - -/** - * @brief - * - * @param reference - * @param quality - */ -template -GuessedValue::GuessedValue(const T &reference, EGuessQuality quality) - : m_Value(reference), m_Variants{ reference }, m_Quality(quality), m_Filter(nullFilter) -{ -} - -/** - * @brief - * - * @param reference - * @return GuessedValue &GuessedValue - */ -template -GuessedValue &GuessedValue::operator=(const GuessedValue &reference) -{ - if (this != &reference) { - if (reference.m_Quality >= m_Quality) { - m_Value = reference.m_Value; - m_Quality = reference.m_Quality; - m_Filter = reference.m_Filter; - m_Variants = reference.m_Variants; - } - } - return *this; -} - -/** - * @brief - * - * @param filterFunction - */ -template -void GuessedValue::setFilter(std::function filterFunction) -{ - m_Filter = filterFunction; -} - - -/** - * @brief - * - * @param value - * @return GuessedValue &GuessedValue - */ -template -GuessedValue &GuessedValue::update(const T &value) -{ - T temp = value; - if (m_Filter(temp)) { - m_Variants.insert(temp); - m_Value = temp; - } - return *this; -} - - -/** - * @brief - * - * @param value - * @param quality - * @return GuessedValue &GuessedValue - */ -template -GuessedValue &GuessedValue::update(const T &value, EGuessQuality quality) -{ - T temp = value; - if (m_Filter(temp)) { - m_Variants.insert(temp); - if (quality >= m_Quality) { - m_Value = temp; - m_Quality = quality; - } - } - return *this; -} - -} // namespace MOBase; - -#endif // GUESSEDVALUE_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef GUESSEDVALUE_H +#define GUESSEDVALUE_H + +#include +#include + +namespace MOBase +{ + +/** + * @brief describes how good the code considers a guess (i.e. for a mod name) + * this is used to determine if a name from another source should overwrite or + * not + */ +enum EGuessQuality +{ + GUESS_INVALID, /// no valid value has been set yet + GUESS_FALLBACK, /// the guess is very basic and should only be used if no other + /// source is available + GUESS_GOOD, /// considered a good guess + GUESS_META, /// the value comes from meta data and is usually what the author + /// intended + GUESS_PRESET, /// the value comes from a previous install of the same data and + /// usually represents what the user chose before + GUESS_USER /// the user selection. Always overrules other sources +}; + +/** + * Represents a value that may be set from different places. Each time the value is + * changed a "quality" is specified to say how probable it is the value is the best + * choice. Only the best choice should be used in the end but alternatives can be + * queried. This class also allows a filter to be set. If a "guess" doesn't pass the + * filter, it is ignored. + */ +template +class GuessedValue +{ +public: +public: + /** + * @brief default constructor + */ + GuessedValue(); + + /** + * @brief constructor with initial value + * + * @param reference the initial value to set + * @param quality quality of the guess + */ + GuessedValue(const T& reference, EGuessQuality quality = GUESS_USER); + + /** + * @brief + * + * @param reference + * @return GuessedValue + */ + GuessedValue& operator=(const GuessedValue& reference); + + /** + * install a filter function. This filter is applied on every update and can + * refuse the update altogether or modify the value. + * @param filterFunction the filter to apply + */ + /** + * @brief + * + * @param filterFunction + */ + void setFilter(std::function filterFunction); + + /** + * @brief + * + * @return operator const T + */ + operator const T&() const { return m_Value; } + + /** + * @brief + * + * @return T *operator -> + */ + T* operator->() { return &m_Value; } + /** + * @brief + * + * @return const T *operator -> + */ + /** + * @brief + * + * @return const T *operator -> + */ + const T* operator->() const { return &m_Value; } + + /** + * @brief + * + * @param value + * @return GuessedValue + */ + GuessedValue& update(const T& value); + /** + * @brief + * + * @param value + * @param quality + * @return GuessedValue + */ + GuessedValue& update(const T& value, EGuessQuality quality); + + /** + * @brief + * + * @return const std::set + */ + const std::set& variants() const { return m_Variants; } + +private: + T m_Value; /**< TODO */ + std::set m_Variants; /**< TODO */ + EGuessQuality m_Quality; /**< TODO */ + std::function m_Filter; +}; + +template +/** + * @brief + * + * @param + * @return bool + */ +bool nullFilter(T&) +{ + return true; +} + +/** + * @brief + * + */ +template +GuessedValue::GuessedValue() + : m_Value(), m_Quality(GUESS_INVALID), m_Filter(nullFilter) +{} + +/** + * @brief + * + * @param reference + * @param quality + */ +template +GuessedValue::GuessedValue(const T& reference, EGuessQuality quality) + : m_Value(reference), m_Variants{reference}, m_Quality(quality), + m_Filter(nullFilter) +{} + +/** + * @brief + * + * @param reference + * @return GuessedValue &GuessedValue + */ +template +GuessedValue& GuessedValue::operator=(const GuessedValue& reference) +{ + if (this != &reference) { + if (reference.m_Quality >= m_Quality) { + m_Value = reference.m_Value; + m_Quality = reference.m_Quality; + m_Filter = reference.m_Filter; + m_Variants = reference.m_Variants; + } + } + return *this; +} + +/** + * @brief + * + * @param filterFunction + */ +template +void GuessedValue::setFilter(std::function filterFunction) +{ + m_Filter = filterFunction; +} + +/** + * @brief + * + * @param value + * @return GuessedValue &GuessedValue + */ +template +GuessedValue& GuessedValue::update(const T& value) +{ + T temp = value; + if (m_Filter(temp)) { + m_Variants.insert(temp); + m_Value = temp; + } + return *this; +} + +/** + * @brief + * + * @param value + * @param quality + * @return GuessedValue &GuessedValue + */ +template +GuessedValue& GuessedValue::update(const T& value, EGuessQuality quality) +{ + T temp = value; + if (m_Filter(temp)) { + m_Variants.insert(temp); + if (quality >= m_Quality) { + m_Value = temp; + m_Quality = quality; + } + } + return *this; +} + +} // namespace MOBase + +#endif // GUESSEDVALUE_H diff --git a/src/idownloadmanager.h b/src/idownloadmanager.h index 3b1e1f10..cb596f97 100644 --- a/src/idownloadmanager.h +++ b/src/idownloadmanager.h @@ -1,94 +1,92 @@ -#ifndef IDOWNLOADMANAGER_H -#define IDOWNLOADMANAGER_H - -#include -#include "dllimport.h" -#include -#include -#include - - -namespace MOBase { - -class QDLLEXPORT IDownloadManager : public QObject -{ - Q_OBJECT - -public: - - IDownloadManager(QObject *parent = nullptr) - : QObject(parent) - {} - - /** - * @brief download a file by url. The list can contain alternative URLs to allow the - * download manager to switch in case of download problems - * @param urls list of urls to download from - * @return an id by which the download will be identified - */ - virtual int startDownloadURLs(const QStringList &urls) = 0; - - /** - * @brief download a file from www.nexusmods.com/. is always the game currently being managed - * @param modID id of the mod for which to download a file - * @param fileID id of the file to download - * @return an id by which the download will be identified - */ - virtual int startDownloadNexusFile(int modID, int fileID) = 0; - - /** - * @brief get the (absolute) file path of the specified download. - * @param id id of the download as returned by the download... functions - * @return absoute path to the downloaded file. This file may not yet exist if the download is incomplete - */ - virtual QString downloadPath(int id) = 0; - - /** - * @brief Installs a handler to be called when a download complete. - * - * @param callback The function to be called when a download complete. The argument is - * the download ID. - * - * @return true if the handler was successfully installed (there is as of now no known reason - * this should fail). - */ - virtual bool onDownloadComplete(const std::function &callback) = 0; - - /** - * @brief Installs a handler to be called when a download is paused. - * - * @param callback The function to be called when a download is paused. The argument is - * the download ID. - * - * @return true if the handler was successfully installed (there is as of now no known reason - * this should fail). - */ - virtual bool onDownloadPaused(const std::function& callback) = 0; - - /** - * @brief Installs a handler to be called when a download fails. - * - * @param callback The function to be called when a download fails. The argument is - * the download ID. - * - * @return true if the handler was successfully installed (there is as of now no known reason - * this should fail). - */ - virtual bool onDownloadFailed(const std::function& callback) = 0; - - /** - * @brief Installs a handler to be called when a download is removed. - * - * @param callback The function to be called when a download is removed. The argument is - * the download ID (which is no longer valid). - * - * @return true if the handler was successfully installed (there is as of now no known reason - * this should fail). - */ - virtual bool onDownloadRemoved(const std::function& callback) = 0; - -}; - -} - -#endif // IDOWNLOADMANAGER_H +#ifndef IDOWNLOADMANAGER_H +#define IDOWNLOADMANAGER_H + +#include "dllimport.h" +#include +#include +#include +#include + +namespace MOBase +{ + +class QDLLEXPORT IDownloadManager : public QObject +{ + Q_OBJECT + +public: + IDownloadManager(QObject* parent = nullptr) : QObject(parent) {} + + /** + * @brief download a file by url. The list can contain alternative URLs to allow the + * download manager to switch in case of download problems + * @param urls list of urls to download from + * @return an id by which the download will be identified + */ + virtual int startDownloadURLs(const QStringList& urls) = 0; + + /** + * @brief download a file from www.nexusmods.com/. is always the game + * currently being managed + * @param modID id of the mod for which to download a file + * @param fileID id of the file to download + * @return an id by which the download will be identified + */ + virtual int startDownloadNexusFile(int modID, int fileID) = 0; + + /** + * @brief get the (absolute) file path of the specified download. + * @param id id of the download as returned by the download... functions + * @return absoute path to the downloaded file. This file may not yet exist if the + * download is incomplete + */ + virtual QString downloadPath(int id) = 0; + + /** + * @brief Installs a handler to be called when a download complete. + * + * @param callback The function to be called when a download complete. The argument is + * the download ID. + * + * @return true if the handler was successfully installed (there is as of now no known + * reason this should fail). + */ + virtual bool onDownloadComplete(const std::function& callback) = 0; + + /** + * @brief Installs a handler to be called when a download is paused. + * + * @param callback The function to be called when a download is paused. The argument + * is the download ID. + * + * @return true if the handler was successfully installed (there is as of now no known + * reason this should fail). + */ + virtual bool onDownloadPaused(const std::function& callback) = 0; + + /** + * @brief Installs a handler to be called when a download fails. + * + * @param callback The function to be called when a download fails. The argument is + * the download ID. + * + * @return true if the handler was successfully installed (there is as of now no known + * reason this should fail). + */ + virtual bool onDownloadFailed(const std::function& callback) = 0; + + /** + * @brief Installs a handler to be called when a download is removed. + * + * @param callback The function to be called when a download is removed. The argument + * is the download ID (which is no longer valid). + * + * @return true if the handler was successfully installed (there is as of now no known + * reason this should fail). + */ + virtual bool onDownloadRemoved(const std::function& callback) = 0; +}; + +} // namespace MOBase + +#endif // IDOWNLOADMANAGER_H diff --git a/src/ifiletree.cpp b/src/ifiletree.cpp index 882645f0..2ce32e05 100644 --- a/src/ifiletree.cpp +++ b/src/ifiletree.cpp @@ -4,781 +4,846 @@ #include // FileTreeEntry: -namespace MOBase { - FileTreeEntry::FileTreeEntry(std::shared_ptr parent, QString name) : - m_Parent(parent), m_Name(name) { } - - QString FileTreeEntry::suffix() const { - const qsizetype idx = m_Name.lastIndexOf("."); - return (isDir() || idx == -1) ? "" : m_Name.mid(idx + 1); - } +namespace MOBase +{ +FileTreeEntry::FileTreeEntry(std::shared_ptr parent, QString name) + : m_Parent(parent), m_Name(name) +{} + +QString FileTreeEntry::suffix() const +{ + const qsizetype idx = m_Name.lastIndexOf("."); + return (isDir() || idx == -1) ? "" : m_Name.mid(idx + 1); +} - bool FileTreeEntry::hasSuffix(QString suffix) const { - return this->suffix().compare(suffix, FileNameComparator::CaseSensitivity) == 0; - } +bool FileTreeEntry::hasSuffix(QString suffix) const +{ + return this->suffix().compare(suffix, FileNameComparator::CaseSensitivity) == 0; +} - bool FileTreeEntry::hasSuffix(QStringList suffixes) const { - return suffixes.contains(suffix(), FileNameComparator::CaseSensitivity); - } +bool FileTreeEntry::hasSuffix(QStringList suffixes) const +{ + return suffixes.contains(suffix(), FileNameComparator::CaseSensitivity); +} - QString FileTreeEntry::pathFrom(std::shared_ptr tree, QString sep) const { +QString FileTreeEntry::pathFrom(std::shared_ptr tree, + QString sep) const +{ - // We will construct the path from right to left: - QString path = name(); + // We will construct the path from right to left: + QString path = name(); - auto p = parent(); - while (p != nullptr && p != tree) { - // We need to check the parent, otherwize we are going to prepend the name - // and a / for the base, which we do not want. - if (p->parent() != nullptr) { - path = p->name() + sep + path; - } - p = p->parent(); + auto p = parent(); + while (p != nullptr && p != tree) { + // We need to check the parent, otherwize we are going to prepend the name + // and a / for the base, which we do not want. + if (p->parent() != nullptr) { + path = p->name() + sep + path; } - - return p == tree ? path : QString(); + p = p->parent(); } - bool FileTreeEntry::detach() { - auto p = parent(); - if (p == nullptr) { - return false; - } - return p->erase(shared_from_this()) != p->end(); - } + return p == tree ? path : QString(); +} - bool FileTreeEntry::moveTo(std::shared_ptr tree) { - return tree->insert(shared_from_this()) != tree->end(); +bool FileTreeEntry::detach() +{ + auto p = parent(); + if (p == nullptr) { + return false; } + return p->erase(shared_from_this()) != p->end(); +} - std::shared_ptr FileTreeEntry::clone() const { - return createFileEntry(nullptr, name()); - } +bool FileTreeEntry::moveTo(std::shared_ptr tree) +{ + return tree->insert(shared_from_this()) != tree->end(); +} - std::shared_ptr FileTreeEntry::createFileEntry(std::shared_ptr parent, QString name) { - return std::shared_ptr(new FileTreeEntry(parent, name)); - } +std::shared_ptr FileTreeEntry::clone() const +{ + return createFileEntry(nullptr, name()); } +std::shared_ptr +FileTreeEntry::createFileEntry(std::shared_ptr parent, QString name) +{ + return std::shared_ptr(new FileTreeEntry(parent, name)); +} +} // namespace MOBase + // IFileTree: -namespace MOBase { - - /** - * Comparator for file entries. - */ - struct FileEntryComparator { - bool operator()(std::shared_ptr const& a, std::shared_ptr const& b) const { - if (a->isDir() && !b->isDir()) { - return true; - } - else if (!a->isDir() && b->isDir()) { - return false; - } - else { - return FileNameComparator::compare(a->name(), b->name()) < 0; - } +namespace MOBase +{ + +/** + * Comparator for file entries. + */ +struct FileEntryComparator +{ + bool operator()(std::shared_ptr const& a, + std::shared_ptr const& b) const + { + if (a->isDir() && !b->isDir()) { + return true; + } else if (!a->isDir() && b->isDir()) { + return false; + } else { + return FileNameComparator::compare(a->name(), b->name()) < 0; } - }; + } +}; - /** - * @brief Comparator that can be used to find entry matching the given name and - * file type. - */ - struct MatchEntryComparator { +/** + * @brief Comparator that can be used to find entry matching the given name and + * file type. + */ +struct MatchEntryComparator +{ - MatchEntryComparator(QString const& name, FileTreeEntry::FileTypes matchTypes) : - m_Name(name), m_MatchTypes(matchTypes) { } + MatchEntryComparator(QString const& name, FileTreeEntry::FileTypes matchTypes) + : m_Name(name), m_MatchTypes(matchTypes) + {} - bool operator()(const std::shared_ptr& fileEntry) const { - return m_MatchTypes.testFlag(fileEntry->fileType()) && fileEntry->compare(m_Name) == 0; - } + bool operator()(const std::shared_ptr& fileEntry) const + { + return m_MatchTypes.testFlag(fileEntry->fileType()) && + fileEntry->compare(m_Name) == 0; + } - bool operator()(const std::shared_ptr& fileEntry) const { - return m_MatchTypes.testFlag(fileEntry->fileType()) && fileEntry->compare(m_Name) == 0; - } + bool operator()(const std::shared_ptr& fileEntry) const + { + return m_MatchTypes.testFlag(fileEntry->fileType()) && + fileEntry->compare(m_Name) == 0; + } - private: - QString const& m_Name; - FileTreeEntry::FileTypes m_MatchTypes; - }; +private: + QString const& m_Name; + FileTreeEntry::FileTypes m_MatchTypes; +}; +/** + * + */ +bool IFileTree::exists(QString path, FileTypes type) const +{ + return find(path, type) != nullptr; +} - /** - * - */ - bool IFileTree::exists(QString path, FileTypes type) const { return find(path, type) != nullptr; } +/** + * + */ +std::shared_ptr IFileTree::find(QString path, FileTypes type) +{ + return fetchEntry(splitPath(path), type); +} +std::shared_ptr IFileTree::find(QString path, FileTypes type) const +{ + return fetchEntry(splitPath(path), type); +} - /** - * - */ - std::shared_ptr IFileTree::find(QString path, FileTypes type) { - return fetchEntry(splitPath(path), type); - } - std::shared_ptr IFileTree::find(QString path, FileTypes type) const { - return fetchEntry(splitPath(path), type); - } +/** + * + */ +void IFileTree::walk( + std::function)> + callback, + QString sep) const +{ - /** - * - */ - void IFileTree::walk(std::function)> callback, QString sep) const { + std::stack>> stack; + // We start by pushing all the entries in this tree, this avoid having to do extra + // check later for avoid leading separator: + for (auto rit = rbegin(); rit != rend(); ++rit) { + stack.push({"", *rit}); + } - std::stack>> stack; + while (!stack.empty()) { + auto [path, entry] = stack.top(); + stack.pop(); - // We start by pushing all the entries in this tree, this avoid having to do extra check later - // for avoid leading separator: - for (auto rit = rbegin(); rit != rend(); ++rit) { - stack.push({ "", *rit }); + auto res = callback(path, entry); + if (res == WalkReturn::STOP) { + break; } - - while (!stack.empty()) { - auto [path, entry] = stack.top(); - stack.pop(); - - auto res = callback(path, entry); - if (res == WalkReturn::STOP) { - break; - } - if (entry->isDir() && res != WalkReturn::SKIP) { - auto tree = entry->astree(); - for (auto rit = tree->rbegin(); rit != tree->rend(); ++rit) { - stack.push({ path + tree->name() + sep, *rit }); - } + if (entry->isDir() && res != WalkReturn::SKIP) { + auto tree = entry->astree(); + for (auto rit = tree->rbegin(); rit != tree->rend(); ++rit) { + stack.push({path + tree->name() + sep, *rit}); } } } +} - /** - * - */ - std::shared_ptr IFileTree::addFile(QString path, bool replaceIfExists) { - QStringList parts = splitPath(path); - - // Check if the file already exists: - auto existingEntry = fetchEntry(parts, IFileTree::FILE_OR_DIRECTORY); - if (!replaceIfExists && existingEntry != nullptr) { - return nullptr; - } +/** + * + */ +std::shared_ptr IFileTree::addFile(QString path, bool replaceIfExists) +{ + QStringList parts = splitPath(path); - // Find or create the tree: - IFileTree* tree; + // Check if the file already exists: + auto existingEntry = fetchEntry(parts, IFileTree::FILE_OR_DIRECTORY); + if (!replaceIfExists && existingEntry != nullptr) { + return nullptr; + } - if (parts.size() > 1) { + // Find or create the tree: + IFileTree* tree; - // Create the tree: - std::shared_ptr treeEntry = createTree(parts.begin(), parts.end() - 1); + if (parts.size() > 1) { - // Early fail if the tree was not created: - if (treeEntry == nullptr) { - return nullptr; - } + // Create the tree: + std::shared_ptr treeEntry = + createTree(parts.begin(), parts.end() - 1); - tree = treeEntry->astree().get(); - } - else { - tree = this; - } - - std::shared_ptr entry = tree->makeFile(tree->astree(), parts[parts.size() - 1]); - - // If makeFile returns a null pointer, it means we cannot create file: - if (entry == nullptr) { + // Early fail if the tree was not created: + if (treeEntry == nullptr) { return nullptr; } - // Remove the existing files if there was one: - if (existingEntry) { - existingEntry->detach(); - } + tree = treeEntry->astree().get(); + } else { + tree = this; + } - // Insert in the tree: - tree->entries().insert( - std::upper_bound(tree->begin(), tree->end(), entry, FileEntryComparator{}), - entry - ); + std::shared_ptr entry = + tree->makeFile(tree->astree(), parts[parts.size() - 1]); - return entry; + // If makeFile returns a null pointer, it means we cannot create file: + if (entry == nullptr) { + return nullptr; } - /** - * - */ - std::shared_ptr IFileTree::addDirectory(QString path) { - QStringList parts = splitPath(path); - return createTree(parts.begin(), parts.end()); + // Remove the existing files if there was one: + if (existingEntry) { + existingEntry->detach(); } - /** - * - */ - IFileTree::iterator IFileTree::insert(std::shared_ptr entry, InsertPolicy insertPolicy) { + // Insert in the tree: + tree->entries().insert( + std::upper_bound(tree->begin(), tree->end(), entry, FileEntryComparator{}), + entry); - // Check that this is not the current tree or a parent tree: - if (entry->isDir()) { - std::shared_ptr tmp = astree(); - while (tmp != nullptr) { - if (tmp == entry->astree()) { - return end(); - } - tmp = tmp->parent(); + return entry; +} + +/** + * + */ +std::shared_ptr IFileTree::addDirectory(QString path) +{ + QStringList parts = splitPath(path); + return createTree(parts.begin(), parts.end()); +} + +/** + * + */ +IFileTree::iterator IFileTree::insert(std::shared_ptr entry, + InsertPolicy insertPolicy) +{ + + // Check that this is not the current tree or a parent tree: + if (entry->isDir()) { + std::shared_ptr tmp = astree(); + while (tmp != nullptr) { + if (tmp == entry->astree()) { + return end(); } + tmp = tmp->parent(); } + } - // Check if there exists an entry with the same name: - auto existingIt = std::find_if(begin(), end(), MatchEntryComparator{ entry->name(), FILE_OR_DIRECTORY }); + // Check if there exists an entry with the same name: + auto existingIt = std::find_if( + begin(), end(), MatchEntryComparator{entry->name(), FILE_OR_DIRECTORY}); - // Already in the tree? - if (existingIt != end() && *existingIt == entry) { - return existingIt; - } + // Already in the tree? + if (existingIt != end() && *existingIt == entry) { + return existingIt; + } - // Find the insertion iterator: - auto insertionIt = std::lower_bound(begin(), end(), entry, FileEntryComparator{}); + // Find the insertion iterator: + auto insertionIt = std::lower_bound(begin(), end(), entry, FileEntryComparator{}); - if (existingIt != end()) { - if (insertPolicy == InsertPolicy::FAIL_IF_EXISTS) { - return end(); - } + if (existingIt != end()) { + if (insertPolicy == InsertPolicy::FAIL_IF_EXISTS) { + return end(); + } - // We replace if the policy is REPLACE or if the new and old entry are - // both files: - if (insertPolicy == InsertPolicy::REPLACE - || ((*existingIt)->isFile() && entry->isFile())) { - if (beforeReplace(this, existingIt->get(), entry.get())) { - // Detach the old entry from its parent (not using .detach() - // to remove the entry since we are replacing it): - (*existingIt)->m_Parent.reset(); - entries().erase(existingIt); - insertionIt = entries().insert(insertionIt, entry); - } - else { - return end(); - } - } - // If we arrive here and one of the entry is a file, we fail: - else if ((*existingIt)->isFile() || entry->isFile()) { + // We replace if the policy is REPLACE or if the new and old entry are + // both files: + if (insertPolicy == InsertPolicy::REPLACE || + ((*existingIt)->isFile() && entry->isFile())) { + if (beforeReplace(this, existingIt->get(), entry.get())) { + // Detach the old entry from its parent (not using .detach() + // to remove the entry since we are replacing it): + (*existingIt)->m_Parent.reset(); + entries().erase(existingIt); + insertionIt = entries().insert(insertionIt, entry); + } else { return end(); } - else { - // If we end up here, we know that the policy is MERGE and that both - // are directory that can be merged: - mergeTree((*existingIt)->astree(), entry->astree(), nullptr); - insertionIt = existingIt; - } } - else if (beforeInsert(this, entry.get())) { - insertionIt = entries().insert(insertionIt, entry); - } - - // Remove the tree from its parent (parent() can be null if we are inserting - // a new tree): - if (entry->parent() != nullptr) { - entry->parent()->erase(entry); + // If we arrive here and one of the entry is a file, we fail: + else if ((*existingIt)->isFile() || entry->isFile()) { + return end(); + } else { + // If we end up here, we know that the policy is MERGE and that both + // are directory that can be merged: + mergeTree((*existingIt)->astree(), entry->astree(), nullptr); + insertionIt = existingIt; } + } else if (beforeInsert(this, entry.get())) { + insertionIt = entries().insert(insertionIt, entry); + } - // If the entry was actually inserted, we update its parent: - if (*insertionIt == entry) { - entry->m_Parent = astree(); - } - // Otherwize, we reset it (if this was a merge operation): - else { - entry->m_Parent.reset(); - } + // Remove the tree from its parent (parent() can be null if we are inserting + // a new tree): + if (entry->parent() != nullptr) { + entry->parent()->erase(entry); + } - return insertionIt; + // If the entry was actually inserted, we update its parent: + if (*insertionIt == entry) { + entry->m_Parent = astree(); } + // Otherwize, we reset it (if this was a merge operation): + else { + entry->m_Parent.reset(); + } + + return insertionIt; +} - /** - * - */ - bool IFileTree::move(std::shared_ptr entry, QString path, InsertPolicy insertPolicy) { +/** + * + */ +bool IFileTree::move(std::shared_ptr entry, QString path, + InsertPolicy insertPolicy) +{ - // Check that this is not a parent tree: - if (entry->isDir()) { - std::shared_ptr tmp = parent(); - while (tmp != nullptr) { - if (tmp == entry->astree()) { - return false; - } - tmp = tmp->parent(); + // Check that this is not a parent tree: + if (entry->isDir()) { + std::shared_ptr tmp = parent(); + while (tmp != nullptr) { + if (tmp == entry->astree()) { + return false; } + tmp = tmp->parent(); } + } - // Insert in folder or replace: - const bool insertFolder = path.isEmpty() || path.endsWith("/") || path.endsWith("\\"); - - // Retrieve the path: - QStringList parts = splitPath(path); - - // Backup the entry name (in case the insertion fails), and update the - // name: - QString entryName = entry->m_Name; - if (!insertFolder) { - entry->m_Name = parts.takeLast(); - } + // Insert in folder or replace: + const bool insertFolder = path.isEmpty() || path.endsWith("/") || path.endsWith("\\"); - // Find or create the tree: - IFileTree* tree; + // Retrieve the path: + QStringList parts = splitPath(path); - if (!parts.isEmpty()) { + // Backup the entry name (in case the insertion fails), and update the + // name: + QString entryName = entry->m_Name; + if (!insertFolder) { + entry->m_Name = parts.takeLast(); + } - // Create the tree: - std::shared_ptr treeEntry = createTree(parts.begin(), parts.end()); + // Find or create the tree: + IFileTree* tree; - // Early fail if the tree was not created: - if (treeEntry == nullptr) { - return false; - } + if (!parts.isEmpty()) { - tree = treeEntry->astree().get(); - } - else { - tree = this; - } + // Create the tree: + std::shared_ptr treeEntry = createTree(parts.begin(), parts.end()); - // We try to insert, and if it fails we need to reset the name: - auto it = tree->insert(entry, insertPolicy); - if (it == tree->end()) { - entry->m_Name = entryName; + // Early fail if the tree was not created: + if (treeEntry == nullptr) { return false; } - return true; + tree = treeEntry->astree().get(); + } else { + tree = this; } - /** - * - */ - std::shared_ptr IFileTree::copy(std::shared_ptr entry, QString path, InsertPolicy insertPolicy) { - // Note: If a conflict exists, the tree is cloned before checking the conflict, so this is not the - // most efficient way but copying tree should be pretty rare (and probably avoided anyway), and this - // allow us to use `move()` to do all the complex operations. - auto clone = entry->clone(); - if (move(clone, path, insertPolicy)) { - return clone; - } - return nullptr; + // We try to insert, and if it fails we need to reset the name: + auto it = tree->insert(entry, insertPolicy); + if (it == tree->end()) { + entry->m_Name = entryName; + return false; } - /** - * - */ - std::size_t IFileTree::merge(std::shared_ptr source, OverwritesType* overwrites) { + return true; +} - // Check that this is not a parent tree: - std::shared_ptr tmp = astree(); - while (tmp != nullptr) { - if (tmp == source) { - return MERGE_FAILED; - } - tmp = tmp->parent(); +/** + * + */ +std::shared_ptr +IFileTree::copy(std::shared_ptr entry, QString path, + InsertPolicy insertPolicy) +{ + // Note: If a conflict exists, the tree is cloned before checking the conflict, so + // this is not the most efficient way but copying tree should be pretty rare (and + // probably avoided anyway), and this allow us to use `move()` to do all the complex + // operations. + auto clone = entry->clone(); + if (move(clone, path, insertPolicy)) { + return clone; + } + return nullptr; +} + +/** + * + */ +std::size_t IFileTree::merge(std::shared_ptr source, + OverwritesType* overwrites) +{ + + // Check that this is not a parent tree: + std::shared_ptr tmp = astree(); + while (tmp != nullptr) { + if (tmp == source) { + return MERGE_FAILED; } + tmp = tmp->parent(); + } + + return mergeTree(astree(), source, overwrites); +} + +/** + * + */ +IFileTree::iterator IFileTree::erase(std::shared_ptr entry) +{ - return mergeTree(astree(), source, overwrites); + if (!beforeRemove(this, entry.get())) { + return end(); } - /** - * - */ - IFileTree::iterator IFileTree::erase(std::shared_ptr entry) { + auto it = std::find(begin(), end(), entry); + if (it == end()) { + return it; + } + entry->m_Parent.reset(); + return entries().erase(it); + ; +} - if (!beforeRemove(this, entry.get())) { - return end(); - } +/** + * + */ +std::pair> +IFileTree::erase(QString name) +{ + auto it = std::find_if(begin(), end(), [&name](const auto& entry) { + return entry->compare(name) == 0; + }); - auto it = std::find(begin(), end(), entry); - if (it == end()) { - return it; - } - entry->m_Parent.reset(); - return entries().erase(it);; + if (it == end()) { + return {it, nullptr}; } - /** - * - */ - std::pair> IFileTree::erase(QString name) { - auto it = std::find_if(begin(), end(), [&name](const auto& entry) { - return entry->compare(name) == 0; - }); + if (!beforeRemove(this, it->get())) { + return {end(), nullptr}; + } - if (it == end()) { - return { it, nullptr }; - } + // Save the entry to return it: + auto entry = *it; + entry->m_Parent.reset(); - if (!beforeRemove(this, it->get())) { - return { end(), nullptr }; - } + return {entries().erase(it), entry}; +} - // Save the entry to return it: - auto entry = *it; - entry->m_Parent.reset(); +/** + * + */ +bool IFileTree::clear() +{ + // Need to find the iterator up to which we should erase: + auto& entries_ = entries(); + auto it = entries_.begin(); + for (; it != entries_.end() && beforeRemove(this, it->get()); ++it) { + // Detach (but not remove from the vector): + (*it)->m_Parent.reset(); + } + entries_.erase(entries_.begin(), it); + return empty(); +} - return { entries().erase(it), entry }; - } +/** + * + */ +std::size_t IFileTree::removeAll(QStringList names) +{ + return removeIf([&names](auto& entry) { + return names.contains(entry->name(), Qt::CaseInsensitive); + }); +} - /** - * - */ - bool IFileTree::clear() { - // Need to find the iterator up to which we should erase: - auto& entries_ = entries(); - auto it = entries_.begin(); - for (; it != entries_.end() && beforeRemove(this, it->get()); ++it) { - // Detach (but not remove from the vector): - (*it)->m_Parent.reset(); - } - entries_.erase(entries_.begin(), it); - return empty(); - } - - /** - * - */ - std::size_t IFileTree::removeAll(QStringList names) { - return removeIf([&names](auto& entry) { - return names.contains(entry->name(), Qt::CaseInsensitive); }); - } - - /** - * - */ - std::size_t IFileTree::removeIf(std::function const&)> predicate) { - std::size_t osize = size(); - auto& en = entries(); - // Cannot use begin() and end() directly because those are immutable iterators: - en.erase(std::remove_if(en.begin(), en.end(), [this, &predicate](auto& entry) { - return beforeRemove(this, entry.get()) && predicate(entry); - }), en.end()); - return osize - size(); - } - - /** - * - */ - QStringList IFileTree::splitPath(QString path) { - // Using raw \\ instead of QDir::separator() since we are replacing by / - // anyway, and this avoid pulling an extra header (like QDir) only - // for the separator. - return path.replace("\\", "/").split("/", Qt::SkipEmptyParts); - } - - /** - * - */ - bool IFileTree::beforeReplace(IFileTree const*, FileTreeEntry const*, FileTreeEntry const*) { - return true; - } - - /** - * - */ - bool IFileTree::beforeInsert(IFileTree const*, FileTreeEntry const*) { - return true; - } - - /** - * - */ - bool IFileTree::beforeRemove(IFileTree const*, FileTreeEntry const*) { - return true; - } - - /** - * - */ - std::size_t IFileTree::mergeTree( - std::shared_ptr destination, std::shared_ptr source, OverwritesType* overwrites) { - - const auto comp = FileEntryComparator{}; - - // Number of overwritten entries: - std::size_t noverwrites = 0; - - // Note: Using the iterators from the vector directly since the other ones - // cannot be assigned to. - auto& dstEntries = destination->entries(), - & srcEntries = source->entries(); - - // Note: Since entries are not sorted by name but by type (file/directory) - // then name, there is no fast way to check for conflict. - for (auto& srcEntry : srcEntries) { - - // Try to find an exact match (name and type) - This iterator also - // serve to know where the entry should be inserted: - auto dstIt = std::lower_bound( - dstEntries.begin(), dstEntries.end(), srcEntry, comp); - - // Exact match found: - if (dstIt != dstEntries.end() - && (*dstIt)->compare(srcEntry->name()) == 0 - && (*dstIt)->isFile() == srcEntry->isFile()) { - - // Both directory, we merge: - if ((*dstIt)->isDir() && srcEntry->isDir()) { - noverwrites += mergeTree((*dstIt)->astree(), srcEntry->astree(), overwrites); - - // Detach the entry: - srcEntry->m_Parent.reset(); - } - // Otherwize, check if the source can replace the destination: - else if (beforeReplace(destination.get(), dstIt->get(), srcEntry.get())) { - // Remove the parent: - auto dstEntry = *dstIt; - dstEntry->m_Parent.reset(); - - // Update overwrites information: - noverwrites++; - if (overwrites != nullptr) { - overwrites->insert({ dstEntry, srcEntry }); - } - - // Replace the destination: - *dstIt = srcEntry; - srcEntry->m_Parent = destination; - } - // If not, fails: - else { - return MERGE_FAILED; +/** + * + */ +std::size_t IFileTree::removeIf( + std::function const&)> predicate) +{ + std::size_t osize = size(); + auto& en = entries(); + // Cannot use begin() and end() directly because those are immutable iterators: + en.erase(std::remove_if(en.begin(), en.end(), + [this, &predicate](auto& entry) { + return beforeRemove(this, entry.get()) && predicate(entry); + }), + en.end()); + return osize - size(); +} + +/** + * + */ +QStringList IFileTree::splitPath(QString path) +{ + // Using raw \\ instead of QDir::separator() since we are replacing by / + // anyway, and this avoid pulling an extra header (like QDir) only + // for the separator. + return path.replace("\\", "/").split("/", Qt::SkipEmptyParts); +} + +/** + * + */ +bool IFileTree::beforeReplace(IFileTree const*, FileTreeEntry const*, + FileTreeEntry const*) +{ + return true; +} + +/** + * + */ +bool IFileTree::beforeInsert(IFileTree const*, FileTreeEntry const*) +{ + return true; +} + +/** + * + */ +bool IFileTree::beforeRemove(IFileTree const*, FileTreeEntry const*) +{ + return true; +} + +/** + * + */ +std::size_t IFileTree::mergeTree(std::shared_ptr destination, + std::shared_ptr source, + OverwritesType* overwrites) +{ + + const auto comp = FileEntryComparator{}; + + // Number of overwritten entries: + std::size_t noverwrites = 0; + + // Note: Using the iterators from the vector directly since the other ones + // cannot be assigned to. + auto &dstEntries = destination->entries(), &srcEntries = source->entries(); + + // Note: Since entries are not sorted by name but by type (file/directory) + // then name, there is no fast way to check for conflict. + for (auto& srcEntry : srcEntries) { + + // Try to find an exact match (name and type) - This iterator also + // serve to know where the entry should be inserted: + auto dstIt = std::lower_bound(dstEntries.begin(), dstEntries.end(), srcEntry, comp); + + // Exact match found: + if (dstIt != dstEntries.end() && (*dstIt)->compare(srcEntry->name()) == 0 && + (*dstIt)->isFile() == srcEntry->isFile()) { + + // Both directory, we merge: + if ((*dstIt)->isDir() && srcEntry->isDir()) { + noverwrites += mergeTree((*dstIt)->astree(), srcEntry->astree(), overwrites); + + // Detach the entry: + srcEntry->m_Parent.reset(); + } + // Otherwize, check if the source can replace the destination: + else if (beforeReplace(destination.get(), dstIt->get(), srcEntry.get())) { + // Remove the parent: + auto dstEntry = *dstIt; + dstEntry->m_Parent.reset(); + + // Update overwrites information: + noverwrites++; + if (overwrites != nullptr) { + overwrites->insert({dstEntry, srcEntry}); } + + // Replace the destination: + *dstIt = srcEntry; + srcEntry->m_Parent = destination; } + // If not, fails: else { - // If we did not find a match, the only way to check is to look - // through the vector: - auto conflictIt = std::find_if(dstEntries.begin(), dstEntries.end(), [name = srcEntry->name()](auto const& dstEntry) { - return dstEntry->compare(name) == 0; - }); - - // Conflict (note that here both entries are of different types, so no need to - // check if we replace or merge): - int deleteIndex = -1; - if (conflictIt != dstEntries.end()) { - - // We check if we can replace the entry: - if (!beforeReplace(destination.get(), conflictIt->get(), srcEntry.get())) { - return MERGE_FAILED; - } - - // We need to store the index because the insert() will mess up the - // iterators: - deleteIndex = static_cast(conflictIt - std::begin(dstEntries)); - if (dstIt < conflictIt) { - deleteIndex += 1; - } - - // Detach the conflicting entry (we erase it later, after the insertion): - (*conflictIt)->m_Parent.reset(); - - // Update overwrites information: - noverwrites++; - if (overwrites != nullptr) { - overwrites->insert({ *conflictIt, srcEntry }); - } - } - // No conflict, we still have to check if we can insert: - else if (!beforeInsert(destination.get(), srcEntry.get())) { + return MERGE_FAILED; + } + } else { + // If we did not find a match, the only way to check is to look + // through the vector: + auto conflictIt = std::find_if(dstEntries.begin(), dstEntries.end(), + [name = srcEntry->name()](auto const& dstEntry) { + return dstEntry->compare(name) == 0; + }); + + // Conflict (note that here both entries are of different types, so no need to + // check if we replace or merge): + int deleteIndex = -1; + if (conflictIt != dstEntries.end()) { + + // We check if we can replace the entry: + if (!beforeReplace(destination.get(), conflictIt->get(), srcEntry.get())) { return MERGE_FAILED; } - // Insert the entry using the previous iterator: - dstEntries.insert(dstIt, srcEntry); - - // We delete here: - if (deleteIndex != -1) { - dstEntries.erase(dstEntries.begin() + deleteIndex); + // We need to store the index because the insert() will mess up the + // iterators: + deleteIndex = static_cast(conflictIt - std::begin(dstEntries)); + if (dstIt < conflictIt) { + deleteIndex += 1; } - // Update the parent: - srcEntry->m_Parent = destination; + // Detach the conflicting entry (we erase it later, after the insertion): + (*conflictIt)->m_Parent.reset(); + + // Update overwrites information: + noverwrites++; + if (overwrites != nullptr) { + overwrites->insert({*conflictIt, srcEntry}); + } + } + // No conflict, we still have to check if we can insert: + else if (!beforeInsert(destination.get(), srcEntry.get())) { + return MERGE_FAILED; } - } - // Clear the sources: - srcEntries.clear(); + // Insert the entry using the previous iterator: + dstEntries.insert(dstIt, srcEntry); - return noverwrites; - } + // We delete here: + if (deleteIndex != -1) { + dstEntries.erase(dstEntries.begin() + deleteIndex); + } - /** - * - */ - std::shared_ptr IFileTree::createOrphanTree(QString name) const { - auto directory = makeDirectory(nullptr, name); - if (directory != nullptr) { - directory->m_Populated = true; + // Update the parent: + srcEntry->m_Parent = destination; } - return directory; } - /** - * - */ - std::shared_ptr IFileTree::fetchEntry(QStringList path, FileTypes matchTypes) { - return std::const_pointer_cast(const_cast(this)->fetchEntry(path, matchTypes)); - } - std::shared_ptr IFileTree::fetchEntry(QStringList const& path, FileTypes matchTypes) const { - // Check to ensure that the path contains at least one element: - if (path.isEmpty()) { - return nullptr; - } + // Clear the sources: + srcEntries.clear(); - // Early check: - if (path[path.size() - 1].startsWith("*")) { - return nullptr; - } + return noverwrites; +} - const IFileTree* tree = this; - auto it = std::begin(path); - for (; tree != nullptr && it != std::end(path) - 1; ++it) { - // Special cases: - if (*it == ".") { - continue; - } - else if (*it == "..") { - tree = tree->parent().get(); - } - else { - // Find the entry at the current level: - auto entryIt = std::find_if(tree->begin(), tree->end(), MatchEntryComparator{ *it, IFileTree::DIRECTORY }); +/** + * + */ +std::shared_ptr IFileTree::createOrphanTree(QString name) const +{ + auto directory = makeDirectory(nullptr, name); + if (directory != nullptr) { + directory->m_Populated = true; + } + return directory; +} - // Early exists if the entry does not exist or is not a directory: - if (entryIt == tree->end()) { - tree = nullptr; - } - else { - tree = (*entryIt)->astree().get(); - } - } - } +/** + * + */ +std::shared_ptr IFileTree::fetchEntry(QStringList path, + FileTypes matchTypes) +{ + return std::const_pointer_cast( + const_cast(this)->fetchEntry(path, matchTypes)); +} +std::shared_ptr IFileTree::fetchEntry(QStringList const& path, + FileTypes matchTypes) const +{ + // Check to ensure that the path contains at least one element: + if (path.isEmpty()) { + return nullptr; + } - if (tree == nullptr) { - return nullptr; - } + // Early check: + if (path[path.size() - 1].startsWith("*")) { + return nullptr; + } - // We have the final tree: - auto entryIt = std::find_if(tree->begin(), tree->end(), MatchEntryComparator{ *it, matchTypes }); - auto bIt = tree->end(); - return entryIt == bIt ? nullptr : *entryIt; - } - - /** - * @brief Create a new file under this tree. - * - * @param parent The current tree, without const-qualification. - * @param name Name of the file. - * @param time Modification time of the file. - * - * @return the created file. - */ - std::shared_ptr IFileTree::makeFile(std::shared_ptr parent, QString name) const { - return createFileEntry(parent, name); - } - - /** - * - */ - IFileTree::IFileTree() { } - - /** - * - */ - std::shared_ptr IFileTree::clone() const { - std::shared_ptr tree = doClone(); - - // Don't copy not populated tree, it is not useful: - if (m_Populated) { - tree->m_Populated = true; - auto& tentries = tree->m_Entries; - for (auto e : entries()) { - auto ce = e->clone(); - ce->m_Parent = tree; - tentries.push_back(ce); + const IFileTree* tree = this; + auto it = std::begin(path); + for (; tree != nullptr && it != std::end(path) - 1; ++it) { + // Special cases: + if (*it == ".") { + continue; + } else if (*it == "..") { + tree = tree->parent().get(); + } else { + // Find the entry at the current level: + auto entryIt = std::find_if(tree->begin(), tree->end(), + MatchEntryComparator{*it, IFileTree::DIRECTORY}); + + // Early exists if the entry does not exist or is not a directory: + if (entryIt == tree->end()) { + tree = nullptr; + } else { + tree = (*entryIt)->astree().get(); } } + } - return tree; + if (tree == nullptr) { + return nullptr; } - /** - * - */ - std::shared_ptr IFileTree::createTree(QStringList::const_iterator begin, QStringList::const_iterator end) { - // The current tree and entry: - std::shared_ptr tree = astree(); - for (auto it = begin; tree != nullptr && it != end; ++it) { - // Special cases: - if (*it == ".") { - continue; - } - else if (*it == "..") { - // parent() returns nullptr if it does not exist, so no - // check required: - tree = parent(); - } - else { + // We have the final tree: + auto entryIt = + std::find_if(tree->begin(), tree->end(), MatchEntryComparator{*it, matchTypes}); + auto bIt = tree->end(); + return entryIt == bIt ? nullptr : *entryIt; +} - // Check if the entry exists (looking for both files and directories - // because we don't want to override a file): - auto entryIt = std::find_if(tree->begin(), tree->end(), MatchEntryComparator{ *it, IFileTree::FILE_OR_DIRECTORY }); +/** + * @brief Create a new file under this tree. + * + * @param parent The current tree, without const-qualification. + * @param name Name of the file. + * @param time Modification time of the file. + * + * @return the created file. + */ +std::shared_ptr +IFileTree::makeFile(std::shared_ptr parent, QString name) const +{ + return createFileEntry(parent, name); +} - // Create if it does not: - if (entryIt == tree->end()) { - auto newTree = tree->makeDirectory(tree, *it); +/** + * + */ +IFileTree::IFileTree() {} - // If makeDirectory returns a null pointer, it means we cannot create tree. - if (newTree == nullptr) { - tree = nullptr; - break; - } +/** + * + */ +std::shared_ptr IFileTree::clone() const +{ + std::shared_ptr tree = doClone(); - // The tree is empty so already populated: - newTree->m_Populated = true; + // Don't copy not populated tree, it is not useful: + if (m_Populated) { + tree->m_Populated = true; + auto& tentries = tree->m_Entries; + for (auto e : entries()) { + auto ce = e->clone(); + ce->m_Parent = tree; + tentries.push_back(ce); + } + } - tree->entries().insert( - std::upper_bound(tree->begin(), tree->end(), newTree, FileEntryComparator{}), - newTree - ); - tree = newTree; - } - else if ((*entryIt)->isDir()) { - tree = (*entryIt)->astree(); - } - else { // Cannot go further: + return tree; +} + +/** + * + */ +std::shared_ptr IFileTree::createTree(QStringList::const_iterator begin, + QStringList::const_iterator end) +{ + // The current tree and entry: + std::shared_ptr tree = astree(); + for (auto it = begin; tree != nullptr && it != end; ++it) { + // Special cases: + if (*it == ".") { + continue; + } else if (*it == "..") { + // parent() returns nullptr if it does not exist, so no + // check required: + tree = parent(); + } else { + + // Check if the entry exists (looking for both files and directories + // because we don't want to override a file): + auto entryIt = + std::find_if(tree->begin(), tree->end(), + MatchEntryComparator{*it, IFileTree::FILE_OR_DIRECTORY}); + + // Create if it does not: + if (entryIt == tree->end()) { + auto newTree = tree->makeDirectory(tree, *it); + + // If makeDirectory returns a null pointer, it means we cannot create tree. + if (newTree == nullptr) { tree = nullptr; + break; } + + // The tree is empty so already populated: + newTree->m_Populated = true; + + tree->entries().insert(std::upper_bound(tree->begin(), tree->end(), newTree, + FileEntryComparator{}), + newTree); + tree = newTree; + } else if ((*entryIt)->isDir()) { + tree = (*entryIt)->astree(); + } else { // Cannot go further: + tree = nullptr; } } - - return tree; } - /** - * @brief Retrieve the vector of entries after populating it if required. - * - * @return the vector of entries. - */ - std::vector>& IFileTree::entries() { - std::call_once(m_OnceFlag, [this]() { populate(); }); - return m_Entries; - } - const std::vector>& IFileTree::entries() const { - std::call_once(m_OnceFlag, [this]() { populate(); }); - return m_Entries; - } + return tree; +} - /** - * @brief Populate the internal vectors and update the flag. - */ - void IFileTree::populate() const { - // Need to check m_Populated again here since the tree can be populated without - // a call to entries() (e.g., on copy/orphanTree): - if (!m_Populated) { - if (!doPopulate(astree(), m_Entries)) { - std::sort(std::begin(m_Entries), std::end(m_Entries), FileEntryComparator{}); - } - m_Populated = true; +/** + * @brief Retrieve the vector of entries after populating it if required. + * + * @return the vector of entries. + */ +std::vector>& IFileTree::entries() +{ + std::call_once(m_OnceFlag, [this]() { + populate(); + }); + return m_Entries; +} +const std::vector>& IFileTree::entries() const +{ + std::call_once(m_OnceFlag, [this]() { + populate(); + }); + return m_Entries; +} + +/** + * @brief Populate the internal vectors and update the flag. + */ +void IFileTree::populate() const +{ + // Need to check m_Populated again here since the tree can be populated without + // a call to entries() (e.g., on copy/orphanTree): + if (!m_Populated) { + if (!doPopulate(astree(), m_Entries)) { + std::sort(std::begin(m_Entries), std::end(m_Entries), FileEntryComparator{}); } + m_Populated = true; } - } + +} // namespace MOBase diff --git a/src/ifiletree.h b/src/ifiletree.h index 8cc60334..bf06d1e3 100644 --- a/src/ifiletree.h +++ b/src/ifiletree.h @@ -22,21 +22,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #define IFILETREE_H #include -#include +#include #include #include #include +#include #include -#include #include -#include +#include #include +#include #include "dllimport.h" #include "utility.h" - /** * This header contains definition for the interface IFileTree and the FileTreeEntry * class. @@ -50,1036 +50,1071 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * use FileTreeEntry for something else, and the only way to create FileTreeEntry * is through an existing IFileTree. * - * IFileTree expose a mutable and a strict non-mutable interfaces based on const-qualification - * of methods, but all underlying implementation are obviously non-const. + * IFileTree expose a mutable and a strict non-mutable interfaces based on + * const-qualification of methods, but all underlying implementation are obviously + * non-const. * * The IFileTree interface is implemented such that creating implementations should * be fairly easy (two short methods to implement). Implementation can override other - * methods in order to reflect changes from the tree to the actual source (e.g., override - * the beforeX() methods to actually rename or move file on the disk). + * methods in order to reflect changes from the tree to the actual source (e.g., + * override the beforeX() methods to actually rename or move file on the disk). * */ -namespace MOBase { - - /** - * - */ - class IFileTree; - - /** - * @brief Simple valid C++ comparator for QString that compare them case-insensitive, - * mostly useful to compare filenames on Windows. - */ - struct FileNameComparator { +namespace MOBase +{ - /** - * @brief The case sensitivity of filenames. - */ - static constexpr auto CaseSensitivity = Qt::CaseInsensitive; - - /** - * @brief Compare the two given filenames. - * - * @param lhs, rhs Filenames to compare. - * - * @return -1, 0 or 1 if the first one is less, equal or greater than the second one. - */ - static int compare(QString const& lhs, QString const& rhs) { - return lhs.compare(rhs, CaseSensitivity); - } +/** + * + */ +class IFileTree; - /** - * - */ - bool operator()(QString const& a, QString const& b) const { - return compare(a, b) < 0; - } - }; +/** + * @brief Simple valid C++ comparator for QString that compare them case-insensitive, + * mostly useful to compare filenames on Windows. + */ +struct FileNameComparator +{ /** - * @brief Exception thrown when an operation on the tree is not supported by the - * implementation or makes no sense (e.g., creation of a file in an archive). + * @brief The case sensitivity of filenames. */ - struct QDLLEXPORT UnsupportedOperationException: public Exception { - using Exception::Exception; - }; + static constexpr auto CaseSensitivity = Qt::CaseInsensitive; /** - * @brief Represent an entry in a file tree, either a file or a directory. This class - * inherited by IFileTree so that operations on entry are the same for a file or - * a directory. + * @brief Compare the two given filenames. * - * This class provides convenience methods to query information on the file, like its - * name or the its last modification time. It also provides a convenience astree() method - * that can be used to retrieve the tree corresponding to its entry in case the entry - * represent a directory. + * @param lhs, rhs Filenames to compare. * + * @return -1, 0 or 1 if the first one is less, equal or greater than the second one. */ - class QDLLEXPORT FileTreeEntry : public std::enable_shared_from_this { - - public: // Enums + static int compare(QString const& lhs, QString const& rhs) + { + return lhs.compare(rhs, CaseSensitivity); + } - /** - * @brief Enumeration of the different file type. - * - */ - enum FileType { - DIRECTORY = 0b01, - FILE = 0b10 - }; - Q_DECLARE_FLAGS(FileTypes, FileType); + /** + * + */ + bool operator()(QString const& a, QString const& b) const + { + return compare(a, b) < 0; + } +}; - constexpr static auto FILE_OR_DIRECTORY = FileTypes{ DIRECTORY, FILE }; +/** + * @brief Exception thrown when an operation on the tree is not supported by the + * implementation or makes no sense (e.g., creation of a file in an archive). + */ +struct QDLLEXPORT UnsupportedOperationException : public Exception +{ + using Exception::Exception; +}; - public: // Deleted operators: +/** + * @brief Represent an entry in a file tree, either a file or a directory. This class + * inherited by IFileTree so that operations on entry are the same for a file or + * a directory. + * + * This class provides convenience methods to query information on the file, like its + * name or the its last modification time. It also provides a convenience astree() + * method that can be used to retrieve the tree corresponding to its entry in case the + * entry represent a directory. + * + */ +class QDLLEXPORT FileTreeEntry : public std::enable_shared_from_this +{ - FileTreeEntry(FileTreeEntry const&) = delete; - FileTreeEntry(FileTreeEntry&&) = delete; +public: // Enums + /** + * @brief Enumeration of the different file type. + * + */ + enum FileType + { + DIRECTORY = 0b01, + FILE = 0b10 + }; + Q_DECLARE_FLAGS(FileTypes, FileType); - FileTreeEntry& operator=(FileTreeEntry const&) = delete; - FileTreeEntry& operator=(FileTreeEntry&&) = delete; + constexpr static auto FILE_OR_DIRECTORY = FileTypes{DIRECTORY, FILE}; - public: // Methods +public: // Deleted operators: + FileTreeEntry(FileTreeEntry const&) = delete; + FileTreeEntry(FileTreeEntry&&) = delete; - /** - * @brief Check if this entry is a file. - * - * @return true if this entry is a file, false otherwize. - */ - bool isFile() const { - return astree() == nullptr; - } + FileTreeEntry& operator=(FileTreeEntry const&) = delete; + FileTreeEntry& operator=(FileTreeEntry&&) = delete; - /** - * @brief Check if this entry is a directory. - * - * @return true if this entry is a directory, false otherwize. - */ - bool isDir() const { - return astree() != nullptr; - } +public: // Methods + /** + * @brief Check if this entry is a file. + * + * @return true if this entry is a file, false otherwize. + */ + bool isFile() const { return astree() == nullptr; } - /** - * @brief Convert this entry to a tree. This method returns a null pointer - * if this entry corresponds to a file. - * - * @return this entry as a tree, or a null pointer if isDir() is false. - */ - virtual std::shared_ptr astree() { - return nullptr; - } + /** + * @brief Check if this entry is a directory. + * + * @return true if this entry is a directory, false otherwize. + */ + bool isDir() const { return astree() != nullptr; } - /** - * @brief Convert this entry to a tree. This method returns a null pointer - * if this entry corresponds to a file. - * - * @return this entry as a tree, or a null pointer if isDir() is false. - */ - virtual std::shared_ptr astree() const { - return nullptr; - } + /** + * @brief Convert this entry to a tree. This method returns a null pointer + * if this entry corresponds to a file. + * + * @return this entry as a tree, or a null pointer if isDir() is false. + */ + virtual std::shared_ptr astree() { return nullptr; } - /** - * @brief Retrieve the type of this entry. - * - * @return the type of this entry. - */ - FileType fileType() const { - return isDir() ? DIRECTORY : FILE; - } + /** + * @brief Convert this entry to a tree. This method returns a null pointer + * if this entry corresponds to a file. + * + * @return this entry as a tree, or a null pointer if isDir() is false. + */ + virtual std::shared_ptr astree() const { return nullptr; } - /** - * @brief Retrieve the name of this entry. - * - * @return the name of this entry. - */ - QString name() const { - return m_Name; - } + /** + * @brief Retrieve the type of this entry. + * + * @return the type of this entry. + */ + FileType fileType() const { return isDir() ? DIRECTORY : FILE; } - /** - * @brief Compare the name of this entry against the given string. - * - * This method only checks the name of the entry, not the full path. - * - * @param name Name to test. - * - * @return -1, 0 or 1 depending on the result of the comparison. - */ - int compare(QString name) const { - return FileNameComparator::compare(m_Name, name); - } + /** + * @brief Retrieve the name of this entry. + * + * @return the name of this entry. + */ + QString name() const { return m_Name; } - /** - * @brief Retrieve the "last" extension of this entry. - * - * The "last" extension is everything after the last dot in the file name. - * - * @return the last extension of this entry, or an empty string if the file has no - * extension or is directory. - */ - QString suffix() const; + /** + * @brief Compare the name of this entry against the given string. + * + * This method only checks the name of the entry, not the full path. + * + * @param name Name to test. + * + * @return -1, 0 or 1 depending on the result of the comparison. + */ + int compare(QString name) const { return FileNameComparator::compare(m_Name, name); } - /** - * @brief Check if this entry has the given suffix. - * - * @param suffix Suffix of to check. - * - * @return true if this entry is a file and has the given suffix. - */ - bool hasSuffix(QString suffix) const; + /** + * @brief Retrieve the "last" extension of this entry. + * + * The "last" extension is everything after the last dot in the file name. + * + * @return the last extension of this entry, or an empty string if the file has no + * extension or is directory. + */ + QString suffix() const; - /** - * @brief Check if this entry has one of the given suffixes. - * - * @param suffixes Suffixes of to check. - * - * @return true if this entry is a file and has the given suffix. - */ - bool hasSuffix(QStringList suffixes) const; + /** + * @brief Check if this entry has the given suffix. + * + * @param suffix Suffix of to check. + * + * @return true if this entry is a file and has the given suffix. + */ + bool hasSuffix(QString suffix) const; - /** - * @brief Retrieve the path from this entry up to the root of the tree. - * - * This method propagate up the tree so is not constant complexity as - * the full path is never stored. - * - * @param sep The type of separator to use to create the path. - * - * @return the path from this entry to the root, including the name - * of this entry. - */ - QString path(QString sep = "\\") const { - return pathFrom(nullptr, sep); - } + /** + * @brief Check if this entry has one of the given suffixes. + * + * @param suffixes Suffixes of to check. + * + * @return true if this entry is a file and has the given suffix. + */ + bool hasSuffix(QStringList suffixes) const; - /** - * @brief Retrieve the path from this entry to the given tree. - * - * @param tree The tree to reach, must be a parent of this entry. - * @param sep The type of separator to use to create the path. - * - * @return the path from this entry up to the given tree, including the name - * of this entry, or QString() if the given tree is not a parent of - * this one. - */ - QString pathFrom(std::shared_ptr tree, QString sep = "\\") const; + /** + * @brief Retrieve the path from this entry up to the root of the tree. + * + * This method propagate up the tree so is not constant complexity as + * the full path is never stored. + * + * @param sep The type of separator to use to create the path. + * + * @return the path from this entry to the root, including the name + * of this entry. + */ + QString path(QString sep = "\\") const { return pathFrom(nullptr, sep); } - /** - * @brief Detach this entry from its parent tree. - * - * @return true if the entry was removed correctly, false otherwize. - */ - bool detach(); + /** + * @brief Retrieve the path from this entry to the given tree. + * + * @param tree The tree to reach, must be a parent of this entry. + * @param sep The type of separator to use to create the path. + * + * @return the path from this entry up to the given tree, including the name + * of this entry, or QString() if the given tree is not a parent of + * this one. + */ + QString pathFrom(std::shared_ptr tree, QString sep = "\\") const; - /** - * @brief Move this entry to the given tree. - * - * @param tree The tree to move this entry to. - * - * @return true if the entry was moved correctly, false otherwize. - */ - bool moveTo(std::shared_ptr tree); + /** + * @brief Detach this entry from its parent tree. + * + * @return true if the entry was removed correctly, false otherwize. + */ + bool detach(); - /** - * @brief Retrieve the immediate parent tree of this entry. - * - * @return the parent tree containing this entry, or a null pointer - * if this entry is the root or the parent tree is unreachable. - */ - std::shared_ptr parent() { - return std::const_pointer_cast(const_cast(this)->parent()); - } + /** + * @brief Move this entry to the given tree. + * + * @param tree The tree to move this entry to. + * + * @return true if the entry was moved correctly, false otherwize. + */ + bool moveTo(std::shared_ptr tree); - /** - * @brief Retrieve the immediate parent tree of this entry. - * - * @return the parent tree containing this entry, or a null pointer - * if this entry is the root or the parent tree is unreachable. - */ - std::shared_ptr parent() const { - return m_Parent.lock(); - } + /** + * @brief Retrieve the immediate parent tree of this entry. + * + * @return the parent tree containing this entry, or a null pointer + * if this entry is the root or the parent tree is unreachable. + */ + std::shared_ptr parent() + { + return std::const_pointer_cast( + const_cast(this)->parent()); + } - public: // Destructor: + /** + * @brief Retrieve the immediate parent tree of this entry. + * + * @return the parent tree containing this entry, or a null pointer + * if this entry is the root or the parent tree is unreachable. + */ + std::shared_ptr parent() const { return m_Parent.lock(); } - virtual ~FileTreeEntry() { } +public: // Destructor: + virtual ~FileTreeEntry() {} - protected: // Constructors: +protected: // Constructors: + /** + * @brief Create a new entry corresponding. + * + * @param parent The tree containing this entry. + * @param name The name of this entry. + */ + FileTreeEntry(std::shared_ptr parent, QString name); - /** - * @brief Create a new entry corresponding. - * - * @param parent The tree containing this entry. - * @param name The name of this entry. - */ - FileTreeEntry(std::shared_ptr parent, QString name); + /** + * @brief Creates a new orphan entry identical to this entry. + * + */ + virtual std::shared_ptr clone() const; - /** - * @brief Creates a new orphan entry identical to this entry. - * - */ - virtual std::shared_ptr clone() const; + /** + * @brief Creates a new FileTreeEntry corresponding to a file with the given + * parameters. + * + * The purpose of this methods is to allow child classes corresponding to tree (i.e., + * that do not inherit directly FileTreeEntry) to create FileTreeEntry. + * + * @param parent The tree containing this file. + * @param name The name of this file. + */ + static std::shared_ptr + createFileEntry(std::shared_ptr parent, QString name); - /** - * @brief Creates a new FileTreeEntry corresponding to a file with the given parameters. - * - * The purpose of this methods is to allow child classes corresponding to tree (i.e., that do - * not inherit directly FileTreeEntry) to create FileTreeEntry. - * - * @param parent The tree containing this file. - * @param name The name of this file. - */ - static std::shared_ptr createFileEntry(std::shared_ptr parent, QString name); +private: + std::weak_ptr m_Parent; - private: + QString m_Name; - std::weak_ptr m_Parent; + friend class IFileTree; +}; - QString m_Name; +Q_DECLARE_OPERATORS_FOR_FLAGS(FileTreeEntry::FileTypes); - friend class IFileTree; +/** + * @brief Interface to classes that provides way to visualize and alter file trees. The + * tree may not correspond to an actual file tree on the disk (e.g., inside an archive, + * from a QTree Widget, ...). + * + * This interface already implements most of the usual methods for a file tree. Child + * classes only have to implement methods to populate the tree and to create child tree + * object. + * + * Read-only operations on the tree are thread-safe, even when the tree has not been + * populated yet. + * + * In order to prevent wrong usage of the tree, implementing classes may throw + * UnsupportedOperationException if an operation is not supported. By default, all + * operations are supported, but some may not make sense in many situations. + * + * The goal of this is not reflect the change made to a IFileTree to the disk, but child + * classes may override relevant methods to do so. + * + * The tree is built upon FileTreeEntry. A given tree holds shared pointers to its + * entries while each entry holds a weak pointer to its parent, this means that the + * descending link are strong (shared pointers) but the uplink are weaks. + * + * Accessing the parent is always done by locking the weak pointer so that returned + * pointer or either null or valid. This structure implies that as long as the initial + * root lives, entry should not be destroyed, unless the entry are detached from the + * root and no shared pointers are kept. + * + * However, it is not guarantee that one can go up the tree from a single node entry. If + * the root node is destroyed, it will not be possible to go up the tree, even if we + * still have a valid shared pointer. + * + * The inheritance is made virtual to provide a way for child classes to use both a + * custom FileTreeEntry and IFileTree implementations. This has no impact on the usage + * of the interface. + * + */ +class QDLLEXPORT IFileTree : public virtual FileTreeEntry +{ +public: // Enumerations and aliases: + /** + * + */ + enum class InsertPolicy + { + FAIL_IF_EXISTS, + REPLACE, + MERGE }; - Q_DECLARE_OPERATORS_FOR_FLAGS(FileTreeEntry::FileTypes); + /** + * @brief Special constant returns by merge when the merge failed. + */ + constexpr static std::size_t MERGE_FAILED = (std::size_t)-1; /** - * @brief Interface to classes that provides way to visualize and alter file trees. The tree - * may not correspond to an actual file tree on the disk (e.g., inside an archive, - * from a QTree Widget, ...). - * - * This interface already implements most of the usual methods for a file tree. Child - * classes only have to implement methods to populate the tree and to create child tree - * object. - * - * Read-only operations on the tree are thread-safe, even when the tree has not been populated - * yet. - * - * In order to prevent wrong usage of the tree, implementing classes may throw - * UnsupportedOperationException if an operation is not supported. By default, all operations - * are supported, but some may not make sense in many situations. - * - * The goal of this is not reflect the change made to a IFileTree to the disk, but child - * classes may override relevant methods to do so. - * - * The tree is built upon FileTreeEntry. A given tree holds shared pointers to its entries - * while each entry holds a weak pointer to its parent, this means that the descending link - * are strong (shared pointers) but the uplink are weaks. * - * Accessing the parent is always done by locking the weak pointer so that returned pointer - * or either null or valid. This structure implies that as long as the initial root lives, - * entry should not be destroyed, unless the entry are detached from the root and no shared - * pointers are kept. - * - * However, it is not guarantee that one can go up the tree from a single node entry. If the - * root node is destroyed, it will not be possible to go up the tree, even if we still have - * a valid shared pointer. - * - * The inheritance is made virtual to provide a way for child classes to use both a custom - * FileTreeEntry and IFileTree implementations. This has no impact on the usage of the interface. + */ + using OverwritesType = std::map, + std::shared_ptr>; + +public: // Iterators: + /** + * The standard iterator are constant, but the pointed value are not. Since + * we are storing a vector of shared pointer to non-const object, we need this + * wrapper to create iterators to shared pointer of const-object to have proper + * immutability when IFileTree is const-qualified. * + * Note: convert_iterator satisfies std::forward_iterator concept but not + * ForwardIterator since dereferencing does not return an lvalue. */ - class QDLLEXPORT IFileTree : public virtual FileTreeEntry { - public: // Enumerations and aliases: + template + struct convert_iterator + { + + using reference = U; + using difference_type = typename V::difference_type; + using value_type = U; + using pointer = U; + using iterator_category = typename V::iterator_category; + + friend bool operator==(convert_iterator a, convert_iterator b) + { + return a.v == b.v; + } + friend bool operator!=(convert_iterator a, convert_iterator b) + { + return a.v != b.v; + } - /** - * - */ - enum class InsertPolicy { - FAIL_IF_EXISTS, - REPLACE, - MERGE - }; + reference operator*() const { return U(*v); } + reference operator->() const { return U(*v); } - /** - * @brief Special constant returns by merge when the merge failed. - */ - constexpr static std::size_t MERGE_FAILED = (std::size_t) -1; + convert_iterator& operator++() + { + v++; + return *this; + } - /** - * - */ - using OverwritesType = std::map, std::shared_ptr>; + convert_iterator operator++(int) + { + value_type value = *(*this); + (*this)++; + return *this; + } - public: // Iterators: + public: + convert_iterator() = default; + convert_iterator(convert_iterator const&) = default; + convert_iterator(convert_iterator&&) = default; + convert_iterator& operator=(convert_iterator const&) = default; + convert_iterator& operator=(convert_iterator&&) = default; - /** - * The standard iterator are constant, but the pointed value are not. Since - * we are storing a vector of shared pointer to non-const object, we need this - * wrapper to create iterators to shared pointer of const-object to have proper - * immutability when IFileTree is const-qualified. - * - * Note: convert_iterator satisfies InputIterator but not ForwardIterator since - * dereferencing it does not return a reference, even if it can likely be used - * exactly in the same way since it returns a pointer-like type (U is a shared - * pointer). - */ - template - struct convert_iterator { - - using reference = U; - using difference_type = typename V::difference_type; - using value_type = U; - using pointer = U; - using iterator_category = typename V::iterator_category; - - friend bool operator==(convert_iterator a, convert_iterator b) { return a.v == b.v; } - friend bool operator!=(convert_iterator a, convert_iterator b) { return a.v != b.v; } - - reference operator*() const { return U(*v); } - reference operator->() const { return U(*v); } - - convert_iterator& operator++() { - v++; - return *this; - } - - value_type operator++(int) { - value_type value = *(*this); - (*this)++; - return *this; - } - - protected: - V v; - - convert_iterator(V v) : v{ v } { - } - friend class IFileTree; - }; - - using value_type = std::shared_ptr; - using reference = std::shared_ptr; - using const_reference = std::shared_ptr; - - using iterator = std::vector>::const_iterator; - using const_iterator = convert_iterator< - std::shared_ptr, - std::vector>::const_iterator>; + protected: + V v; - using reverse_iterator = std::vector>::const_reverse_iterator; - using const_reverse_iterator = convert_iterator< - std::shared_ptr, - std::vector>::const_reverse_iterator>; + convert_iterator(V v) : v{v} {} + friend class IFileTree; + }; - public: // Access methods: + using value_type = std::shared_ptr; + using reference = std::shared_ptr; + using const_reference = std::shared_ptr; - /** - * - */ - iterator begin() { return { std::cbegin(entries()) }; }; - const_iterator begin() const { return { std::cbegin(entries()) }; }; - const_iterator cbegin() const { return { std::cbegin(entries()) }; }; - - /** - * - */ - reverse_iterator rbegin() { return { std::crbegin(entries()) }; }; - const_reverse_iterator rbegin() const { return { std::crbegin(entries()) }; }; - const_reverse_iterator crbegin() const { return { std::crbegin(entries()) }; }; + using iterator = std::vector>::const_iterator; + using const_iterator = + convert_iterator, + std::vector>::const_iterator>; - /** - * - */ - iterator end() { return { std::cend(entries()) }; }; - const_iterator end() const { return { std::cend(entries()) }; }; - const_iterator cend() const { return { std::cend(entries()) }; }; + using reverse_iterator = + std::vector>::const_reverse_iterator; + using const_reverse_iterator = convert_iterator< + std::shared_ptr, + std::vector>::const_reverse_iterator>; - /** - * - */ - reverse_iterator rend() { return { std::crend(entries()) }; }; - const_reverse_iterator rend() const { return { std::crend(entries()) }; }; - const_reverse_iterator crend() const { return { std::crend(entries()) }; }; +#if __cplusplus > 201703L + static_assert(std::forward_iterator); + static_assert(std::forward_iterator); + static_assert(std::forward_iterator); + static_assert(std::forward_iterator); +#endif - /** - * @brief Retrieve the number of entries in this tree. - * - * This is constant if the tree has already been populated. - * - * @return the number of entries in this tree. - */ - std::size_t size() const { - return entries().size(); - } +public: // Access methods: + /** + * + */ + iterator begin() { return {std::cbegin(entries())}; } + const_iterator begin() const { return {std::cbegin(entries())}; } + const_iterator cbegin() const { return {std::cbegin(entries())}; } - /** - * @brief Retrieve the file entry at the given index. - * - * @param i Index of the entry to retrieve. - * - * @return the file entry at the given index. - * - * @throw std::out_of_range if the index is invalid. - */ - std::shared_ptr at(std::size_t i) { - if (i < size()) { - return entries()[i]; - } - throw std::out_of_range("IFileTree::at"); - } - std::shared_ptr at(std::size_t i) const { - if (i < size()) { - return entries()[i]; - } - throw std::out_of_range("IFileTree::at"); - } + /** + * + */ + reverse_iterator rbegin() { return {std::crbegin(entries())}; } + const_reverse_iterator rbegin() const { return {std::crbegin(entries())}; } + const_reverse_iterator crbegin() const { return {std::crbegin(entries())}; } - /** - * @brief Check if this tree is empty, i.e., if it contains no entries. - * - * @return true if the tree is empty, false otherwize. - */ - bool empty() const { - return size() == 0; - } + /** + * + */ + iterator end() { return {std::cend(entries())}; } + const_iterator end() const { return {std::cend(entries())}; } + const_iterator cend() const { return {std::cend(entries())}; } - /** - * @brief Check if the given entry exists. - * - * @param path Path to the entry, separated by / or \. - * @param type The type of the entry to check. - * - * @return true if the entry was found, false otherwize. - */ - bool exists(QString path, FileTreeEntry::FileTypes type = FileTreeEntry::FILE_OR_DIRECTORY) const; + /** + * + */ + reverse_iterator rend() { return {std::crend(entries())}; } + const_reverse_iterator rend() const { return {std::crend(entries())}; } + const_reverse_iterator crend() const { return {std::crend(entries())}; } - /** - * @brief Retrieve the given entry. - * - * If an entry is found at the given path but does not match the given type, - * a null pointer is returned. - * - * @param path Path to the entry, separated by / or \. - * @param type The type of the entry to find. - * - * @return the entry if found, a null pointer otherwize. - */ - std::shared_ptr find(QString path, FileTypes type = FILE_OR_DIRECTORY); - std::shared_ptr find(QString path, FileTypes type = FILE_OR_DIRECTORY) const; + /** + * @brief Retrieve the number of entries in this tree. + * + * This is constant if the tree has already been populated. + * + * @return the number of entries in this tree. + */ + std::size_t size() const { return entries().size(); } - /** - * @brief Convenient method around find() that returns IFileTree instead of entries. - * - * @param path Path to the directory, separated by / or \. - * - * @return the directory if found, a null pointer otherwize. - */ - std::shared_ptr findDirectory(QString path) { - auto entry = find(path, DIRECTORY); - return (entry != nullptr && entry->isDir()) ? entry->astree() : nullptr; - } - std::shared_ptr findDirectory(QString path) const { - auto entry = find(path, DIRECTORY); - return (entry != nullptr && entry->isDir()) ? entry->astree() : nullptr; + /** + * @brief Retrieve the file entry at the given index. + * + * @param i Index of the entry to retrieve. + * + * @return the file entry at the given index. + * + * @throw std::out_of_range if the index is invalid. + */ + std::shared_ptr at(std::size_t i) + { + if (i < size()) { + return entries()[i]; } - - /** - * @brief Retrieve the path from this tree to the given entry. - * - * @param entry The entry to reach, must be in this tree. - * @param sep The type of separator to use to create the path. - * - * @return the path from this tree to the given entry, including the name - * of the entry, or QString() if the given entry is not in this tree. - */ - QString pathTo(std::shared_ptr entry, QString sep = "\\") const { - return entry->pathFrom(astree()); + throw std::out_of_range("IFileTree::at"); + } + std::shared_ptr at(std::size_t i) const + { + if (i < size()) { + return entries()[i]; } + throw std::out_of_range("IFileTree::at"); + } - public: // Walk operations + /** + * @brief Check if this tree is empty, i.e., if it contains no entries. + * + * @return true if the tree is empty, false otherwize. + */ + bool empty() const { return size() == 0; } - enum class WalkReturn { + /** + * @brief Check if the given entry exists. + * + * @param path Path to the entry, separated by / or \. + * @param type The type of the entry to check. + * + * @return true if the entry was found, false otherwize. + */ + bool exists(QString path, + FileTreeEntry::FileTypes type = FileTreeEntry::FILE_OR_DIRECTORY) const; - /** - * @brief Continue walking normally. - */ - CONTINUE, + /** + * @brief Retrieve the given entry. + * + * If an entry is found at the given path but does not match the given type, + * a null pointer is returned. + * + * @param path Path to the entry, separated by / or \. + * @param type The type of the entry to find. + * + * @return the entry if found, a null pointer otherwize. + */ + std::shared_ptr find(QString path, FileTypes type = FILE_OR_DIRECTORY); + std::shared_ptr find(QString path, + FileTypes type = FILE_OR_DIRECTORY) const; - /** - * @brief Stop walking normally. - */ - STOP, + /** + * @brief Convenient method around find() that returns IFileTree instead of entries. + * + * @param path Path to the directory, separated by / or \. + * + * @return the directory if found, a null pointer otherwize. + */ + std::shared_ptr findDirectory(QString path) + { + auto entry = find(path, DIRECTORY); + return (entry != nullptr && entry->isDir()) ? entry->astree() : nullptr; + } + std::shared_ptr findDirectory(QString path) const + { + auto entry = find(path, DIRECTORY); + return (entry != nullptr && entry->isDir()) ? entry->astree() : nullptr; + } - /** - * @brief Skip this folder (no effect if the entry is a file). - */ - SKIP + /** + * @brief Retrieve the path from this tree to the given entry. + * + * @param entry The entry to reach, must be in this tree. + * @param sep The type of separator to use to create the path. + * + * @return the path from this tree to the given entry, including the name + * of the entry, or QString() if the given entry is not in this tree. + */ + QString pathTo(std::shared_ptr entry, QString sep = "\\") const + { + return entry->pathFrom(astree()); + } - }; +public: // Walk operations + enum class WalkReturn + { /** - * @brief Walk this tree, calling the given function for each entry in it. - * - * The given callback will be called with two parameters: the path from this tree to the given entry - * (with a trailing separator, not including the entry name), and the actual entry. The method returns - * a `WalkReturn` object to indicates what to do. - * - * During the walk, parent tree are guaranteed to be visited before their childrens. The given function - * is never called with the current tree. - * - * @param callback Method to call for each entry in the tree. + * @brief Continue walking normally. */ - void walk(std::function)> callback, QString sep = "\\") const; - - public: // Utility functions: + CONTINUE, /** - * @brief Create a new orphan empty tree. - * - * @param name Name of the tree. - * - * @return a new tree without any parent. + * @brief Stop walking normally. */ - std::shared_ptr createOrphanTree(QString name = "") const; - - public: // Mutable operations: + STOP, /** - * @brief Create a new file directly under this tree. - * - * This method will return a null pointer if the file already exists and if - * replaceIfExists is false. This method invalidates iterators to this tree and - * all the subtrees present in the given path. - * - * @param name Name of the file. - * @param replaceIfExists If true and an entry already exists at the given path, - * it will be replaced by a new entry. This will replace both files and - * directories. - * - * @return the entry corresponding to the create file, or a null - * pointer if the file was not created. + * @brief Skip this folder (no effect if the entry is a file). */ - virtual std::shared_ptr addFile(QString path, bool replaceIfExists = false); + SKIP - /** - * @brief Create a new directory tree under this tree. - * - * This method will create missing folders in the given path and will - * not fail if the directory already exists but will fail if the given - * path contains "." or "..". - * This method invalidates iterators to this tree and all the subtrees - * present in the given path. - * - * @param path Path to the directory. - * - * @return the entry corresponding to the created directory, or a null - * pointer if the directory was not created. - */ - virtual std::shared_ptr addDirectory(QString path); + }; - /** - * @brief Insert the given entry in this tree, removing it from its - * previouis parent. - * - * The entry must not be this tree or a parent entry of this tree. - * - * - If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry - * with the same name already exists. - * - If the policy is REPLACE, an existing entry will be replaced by the given entry. - * - If MERGE: - * - If there is no entry with the same name, the new entry is inserted. - * - If there is an entry with the same name: - * - If both entries are files, the old file is replaced by the given entry. - * - If both entries are directories, a merge is performed as if using merge(). - * - Otherwize the insertion fails (two entries with different types). - * - * This method invalidates iterator to this tree, to the parent tree of the given - * entry, and to subtrees of this tree if the insert policy is MERGE. - * - * @param entry Entry to insert. - * @param insertPolicy Policy to use on conflict. - * - * @return an iterator to the inserted tree if it was inserted or if it - * already existed, or the end iterator if insertPolicy is FAIL_IF_EXISTS - * and an entry with the same name already exists. - */ - iterator insert(std::shared_ptr entry, InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); + /** + * @brief Walk this tree, calling the given function for each entry in it. + * + * The given callback will be called with two parameters: the path from this tree to + * the given entry (with a trailing separator, not including the entry name), and the + * actual entry. The method returns a `WalkReturn` object to indicates what to do. + * + * During the walk, parent tree are guaranteed to be visited before their childrens. + * The given function is never called with the current tree. + * + * @param callback Method to call for each entry in the tree. + */ + void + walk(std::function)> + callback, + QString sep = "\\") const; - /** - * @brief Merge the given tree with this tree, i.e., insert all entries - * of the given tree into this tree. - * - * The tree must not be this tree or a parent entry of this tree. Files present in both tree - * will be replaced by files in the given tree. The overwrites parameter can - * be used to track the replaced files. After a merge, the source tree will be - * empty but still attached to its parent. - * - * Note that the merge process makes no distinction between files and directories - * when merging: if a directory is present in this tree and a file from source - * is in conflict with it, the tree will be removed and the file inserted; if a file - * is in this tree and a directory from source is in conflict with it, the file will - * be replaced with the directory. - * - * This method invalidates iterators to this tree, all the subtrees under this tree - * present in the given path, and all the subtrees of the given source. - * - * @param source Tree to merge. - * @param overwrites If not null, can be used to create a mapping from - * overriden file to new files. - * - * @return the number of overwritten entries, or MERGE_FAILED if the merge - * failed (e.g. because the source is a parent of this tree). - */ - std::size_t merge(std::shared_ptr source, OverwritesType *overwrites = nullptr); +public: // Utility functions: + /** + * @brief Create a new orphan empty tree. + * + * @param name Name of the tree. + * + * @return a new tree without any parent. + */ + std::shared_ptr createOrphanTree(QString name = "") const; - /** - * @brief Move the given entry to the given path under this tree. - * - * The entry must not be a parent tree of this tree. This method can also be used - * to rename entries. - * - * If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry - * at the same location already exists. If the policy is REPLACE, an existing - * entry will be replaced. If MERGE, the entry will be merged with the existing - * one (if the entry is a file, and a file exists, the file will be replaced). - * - * This method invalidates iterator to this tree, to the parent tree of the given - * entry, and to subtrees of this tree if the insert policy is MERGE. - * - * @param entry Entry to insert. - * @param path The path to move the entry to. If the path ends with / or \, - * the entry will be inserted in the corresponding directory instead of replacing - * it. If the given path is empty (`""`), this is equivalent to `insert()`. - * @param insertPolicy Policy to use on conflict. - * - * @return true if the entry was moved correctly, false otherwize. - */ - bool move(std::shared_ptr entry, QString path = "", InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); +public: // Mutable operations: + /** + * @brief Create a new file directly under this tree. + * + * This method will return a null pointer if the file already exists and if + * replaceIfExists is false. This method invalidates iterators to this tree and + * all the subtrees present in the given path. + * + * @param name Name of the file. + * @param replaceIfExists If true and an entry already exists at the given path, + * it will be replaced by a new entry. This will replace both files and + * directories. + * + * @return the entry corresponding to the create file, or a null + * pointer if the file was not created. + */ + virtual std::shared_ptr addFile(QString path, + bool replaceIfExists = false); - /** - * @brief Copy the given entry to the given path under this tree. - * - * The entry must not be a parent tree of this tree. - * - * If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry - * at the same location already exists. If the policy is REPLACE, an existing - * entry will be replaced. If MERGE, the entry will be merged with the existing - * one (if the entry is a file, and a file exists, the file will be replaced). - * - * This method invalidates iterator to this tree and to subtrees of this tree if - * the insert policy is MERGE. The given entry is left untouched - * - * @param entry Entry to copy. - * @param path The path to copy the entry to. If the path ends with / or \, - * the entry will be inserted in the corresponding directory instead of replacing - * it. - * @param insertPolicy Policy to use on conflict. - * - * @return the copy of the entry if it was copied correctly, a null pointer otherwise. - */ - std::shared_ptr copy(std::shared_ptr entry, QString path = "", InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); + /** + * @brief Create a new directory tree under this tree. + * + * This method will create missing folders in the given path and will + * not fail if the directory already exists but will fail if the given + * path contains "." or "..". + * This method invalidates iterators to this tree and all the subtrees + * present in the given path. + * + * @param path Path to the directory. + * + * @return the entry corresponding to the created directory, or a null + * pointer if the directory was not created. + */ + virtual std::shared_ptr addDirectory(QString path); - /** - * @brief Delete the given entry. - * - * @param entry Entry to delete. The entry must belongs to this tree (and - * not to a subtree). - * - * @return an iterator following the removed entry (might be the end - * iterator if the entry was not found or was the last). - */ - iterator erase(std::shared_ptr entry); + /** + * @brief Insert the given entry in this tree, removing it from its + * previouis parent. + * + * The entry must not be this tree or a parent entry of this tree. + * + * - If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry + * with the same name already exists. + * - If the policy is REPLACE, an existing entry will be replaced by the given entry. + * - If MERGE: + * - If there is no entry with the same name, the new entry is inserted. + * - If there is an entry with the same name: + * - If both entries are files, the old file is replaced by the given entry. + * - If both entries are directories, a merge is performed as if using merge(). + * - Otherwize the insertion fails (two entries with different types). + * + * This method invalidates iterator to this tree, to the parent tree of the given + * entry, and to subtrees of this tree if the insert policy is MERGE. + * + * @param entry Entry to insert. + * @param insertPolicy Policy to use on conflict. + * + * @return an iterator to the inserted tree if it was inserted or if it + * already existed, or the end iterator if insertPolicy is FAIL_IF_EXISTS + * and an entry with the same name already exists. + */ + iterator insert(std::shared_ptr entry, + InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); - /** - * @brief Delete the entry with the given name. - * - * This method does not recurse into subtrees, so the entry should be - * accessible directly from this tree. - * - * @param name Name of the entry to delete. - * - * @return a pair containing an iterator following the removed entry (might - * be the end iterator if the entry was not found or was the last) and - * the removed entry (or a null pointer if the entry was not found). - */ - std::pair> erase(QString name); + /** + * @brief Merge the given tree with this tree, i.e., insert all entries + * of the given tree into this tree. + * + * The tree must not be this tree or a parent entry of this tree. Files present in + * both tree will be replaced by files in the given tree. The overwrites parameter can + * be used to track the replaced files. After a merge, the source tree will be + * empty but still attached to its parent. + * + * Note that the merge process makes no distinction between files and directories + * when merging: if a directory is present in this tree and a file from source + * is in conflict with it, the tree will be removed and the file inserted; if a file + * is in this tree and a directory from source is in conflict with it, the file will + * be replaced with the directory. + * + * This method invalidates iterators to this tree, all the subtrees under this tree + * present in the given path, and all the subtrees of the given source. + * + * @param source Tree to merge. + * @param overwrites If not null, can be used to create a mapping from + * overriden file to new files. + * + * @return the number of overwritten entries, or MERGE_FAILED if the merge + * failed (e.g. because the source is a parent of this tree). + */ + std::size_t merge(std::shared_ptr source, + OverwritesType* overwrites = nullptr); - /** - * @brief Delete (detach) all the entries from this tree - * - * This method will go through the entries in this tree and stop at the first - * entry that cannot be deleted, this means that the tree can be partially cleared. - * - * @return true if all entries could be deleted, false otherwize. - */ - bool clear(); + /** + * @brief Move the given entry to the given path under this tree. + * + * The entry must not be a parent tree of this tree. This method can also be used + * to rename entries. + * + * If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry + * at the same location already exists. If the policy is REPLACE, an existing + * entry will be replaced. If MERGE, the entry will be merged with the existing + * one (if the entry is a file, and a file exists, the file will be replaced). + * + * This method invalidates iterator to this tree, to the parent tree of the given + * entry, and to subtrees of this tree if the insert policy is MERGE. + * + * @param entry Entry to insert. + * @param path The path to move the entry to. If the path ends with / or \, + * the entry will be inserted in the corresponding directory instead of replacing + * it. If the given path is empty (`""`), this is equivalent to `insert()`. + * @param insertPolicy Policy to use on conflict. + * + * @return true if the entry was moved correctly, false otherwize. + */ + bool move(std::shared_ptr entry, QString path = "", + InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); - /** - * @brief Delete the entries with the given names from the tree. - * - * This method does not recurse into subtrees, so the entry should be - * accessible directly from this tree. This method invalidates iterators. - * - * @param names Names of the entries to delete. - * - * @return the number of deleted entry. - */ - std::size_t removeAll(QStringList names); + /** + * @brief Copy the given entry to the given path under this tree. + * + * The entry must not be a parent tree of this tree. + * + * If the insert policy if FAIL_IF_EXISTS, the call will fail if an entry + * at the same location already exists. If the policy is REPLACE, an existing + * entry will be replaced. If MERGE, the entry will be merged with the existing + * one (if the entry is a file, and a file exists, the file will be replaced). + * + * This method invalidates iterator to this tree and to subtrees of this tree if + * the insert policy is MERGE. The given entry is left untouched + * + * @param entry Entry to copy. + * @param path The path to copy the entry to. If the path ends with / or \, + * the entry will be inserted in the corresponding directory instead of replacing + * it. + * @param insertPolicy Policy to use on conflict. + * + * @return the copy of the entry if it was copied correctly, a null pointer otherwise. + */ + std::shared_ptr + copy(std::shared_ptr entry, QString path = "", + InsertPolicy insertPolicy = InsertPolicy::FAIL_IF_EXISTS); - /** - * @brief Delete the entries that match the given predicate from the tree. - * - * This method does not recurse into subtrees, so the entry should be - * accessible directly from this tree. This method invalidates iterators. - * - * @param predicate Predicate that should return true for entries to delete. - * - * @return the number of deleted entry. - */ - std::size_t removeIf(std::function const& entry)> predicate); + /** + * @brief Delete the given entry. + * + * @param entry Entry to delete. The entry must belongs to this tree (and + * not to a subtree). + * + * @return an iterator following the removed entry (might be the end + * iterator if the entry was not found or was the last). + */ + iterator erase(std::shared_ptr entry); - public: // Inherited methods: + /** + * @brief Delete the entry with the given name. + * + * This method does not recurse into subtrees, so the entry should be + * accessible directly from this tree. + * + * @param name Name of the entry to delete. + * + * @return a pair containing an iterator following the removed entry (might + * be the end iterator if the entry was not found or was the last) and + * the removed entry (or a null pointer if the entry was not found). + */ + std::pair> erase(QString name); - /** - * @brief Retrieve the tree corresponding to this entry. Returns a null pointer - * if this entry corresponds to a file. - * - * @return the tree corresponding to this entry, or a null pointer if - * isDir() is false. - */ - virtual std::shared_ptr astree() override { - return std::dynamic_pointer_cast(shared_from_this()); - } + /** + * @brief Delete (detach) all the entries from this tree + * + * This method will go through the entries in this tree and stop at the first + * entry that cannot be deleted, this means that the tree can be partially cleared. + * + * @return true if all entries could be deleted, false otherwize. + */ + bool clear(); - /** - * @brief Retrieve the tree corresponding to this entry. Returns a null pointer - * if this entry corresponds to a file. - * - * @return the tree corresponding to this entry, or a null pointer if - * isDir() is false. - */ - virtual std::shared_ptr astree() const override { - return std::dynamic_pointer_cast(shared_from_this()); - } + /** + * @brief Delete the entries with the given names from the tree. + * + * This method does not recurse into subtrees, so the entry should be + * accessible directly from this tree. This method invalidates iterators. + * + * @param names Names of the entries to delete. + * + * @return the number of deleted entry. + */ + std::size_t removeAll(QStringList names); - public: // Destructor: + /** + * @brief Delete the entries that match the given predicate from the tree. + * + * This method does not recurse into subtrees, so the entry should be + * accessible directly from this tree. This method invalidates iterators. + * + * @param predicate Predicate that should return true for entries to delete. + * + * @return the number of deleted entry. + */ + std::size_t + removeIf(std::function const& entry)> predicate); - virtual ~IFileTree() { - } +public: // Inherited methods: + /** + * @brief Retrieve the tree corresponding to this entry. Returns a null pointer + * if this entry corresponds to a file. + * + * @return the tree corresponding to this entry, or a null pointer if + * isDir() is false. + */ + virtual std::shared_ptr astree() override + { + return std::dynamic_pointer_cast(shared_from_this()); + } - public: // Deleted operators: + /** + * @brief Retrieve the tree corresponding to this entry. Returns a null pointer + * if this entry corresponds to a file. + * + * @return the tree corresponding to this entry, or a null pointer if + * isDir() is false. + */ + virtual std::shared_ptr astree() const override + { + return std::dynamic_pointer_cast(shared_from_this()); + } + +public: // Destructor: + virtual ~IFileTree() {} - IFileTree(IFileTree const&) = delete; - IFileTree(IFileTree&&) = delete; +public: // Deleted operators: + IFileTree(IFileTree const&) = delete; + IFileTree(IFileTree&&) = delete; - IFileTree& operator=(IFileTree const&) = delete; - IFileTree& operator=(IFileTree&&) = delete; + IFileTree& operator=(IFileTree const&) = delete; + IFileTree& operator=(IFileTree&&) = delete; /** - * A few implementation details here for implementing classes. While there are multiple - * virtual public methods, most implementation should not have to re-implement them. + * A few implementation details here for implementing classes. While there are + * multiple virtual public methods, most implementation should not have to + * re-implement them. * - * There are three pure virtual methods that needs to be implemented by any child class: - * - makeDirectory(): used to create directories - this method serves to create directory - * that may or may not existing in the underlying source. Implementing class do not - * have to rely on this for `doPopulate()`. This method is also called when new - * directory needs to be created (addDirectory, insert, createOrphanTree, merge, etc.), - * and may return a null pointer to indicate that the operations failed or is not permitted. - * - doClone(): called when a tree needs to be cloned (e.g., for a copy) - this methods does - * not copy the subtrees, it should only create an empty tree equivalent to the current tree. + * There are three pure virtual methods that needs to be implemented by any child + * class: + * - makeDirectory(): used to create directories - this method serves to create + * directory that may or may not existing in the underlying source. Implementing class + * do not have to rely on this for `doPopulate()`. This method is also called when new + * directory needs to be created (addDirectory, insert, createOrphanTree, + * merge, etc.), and may return a null pointer to indicate that the operations failed + * or is not permitted. + * - doClone(): called when a tree needs to be cloned (e.g., for a copy) - this + * methods does not copy the subtrees, it should only create an empty tree equivalent + * to the current tree. * - doPopulate(): called when a tree have to be populated. * * The other commons methods that can be re-implemented are: - * - makeFile(), this is used to create new file - this is very similar to makeDirectory() - * except that it has a default implementation that simply creates a FileTreeEntry. - * - beforeInsert(), beforeReplace() and beforeRemove(): these can be implemented to 1) prevent - * some operations, 2) perform operations on the actual tree (e.g., move a file on the disk). + * - makeFile(), this is used to create new file - this is very similar to + * makeDirectory() except that it has a default implementation that simply creates a + * FileTreeEntry. + * - beforeInsert(), beforeReplace() and beforeRemove(): these can be implemented to + * 1) prevent some operations, 2) perform operations on the actual tree (e.g., move a + * file on the disk). */ - protected: - - friend class FileTreeEntry; +protected: + friend class FileTreeEntry; - /** - * Split the given path into parts. - * - * @param path The path to split. - * - * @return a list containing the section of the path. - */ - static QStringList splitPath(QString path); - - /** - * @brief Called before replacing an entry with another one. - * - * This is a pre-method meaning that it can be used to prevent an operation on - * the tree. - * - * This method is for internal usage only and is called when an entry is going to - * be replaced by another (because there is name conflict). - * - * The base implementation of this method does nothing (the actual replacement is - * made elsewhere). This method can be used to prevent a replacement by returning - * false. - * - * @param dstTree Tree containing the destination entry. - * @param destination Entry that will be replaced. - * @param source Entry that will replace the destination. - * - * @return true if the entry can be replaced, false otherwize. - */ - virtual bool beforeReplace( - IFileTree const* dstTree, FileTreeEntry const* destination, FileTreeEntry const* source); - - /** - * @brief Called before inserting an entry in a tree. - * - * This is a pre-method meaning that it can be used to prevent an operation on - * the tree. - * - * This method is for internal usage only and is called when an entry is going to - * be inserted in a tree. This method is not called after makeFile() or makeDirectory() - * so those should be used to prevent creation of files and directories. - * - * The base implementation of this method does nothing (the actual insertion is - * made elsewhere). This method can be used to prevent an insertion by returning - * false. - * - * @param tree Tree into which the entry will be inserted. - * @param source Entry that will be inserted the destination. - * - * @return true if the entry can be inserted, false otherwize. - */ - virtual bool beforeInsert(IFileTree const* entry, FileTreeEntry const* name); + /** + * Split the given path into parts. + * + * @param path The path to split. + * + * @return a list containing the section of the path. + */ + static QStringList splitPath(QString path); - /** - * @brief Called before removing an entry. - * - * This is a pre-method meaning that it can be used to prevent an operation on - * the tree. - * - * This method is for internal usage only and is called when an entry is going to - * be removed from a tree. - * - * The base implementation of this method does nothing (the actual removal is - * made elsewhere). This method can be used to prevent it by returning false. - * - * @param tree Tree containing the entry. - * @param entry Entry that will be removed. - * - * @return true if the entry can be removed, false otherwize. - */ - virtual bool beforeRemove(IFileTree const* entry, FileTreeEntry const* name); + /** + * @brief Called before replacing an entry with another one. + * + * This is a pre-method meaning that it can be used to prevent an operation on + * the tree. + * + * This method is for internal usage only and is called when an entry is going to + * be replaced by another (because there is name conflict). + * + * The base implementation of this method does nothing (the actual replacement is + * made elsewhere). This method can be used to prevent a replacement by returning + * false. + * + * @param dstTree Tree containing the destination entry. + * @param destination Entry that will be replaced. + * @param source Entry that will replace the destination. + * + * @return true if the entry can be replaced, false otherwize. + */ + virtual bool beforeReplace(IFileTree const* dstTree, FileTreeEntry const* destination, + FileTreeEntry const* source); - /** - * @brief Create a new file under this tree. - * - * @param parent The current tree, without const-qualification. - * @param name Name of the file. - * - * @return the created file. - */ - virtual std::shared_ptr makeFile(std::shared_ptr parent, QString name) const; + /** + * @brief Called before inserting an entry in a tree. + * + * This is a pre-method meaning that it can be used to prevent an operation on + * the tree. + * + * This method is for internal usage only and is called when an entry is going to + * be inserted in a tree. This method is not called after makeFile() or + * makeDirectory() so those should be used to prevent creation of files and + * directories. + * + * The base implementation of this method does nothing (the actual insertion is + * made elsewhere). This method can be used to prevent an insertion by returning + * false. + * + * @param tree Tree into which the entry will be inserted. + * @param source Entry that will be inserted the destination. + * + * @return true if the entry can be inserted, false otherwize. + */ + virtual bool beforeInsert(IFileTree const* entry, FileTreeEntry const* name); - /** - * @brief Create a new entry corresponding to a subtree under this tree. - * - * @param parent The current tree, without const-qualification. - * @param name Name of the directory. - * - * @return the entry for the created directory. - */ - virtual std::shared_ptr makeDirectory(std::shared_ptr parent, QString name) const = 0; + /** + * @brief Called before removing an entry. + * + * This is a pre-method meaning that it can be used to prevent an operation on + * the tree. + * + * This method is for internal usage only and is called when an entry is going to + * be removed from a tree. + * + * The base implementation of this method does nothing (the actual removal is + * made elsewhere). This method can be used to prevent it by returning false. + * + * @param tree Tree containing the entry. + * @param entry Entry that will be removed. + * + * @return true if the entry can be removed, false otherwize. + */ + virtual bool beforeRemove(IFileTree const* entry, FileTreeEntry const* name); - /** - * @brief Method that child classes should implement. - * - * This method should populate the given entries of this tree by using the makeFile and makeTree method. The - * usage of the makeFile and makeTree method is not mandatory here. - * - * If the implementation can populate the vector of entries in order, it is possible to return false to - * tell IFileTree not to re-sort the vector. If sorted, directories should be before files, and both directories - * and files should be sorted by name in a case-insensitive way. - * - * @param parent The current tree, without const-qualification. - * @param entries Vector of entries to populate. - * - * @return true if the vector of entries is already sorted, false if it must be sorted. - */ - virtual bool doPopulate(std::shared_ptr parent, std::vector>& entries) const = 0; + /** + * @brief Create a new file under this tree. + * + * @param parent The current tree, without const-qualification. + * @param name Name of the file. + * + * @return the created file. + */ + virtual std::shared_ptr + makeFile(std::shared_ptr parent, QString name) const; - /** - * @brief Creates a copy of this file tree. - * - * This methods is called by clone() in order to copy child class attributes. This method should basically - * returns a new copy of the tree with the attributes added by the implementation copied (and nothing else). - * - * @return the cloned tree. - */ - virtual std::shared_ptr doClone() const = 0; + /** + * @brief Create a new entry corresponding to a subtree under this tree. + * + * @param parent The current tree, without const-qualification. + * @param name Name of the directory. + * + * @return the entry for the created directory. + */ + virtual std::shared_ptr + makeDirectory(std::shared_ptr parent, QString name) const = 0; - protected: // Constructor + /** + * @brief Method that child classes should implement. + * + * This method should populate the given entries of this tree by using the makeFile + * and makeTree method. The usage of the makeFile and makeTree method is not mandatory + * here. + * + * If the implementation can populate the vector of entries in order, it is possible + * to return false to tell IFileTree not to re-sort the vector. If sorted, directories + * should be before files, and both directories and files should be sorted by name in + * a case-insensitive way. + * + * @param parent The current tree, without const-qualification. + * @param entries Vector of entries to populate. + * + * @return true if the vector of entries is already sorted, false if it must be + * sorted. + */ + virtual bool + doPopulate(std::shared_ptr parent, + std::vector>& entries) const = 0; - /** - * @brief Creates a new tree. This method takes no parameter since, due to the virtual inheritance, - * child classes must directly call the FileTreeEntry constructor. - */ - IFileTree(); + /** + * @brief Creates a copy of this file tree. + * + * This methods is called by clone() in order to copy child class attributes. This + * method should basically returns a new copy of the tree with the attributes added by + * the implementation copied (and nothing else). + * + * @return the cloned tree. + */ + virtual std::shared_ptr doClone() const = 0; - /** - * - */ - std::shared_ptr clone() const override; +protected: // Constructor + /** + * @brief Creates a new tree. This method takes no parameter since, due to the virtual + * inheritance, child classes must directly call the FileTreeEntry constructor. + */ + IFileTree(); /** * */ - private: // Private stuff, look away! + std::shared_ptr clone() const override; - /** - * @brief Retrieve the entry corresponding to the given path. - * - * @param path Path to entry. - * @param matchType Type of file to check. - * - * @return the entry, or a null pointer if the entry did not exist. - */ - std::shared_ptr fetchEntry(QStringList path, FileTypes matchType); - std::shared_ptr fetchEntry(QStringList const& path, FileTypes matchType) const; + /** + * + */ +private: // Private stuff, look away! + /** + * @brief Retrieve the entry corresponding to the given path. + * + * @param path Path to entry. + * @param matchType Type of file to check. + * + * @return the entry, or a null pointer if the entry did not exist. + */ + std::shared_ptr fetchEntry(QStringList path, FileTypes matchType); + std::shared_ptr fetchEntry(QStringList const& path, + FileTypes matchType) const; - /** - * @brief Merge the source tree into the destination tree. On conflict, the source entries are always chosen. - * - * @param destination Destination tree. - * @param source Source tree. - * - * @return the number of overwritten entries. - */ - std::size_t mergeTree( - std::shared_ptr destination, std::shared_ptr source, OverwritesType* overwrites); + /** + * @brief Merge the source tree into the destination tree. On conflict, the source + * entries are always chosen. + * + * @param destination Destination tree. + * @param source Source tree. + * + * @return the number of overwritten entries. + */ + std::size_t mergeTree(std::shared_ptr destination, + std::shared_ptr source, OverwritesType* overwrites); - /** - * @brief Create a new subtree under the given tree. - * - * This method will create missing folders in the given path and will not fail if the directory - * already exists but will fail the given path contains "." or "..". - * - * @param begin, end Range of section of the path. - * - * @return the entry corresponding to the create tree, or a null pointer if the tree was not created. - */ - std::shared_ptr createTree(QStringList::const_iterator begin, QStringList::const_iterator end); + /** + * @brief Create a new subtree under the given tree. + * + * This method will create missing folders in the given path and will not fail if the + * directory already exists but will fail the given path contains "." or "..". + * + * @param begin, end Range of section of the path. + * + * @return the entry corresponding to the create tree, or a null pointer if the tree + * was not created. + */ + std::shared_ptr createTree(QStringList::const_iterator begin, + QStringList::const_iterator end); - // Indicate if this tree has been populated: - mutable std::atomic m_Populated{ false }; - mutable std::once_flag m_OnceFlag; - mutable std::vector> m_Entries; + // Indicate if this tree has been populated: + mutable std::atomic m_Populated{false}; + mutable std::once_flag m_OnceFlag; + mutable std::vector> m_Entries; - /** - * @brief Retrieve the vector of entries after populating it if required. - * - * @return the vector of entries. - */ - std::vector>& entries(); - const std::vector>& entries() const; + /** + * @brief Retrieve the vector of entries after populating it if required. + * + * @return the vector of entries. + */ + std::vector>& entries(); + const std::vector>& entries() const; - /** - * @brief Populate the internal vectors and update the flag. - */ - void populate() const; - }; + /** + * @brief Populate the internal vectors and update the flag. + */ + void populate() const; +}; -} +} // namespace MOBase #endif diff --git a/src/iinstallationmanager.h b/src/iinstallationmanager.h index a6f74098..ef02b294 100644 --- a/src/iinstallationmanager.h +++ b/src/iinstallationmanager.h @@ -18,29 +18,28 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef IINSTALLATIONMANAGER_H #define IINSTALLATIONMANAGER_H #include #include -#include "iplugininstaller.h" #include "ifiletree.h" +#include "iplugininstaller.h" -namespace MOBase { - - -template class GuessedValue; +namespace MOBase +{ +template +class GuessedValue; /** * @brief The IInstallationManager class. */ -class IInstallationManager { +class IInstallationManager +{ public: - virtual ~IInstallationManager() {} /** @@ -65,10 +64,12 @@ class IInstallationManager { * @note The temporary file is automatically cleaned up after the installation. * @note This call can be very slow if the archive is large and "solid". */ - virtual QString extractFile(std::shared_ptr entry, bool silent = false) = 0; + virtual QString extractFile(std::shared_ptr entry, + bool silent = false) = 0; /** - * @brief Extract the specified files from the currently opened archive to a temporary location. + * @brief Extract the specified files from the currently opened archive to a temporary + * location. * * @param entres Entries corresponding to the files to extract. * @param silent If true, the dialog showing extraction progress will not be shown. @@ -82,24 +83,29 @@ class IInstallationManager { * @note The temporary file is automatically cleaned up after the installation. * @note This call can be very slow if the archive is large and "solid". * - * The flatten argument is not present here while it is present in the deprecated QStringList - * version for multiple reasons: 1) it was never used, 2) it is kind of fishy because there - * is no way to know if a file is going to be overriden, 3) it is quite easy to flatten a - * IFileTree and thus to given a list of entries flattened (this was not possible with the - * QStringList version since these were based on the name of the file inside the archive). + * The flatten argument is not present here while it is present in the deprecated + * QStringList version for multiple reasons: 1) it was never used, 2) it is kind of + * fishy because there is no way to know if a file is going to be overriden, 3) it is + * quite easy to flatten a IFileTree and thus to given a list of entries flattened + * (this was not possible with the QStringList version since these were based on the + * name of the file inside the archive). */ - virtual QStringList extractFiles(std::vector> const& entries, bool silent = false) = 0; + virtual QStringList + extractFiles(std::vector> const& entries, + bool silent = false) = 0; /** * @brief Create a new file on the disk corresponding to the given entry. * - * This method can be used by installer that needs to create files that are not in the original - * archive. At the end of the installation, if there are entries in the final tree that were used - * to create files, the corresponding files will be moved to the mod folder. + * This method can be used by installer that needs to create files that are not in the + * original archive. At the end of the installation, if there are entries in the final + * tree that were used to create files, the corresponding files will be moved to the + * mod folder. * * @param entry The entry for which a temporary file should be created. * - * @return the path to the created file, or an empty QString() if the file could not be created. + * @return the path to the created file, or an empty QString() if the file could not + * be created. */ virtual QString createFile(std::shared_ptr entry) = 0; @@ -112,10 +118,11 @@ class IInstallationManager { * * @return the installation result. */ - virtual IPluginInstaller::EInstallResult installArchive(MOBase::GuessedValue &modName, const QString &archiveFile, int modID = 0) = 0; - + virtual IPluginInstaller::EInstallResult + installArchive(MOBase::GuessedValue& modName, const QString& archiveFile, + int modID = 0) = 0; }; -} // namespace MOBase +} // namespace MOBase -#endif // IINSTALLATIONMANAGER_H +#endif // IINSTALLATIONMANAGER_H diff --git a/src/imodinterface.h b/src/imodinterface.h index 2eea3988..ca8c6ff6 100644 --- a/src/imodinterface.h +++ b/src/imodinterface.h @@ -1,322 +1,328 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IMODINTERFACE_H -#define IMODINTERFACE_H - -#include -#include -#include - -#include -#include -#include -#include - - -namespace MOBase { - -class VersionInfo; -class IFileTree; - -enum class EndorsedState { - ENDORSED_FALSE, - ENDORSED_TRUE, - ENDORSED_UNKNOWN, - ENDORSED_NEVER -}; - -enum class TrackedState { - TRACKED_FALSE, - TRACKED_TRUE, - TRACKED_UNKNOWN, -}; - -class IModInterface -{ -public: - - virtual ~IModInterface() {} - -public: // Non-meta related information: - - /** - * @return the name of the mod. - */ - virtual QString name() const = 0; - - /** - * @return the absolute path to the mod to be used in file system operations. - */ - virtual QString absolutePath() const = 0; - -public: // Meta-related information: - - /** - * @return the comments for this mod, if any. - */ - virtual QString comments() const = 0; - - /** - * @return the notes for this mod, if any. - */ - virtual QString notes() const = 0; - - /** - * @brief Retrieve the short name of the game associated with this mod. This may differ - * from the current game plugin (e.g. you can install a Skyrim LE game in a SSE - * installation). - * - * @return the name of the game associated with this mod. - */ - virtual QString gameName() const = 0; - - /** - * @return the name of the repository from which this mod was installed. - */ - virtual QString repository() const = 0; - - /** - * @return the Nexus ID of this mod. - */ - virtual int nexusId() const = 0; - - /** - * @return the current version of this mod. - */ - virtual VersionInfo version() const = 0; - - /** - * @return the newest version of thid mod (as known by MO2). If this matches version(), - * then the mod is up-to-date. - */ - virtual VersionInfo newestVersion() const = 0; - - /** - * @return the ignored version of this mod (for update), or an invalid version if the user - * did not ignore version for this mod. - */ - virtual VersionInfo ignoredVersion() const = 0; - - /** - * @return the absolute path to the file that was used to install this mod. - */ - virtual QString installationFile() const = 0; - - virtual std::set> installedFiles() const = 0; - - /** - * @return true if this mod was marked as converted by the user. - * - * @note When a mod is for a different game, a flag is shown to users to warn them, but - * they can mark mods as converted to remove this flag. - */ - virtual bool converted() const = 0; - - /** - * @return true if th is mod was marked as containing valid game data. - * - * @note MO2 uses ModDataChecker to check the content of mods, but sometimes these fail, in - * which case mods are incorrectly marked as 'not containing valid games data'. Users can - * choose to mark these mods as valid to hide the warning / flag. - */ - virtual bool validated() const = 0; - - /** - * @return the color of the 'Notes' column chosen by the user. - */ - virtual QColor color() const = 0; - - /** - * @return the URL of this mod, or an empty QString() if no URL is associated - * with this mod. - */ - virtual QString url() const = 0; - - /** - * @return the ID of the primary category of this mod. - */ - virtual int primaryCategory() const = 0; - - /** - * @return the list of categories this mod belongs to. - */ - virtual QStringList categories() const = 0; - - /** - * @return the tracked state of this mod. - */ - virtual TrackedState trackedState() const = 0; - - /** - * @return the endorsement state of this mod. - */ - virtual EndorsedState endorsedState() const = 0; - - /** - * @brief Retrieve a file tree corresponding to the underlying disk content - * of this mod. - * - * The file tree should not be cached since it is already cached and updated when - * required. - * - * @return a file tree representing the content of this mod. - */ - virtual std::shared_ptr fileTree() const = 0; - - /** - * @return true if this object represents the overwrite mod. - */ - virtual bool isOverwrite() const = 0; - - /** - * @return true if this object represents a backup. - */ - virtual bool isBackup() const = 0; - - /** - * @return true if this object represents a separator. - */ - virtual bool isSeparator() const = 0; - - /** - * @return true if this object represents a foreign mod. - */ - virtual bool isForeign() const = 0; - -public: // Mutable operations: - - /** - * @brief set/change the version of this mod - * @param version new version of the mod - */ - virtual void setVersion(const VersionInfo &version) = 0; - - /** - * @brief sets the installation file for this mod - * @param fileName archive file name - */ - virtual void setInstallationFile(const QString &fileName) = 0; - - /** - * @brief set/change the latest known version of this mod - * @param version newest known version of the mod - */ - virtual void setNewestVersion(const VersionInfo &version) = 0; - - /** - * @brief set endorsement state of the mod - * @param endorsed new endorsement state - */ - virtual void setIsEndorsed(bool endorsed) = 0; - - /** - * @brief sets the mod id on nexus for this mod - * @param the new id to set - */ - virtual void setNexusID(int nexusID) = 0; - - /** - * @brief sets the category id from a nexus category id. Conversion to MO id happens internally - * @param categoryID the nexus category id - * @note if a mapping is not possible, the category is set to the default value - */ - virtual void addNexusCategory(int categoryID) = 0; - - /** - * @brief assign a category to the mod. If the named category doesn't exist it is created - * @param categoryName name of the new category - */ - virtual void addCategory(const QString &categoryName) = 0; - - /** - * @brief unassign a category from this mod. - * @param categoryName name of the category to be removed - * @return true if the category was removed successfully, false if no such category was assigned - */ - virtual bool removeCategory(const QString &categoryName) = 0; - - /** - * @brief set/change the source game of this mod - * - * @param gameName the source game shortName - */ - virtual void setGameName(const QString &gameName) = 0; - - /** - * @brief Set a URL for this mod. - * - * @param url The URL of this mod. - */ - virtual void setUrl(const QString &url) = 0; - -public: // Plugin operations: - - /** - * @brief Retrieve the specified setting in this mod for a plugin. - * - * @param pluginName Name of the plugin for which to retrieve a setting. This should always be IPlugin::name() - * unless you have a really good reason to access settings of another plugin. - * @param key Identifier of the setting. - * @param defaultValue The default value to return if the setting does not exist. - * - * @return the setting, if found, or the default value. - */ - virtual QVariant pluginSetting(const QString& pluginName, const QString& key, const QVariant& defaultValue = QVariant()) const = 0; - - /** - * @brief Retrieve the settings in this mod for a plugin. - * - * @param pluginName Name of the plugin for which to retrieve settings. This should always be IPlugin::name() - * unless you have a really good reason to access settings of another plugin. - * - * @return a map from setting key to value. The map is empty if there are not settings for this mod. - */ - virtual std::map pluginSettings(const QString& pluginName) const = 0; - - /** - * @brief Set the specified setting in this mod for a plugin. - * - * @param pluginName Name of the plugin for which to retrieve a setting. This should always be IPlugin::name() - * unless you have a really good reason to access settings of another plugin. - * @param key Identifier of the setting. - * @param value New value for the setting to set. - * - * @return true if the setting was set correctly, false otherwise. - */ - virtual bool setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value) = 0; - - /** - * @brief Remove all the settings of the specified plugin from th is mod. - * - * @param pluginName Name of the plugin for which settings should be removed. This should always be IPlugin::name() - * unless you have a really good reason to access settings of another plugin. - * - * @return the old settings from the given plugin, as returned by `pluginSettings()`. - */ - virtual std::map clearPluginSettings(const QString& pluginName) = 0; - -}; - - -} // namespace MOBase - -#endif // IMODINTERFACE_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IMODINTERFACE_H +#define IMODINTERFACE_H + +#include +#include +#include + +#include +#include +#include +#include + +namespace MOBase +{ + +class VersionInfo; +class IFileTree; + +enum class EndorsedState +{ + ENDORSED_FALSE, + ENDORSED_TRUE, + ENDORSED_UNKNOWN, + ENDORSED_NEVER +}; + +enum class TrackedState +{ + TRACKED_FALSE, + TRACKED_TRUE, + TRACKED_UNKNOWN, +}; + +class IModInterface +{ +public: + virtual ~IModInterface() {} + +public: // Non-meta related information: + /** + * @return the name of the mod. + */ + virtual QString name() const = 0; + + /** + * @return the absolute path to the mod to be used in file system operations. + */ + virtual QString absolutePath() const = 0; + +public: // Meta-related information: + /** + * @return the comments for this mod, if any. + */ + virtual QString comments() const = 0; + + /** + * @return the notes for this mod, if any. + */ + virtual QString notes() const = 0; + + /** + * @brief Retrieve the short name of the game associated with this mod. This may + * differ from the current game plugin (e.g. you can install a Skyrim LE game in a SSE + * installation). + * + * @return the name of the game associated with this mod. + */ + virtual QString gameName() const = 0; + + /** + * @return the name of the repository from which this mod was installed. + */ + virtual QString repository() const = 0; + + /** + * @return the Nexus ID of this mod. + */ + virtual int nexusId() const = 0; + + /** + * @return the current version of this mod. + */ + virtual VersionInfo version() const = 0; + + /** + * @return the newest version of thid mod (as known by MO2). If this matches + * version(), then the mod is up-to-date. + */ + virtual VersionInfo newestVersion() const = 0; + + /** + * @return the ignored version of this mod (for update), or an invalid version if the + * user did not ignore version for this mod. + */ + virtual VersionInfo ignoredVersion() const = 0; + + /** + * @return the absolute path to the file that was used to install this mod. + */ + virtual QString installationFile() const = 0; + + virtual std::set> installedFiles() const = 0; + + /** + * @return true if this mod was marked as converted by the user. + * + * @note When a mod is for a different game, a flag is shown to users to warn them, + * but they can mark mods as converted to remove this flag. + */ + virtual bool converted() const = 0; + + /** + * @return true if th is mod was marked as containing valid game data. + * + * @note MO2 uses ModDataChecker to check the content of mods, but sometimes these + * fail, in which case mods are incorrectly marked as 'not containing valid games + * data'. Users can choose to mark these mods as valid to hide the warning / flag. + */ + virtual bool validated() const = 0; + + /** + * @return the color of the 'Notes' column chosen by the user. + */ + virtual QColor color() const = 0; + + /** + * @return the URL of this mod, or an empty QString() if no URL is associated + * with this mod. + */ + virtual QString url() const = 0; + + /** + * @return the ID of the primary category of this mod. + */ + virtual int primaryCategory() const = 0; + + /** + * @return the list of categories this mod belongs to. + */ + virtual QStringList categories() const = 0; + + /** + * @return the tracked state of this mod. + */ + virtual TrackedState trackedState() const = 0; + + /** + * @return the endorsement state of this mod. + */ + virtual EndorsedState endorsedState() const = 0; + + /** + * @brief Retrieve a file tree corresponding to the underlying disk content + * of this mod. + * + * The file tree should not be cached since it is already cached and updated when + * required. + * + * @return a file tree representing the content of this mod. + */ + virtual std::shared_ptr fileTree() const = 0; + + /** + * @return true if this object represents the overwrite mod. + */ + virtual bool isOverwrite() const = 0; + + /** + * @return true if this object represents a backup. + */ + virtual bool isBackup() const = 0; + + /** + * @return true if this object represents a separator. + */ + virtual bool isSeparator() const = 0; + + /** + * @return true if this object represents a foreign mod. + */ + virtual bool isForeign() const = 0; + +public: // Mutable operations: + /** + * @brief set/change the version of this mod + * @param version new version of the mod + */ + virtual void setVersion(const VersionInfo& version) = 0; + + /** + * @brief sets the installation file for this mod + * @param fileName archive file name + */ + virtual void setInstallationFile(const QString& fileName) = 0; + + /** + * @brief set/change the latest known version of this mod + * @param version newest known version of the mod + */ + virtual void setNewestVersion(const VersionInfo& version) = 0; + + /** + * @brief set endorsement state of the mod + * @param endorsed new endorsement state + */ + virtual void setIsEndorsed(bool endorsed) = 0; + + /** + * @brief sets the mod id on nexus for this mod + * @param the new id to set + */ + virtual void setNexusID(int nexusID) = 0; + + /** + * @brief sets the category id from a nexus category id. Conversion to MO id happens + * internally + * @param categoryID the nexus category id + * @note if a mapping is not possible, the category is set to the default value + */ + virtual void addNexusCategory(int categoryID) = 0; + + /** + * @brief assign a category to the mod. If the named category doesn't exist it is + * created + * @param categoryName name of the new category + */ + virtual void addCategory(const QString& categoryName) = 0; + + /** + * @brief unassign a category from this mod. + * @param categoryName name of the category to be removed + * @return true if the category was removed successfully, false if no such category + * was assigned + */ + virtual bool removeCategory(const QString& categoryName) = 0; + + /** + * @brief set/change the source game of this mod + * + * @param gameName the source game shortName + */ + virtual void setGameName(const QString& gameName) = 0; + + /** + * @brief Set a URL for this mod. + * + * @param url The URL of this mod. + */ + virtual void setUrl(const QString& url) = 0; + +public: // Plugin operations: + /** + * @brief Retrieve the specified setting in this mod for a plugin. + * + * @param pluginName Name of the plugin for which to retrieve a setting. This should + * always be IPlugin::name() unless you have a really good reason to access + * settings of another plugin. + * @param key Identifier of the setting. + * @param defaultValue The default value to return if the setting does not exist. + * + * @return the setting, if found, or the default value. + */ + virtual QVariant pluginSetting(const QString& pluginName, const QString& key, + const QVariant& defaultValue = QVariant()) const = 0; + + /** + * @brief Retrieve the settings in this mod for a plugin. + * + * @param pluginName Name of the plugin for which to retrieve settings. This should + * always be IPlugin::name() unless you have a really good reason to access settings + * of another plugin. + * + * @return a map from setting key to value. The map is empty if there are not settings + * for this mod. + */ + virtual std::map + pluginSettings(const QString& pluginName) const = 0; + + /** + * @brief Set the specified setting in this mod for a plugin. + * + * @param pluginName Name of the plugin for which to retrieve a setting. This should + * always be IPlugin::name() unless you have a really good reason to access settings + * of another plugin. + * @param key Identifier of the setting. + * @param value New value for the setting to set. + * + * @return true if the setting was set correctly, false otherwise. + */ + virtual bool setPluginSetting(const QString& pluginName, const QString& key, + const QVariant& value) = 0; + + /** + * @brief Remove all the settings of the specified plugin from th is mod. + * + * @param pluginName Name of the plugin for which settings should be removed. This + * should always be IPlugin::name() unless you have a really good reason to access + * settings of another plugin. + * + * @return the old settings from the given plugin, as returned by `pluginSettings()`. + */ + virtual std::map + clearPluginSettings(const QString& pluginName) = 0; +}; + +} // namespace MOBase + +#endif // IMODINTERFACE_H diff --git a/src/imodlist.h b/src/imodlist.h index 725573a3..7f7a2a12 100644 --- a/src/imodlist.h +++ b/src/imodlist.h @@ -1,216 +1,229 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2013 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IMODLIST_H -#define IMODLIST_H - -#include -#include - -#include -#include - -#include "iprofile.h" -#include "imodinterface.h" - -namespace MOBase { - -/** - * @brief interface to the mod-list - * @note all api functions in this interface work need the internal name of a mod to find a mod. For regular mods - * (mods the user installed) the display name (as shown to the user) and internal name are identical. For other - * mods (non-MO mods) there is currently no way to translate from display name to internal name because the display - * name might not me un-ambiguous. - */ -class IModList { - -public: - - enum ModState { - STATE_EXISTS = 0x00000001, - STATE_ACTIVE = 0x00000002, - STATE_ESSENTIAL = 0x00000004, - STATE_EMPTY = 0x00000008, - STATE_ENDORSED = 0x00000010, - STATE_VALID = 0x00000020, - STATE_ALTERNATE = 0x00000040 - }; - - Q_DECLARE_FLAGS(ModStates, ModState) - -public: - - virtual ~IModList() {} - - /** - * @brief retrieves the display name of a mod from it's internal name - * @param internalName the internal name - * @return a string intended to identify the name to the user - * @note If you received an internal name from an api (i.e. IPluginList::origin) then you should use that name - * to identify the mod to all other api calls but use this function to retrieve the name to show to the user. - */ - virtual QString displayName(const QString &internalName) const = 0; - - /** - * @brief Retrieve a list of all installed mod names. - * - * @return list of mods (internal names). - */ - virtual QStringList allMods() const = 0; - - /** - * @brief Retrieve the list of installed mod names, sorted by current profile priority. - * - * @param profile The profile to use for the priority. If nullptr, the current - * profile is used. - * - * @return list of mods (internal names), sorted by priority. - */ - virtual QStringList allModsByProfilePriority(MOBase::IProfile *profile = nullptr) const = 0; - - /** - * @brief Retrieve the mod with the given name. - * - * @param name Name of the mod to retrieve. - * - * @return the mod with the given name, or a null pointer if there is no mod with this name. - */ - virtual IModInterface* getMod(const QString& name) const = 0; - - /** - * @brief Remove a mod (from disc and from the ui). - * - * @param mod The mod to remove. - * - * @return true on success, false on error. - */ - virtual bool removeMod(MOBase::IModInterface *mod) = 0; - - /** - * @brief Rename the given mod. - * - * This invalidate the mod so you should use the returned value afterwards. - * - * @param mod The mod to rename. - * - * @return the new mod (after renaming) on success, a null pointer on error. - */ - virtual MOBase::IModInterface* renameMod(MOBase::IModInterface *mod, const QString& name) = 0; - - - /** - * @brief retrieve the state of a mod - * @param name name of the mod - * @return a bitset of information about the mod - */ - virtual ModStates state(const QString &name) const = 0; - - /** - * @brief enable or disable a mod - * - * @param name name of the mod - * @param active if true the mod is enabled, otherwise it's disabled - * - * @return true on success, false if the mod name is not valid - * - * @note calling this will cause MO to re-evaluate its virtual file system so this is fairly - * expensive - */ - virtual bool setActive(const QString &name, bool active) = 0; - - /** - * @brief enable or disable a list of mod - * - * @param names names of the mod - * @param active if true mods are enabled, otherwise they are disabled - * - * @return the number of mods successfully enabled or disabled - * - * @note calling this will cause MO to re-evaluate its virtual file system so this is fairly - * expensive - */ - virtual int setActive(const QStringList& names, bool active) = 0; - - - /** - * @brief retrieve the priority of a mod - * @param name name of the mod - * @return the priority (the higher the more important). Returns -1 if the mod doesn't exist - */ - virtual int priority(const QString &name) const = 0; - - /** - * @brief change the priority of a mod - * @param name name of the mod - * @param newPriority new priority of the mod - * @return true on success, false if the priority change was not possible. This is usually because one of the parameters is invalid - * @note Very important: newPriority is the new priority after the move. Keep in mind that the mod disappears from it's old location and - * all mods with higher priority than the moved mod decrease in priority by one. - */ - virtual bool setPriority(const QString &name, int newPriority) = 0; - - /** - * @brief Add a new callback to be called when a new mod is installed. - * - * Parameters of the callback: - * - The installed mod. - * - * @param func Function to called when a mod has been installed. - */ - virtual bool onModInstalled(const std::function& func) = 0; - - /** - * @brief Add a new callback to be called when a mod is removed. - * - * Parameters of the callback: - * - The name of the removed mod. - * - * @param func Function to called when a mod has been removed. - */ - virtual bool onModRemoved(const std::function& func) = 0; - - /** - * @brief Installs a handler for the event that the state of mods changed (enabled/disabled, endorsed, ...). - * - * Parameters of the callback: - * - Map containing the mods whose states have changed. Keys are mod names and values are mod states. - * - * @param func The signal to be called when the state of any mod changes. - * - * @return true if the handler was successfully installed, false otherwise (there is as of now no known reason this should fail). - */ - virtual bool onModStateChanged(const std::function&)> &func) = 0; - - /** - * installs a handler for the event that a mod changes priority - * @param func the signal to be called when the priority of a mod changes - * (first parameter for the handler is the name of the mod, second is the old priority, third the new one) - * @return true if the handler was successfully installed (there is as of now no known reason this should fail) - */ - virtual bool onModMoved(const std::function &func) = 0; - -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(IModList::ModStates) - -} - -#endif // IMODLIST_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2013 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IMODLIST_H +#define IMODLIST_H + +#include +#include + +#include +#include + +#include "imodinterface.h" +#include "iprofile.h" + +namespace MOBase +{ + +/** + * @brief interface to the mod-list + * @note all api functions in this interface work need the internal name of a mod to + * find a mod. For regular mods (mods the user installed) the display name (as shown to + * the user) and internal name are identical. For other mods (non-MO mods) there is + * currently no way to translate from display name to internal name because the display + * name might not me un-ambiguous. + */ +class IModList +{ + +public: + enum ModState + { + STATE_EXISTS = 0x00000001, + STATE_ACTIVE = 0x00000002, + STATE_ESSENTIAL = 0x00000004, + STATE_EMPTY = 0x00000008, + STATE_ENDORSED = 0x00000010, + STATE_VALID = 0x00000020, + STATE_ALTERNATE = 0x00000040 + }; + + Q_DECLARE_FLAGS(ModStates, ModState) + +public: + virtual ~IModList() {} + + /** + * @brief retrieves the display name of a mod from it's internal name + * @param internalName the internal name + * @return a string intended to identify the name to the user + * @note If you received an internal name from an api (i.e. IPluginList::origin) then + * you should use that name to identify the mod to all other api calls but use this + * function to retrieve the name to show to the user. + */ + virtual QString displayName(const QString& internalName) const = 0; + + /** + * @brief Retrieve a list of all installed mod names. + * + * @return list of mods (internal names). + */ + virtual QStringList allMods() const = 0; + + /** + * @brief Retrieve the list of installed mod names, sorted by current profile + * priority. + * + * @param profile The profile to use for the priority. If nullptr, the current + * profile is used. + * + * @return list of mods (internal names), sorted by priority. + */ + virtual QStringList + allModsByProfilePriority(MOBase::IProfile* profile = nullptr) const = 0; + + /** + * @brief Retrieve the mod with the given name. + * + * @param name Name of the mod to retrieve. + * + * @return the mod with the given name, or a null pointer if there is no mod with this + * name. + */ + virtual IModInterface* getMod(const QString& name) const = 0; + + /** + * @brief Remove a mod (from disc and from the ui). + * + * @param mod The mod to remove. + * + * @return true on success, false on error. + */ + virtual bool removeMod(MOBase::IModInterface* mod) = 0; + + /** + * @brief Rename the given mod. + * + * This invalidate the mod so you should use the returned value afterwards. + * + * @param mod The mod to rename. + * + * @return the new mod (after renaming) on success, a null pointer on error. + */ + virtual MOBase::IModInterface* renameMod(MOBase::IModInterface* mod, + const QString& name) = 0; + + /** + * @brief retrieve the state of a mod + * @param name name of the mod + * @return a bitset of information about the mod + */ + virtual ModStates state(const QString& name) const = 0; + + /** + * @brief enable or disable a mod + * + * @param name name of the mod + * @param active if true the mod is enabled, otherwise it's disabled + * + * @return true on success, false if the mod name is not valid + * + * @note calling this will cause MO to re-evaluate its virtual file system so this is + * fairly expensive + */ + virtual bool setActive(const QString& name, bool active) = 0; + + /** + * @brief enable or disable a list of mod + * + * @param names names of the mod + * @param active if true mods are enabled, otherwise they are disabled + * + * @return the number of mods successfully enabled or disabled + * + * @note calling this will cause MO to re-evaluate its virtual file system so this is + * fairly expensive + */ + virtual int setActive(const QStringList& names, bool active) = 0; + + /** + * @brief retrieve the priority of a mod + * @param name name of the mod + * @return the priority (the higher the more important). Returns -1 if the mod doesn't + * exist + */ + virtual int priority(const QString& name) const = 0; + + /** + * @brief change the priority of a mod + * @param name name of the mod + * @param newPriority new priority of the mod + * @return true on success, false if the priority change was not possible. This is + * usually because one of the parameters is invalid + * @note Very important: newPriority is the new priority after the move. Keep in mind + * that the mod disappears from it's old location and all mods with higher priority + * than the moved mod decrease in priority by one. + */ + virtual bool setPriority(const QString& name, int newPriority) = 0; + + /** + * @brief Add a new callback to be called when a new mod is installed. + * + * Parameters of the callback: + * - The installed mod. + * + * @param func Function to called when a mod has been installed. + */ + virtual bool onModInstalled(const std::function& func) = 0; + + /** + * @brief Add a new callback to be called when a mod is removed. + * + * Parameters of the callback: + * - The name of the removed mod. + * + * @param func Function to called when a mod has been removed. + */ + virtual bool onModRemoved(const std::function& func) = 0; + + /** + * @brief Installs a handler for the event that the state of mods changed + * (enabled/disabled, endorsed, ...). + * + * Parameters of the callback: + * - Map containing the mods whose states have changed. Keys are mod names and + * values are mod states. + * + * @param func The signal to be called when the state of any mod changes. + * + * @return true if the handler was successfully installed, false otherwise (there is + * as of now no known reason this should fail). + */ + virtual bool onModStateChanged( + const std::function&)>& func) = 0; + + /** + * installs a handler for the event that a mod changes priority + * @param func the signal to be called when the priority of a mod changes + * (first parameter for the handler is the name of the mod, second is the old + * priority, third the new one) + * @return true if the handler was successfully installed (there is as of now no known + * reason this should fail) + */ + virtual bool + onModMoved(const std::function& func) = 0; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(IModList::ModStates) + +} // namespace MOBase + +#endif // IMODLIST_H diff --git a/src/imodrepositorybridge.cpp b/src/imodrepositorybridge.cpp index 9dc0dc2b..06adefbf 100644 --- a/src/imodrepositorybridge.cpp +++ b/src/imodrepositorybridge.cpp @@ -1 +1 @@ -#include "imodrepositorybridge.h" +#include "imodrepositorybridge.h" diff --git a/src/imodrepositorybridge.h b/src/imodrepositorybridge.h index 4bbd260c..34ded6a0 100644 --- a/src/imodrepositorybridge.h +++ b/src/imodrepositorybridge.h @@ -1,22 +1,19 @@ #ifndef INEXUSBRIDGE_H #define INEXUSBRIDGE_H - +#include "modrepositoryfileinfo.h" +#include #include #include -#include -#include "modrepositoryfileinfo.h" - - -namespace MOBase { +namespace MOBase +{ class QDLLEXPORT IModRepositoryBridge : public QObject { Q_OBJECT public: - - IModRepositoryBridge(QObject *parent = nullptr) : QObject(parent) {} + IModRepositoryBridge(QObject* parent = nullptr) : QObject(parent) {} /** * @brief request description for a mod @@ -41,7 +38,8 @@ class QDLLEXPORT IModRepositoryBridge : public QObject * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestFileInfo(QString game, int modID, int fileID, QVariant userData) = 0; + virtual void requestFileInfo(QString game, int modID, int fileID, + QVariant userData) = 0; /** * @brief request the download url of a file @@ -50,17 +48,18 @@ class QDLLEXPORT IModRepositoryBridge : public QObject * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData) = 0; + virtual void requestDownloadURL(QString gameName, int modID, int fileID, + QVariant userData) = 0; /** * @brief requestToggleEndorsement * @param modID id of the mod caller is interested in * @param userData user data to be returned with the result */ - virtual void requestToggleEndorsement(QString gameName, int modID, QString modVersion, bool endorse, QVariant userData) = 0; + virtual void requestToggleEndorsement(QString gameName, int modID, QString modVersion, + bool endorse, QVariant userData) = 0; private: - Q_DISABLE_COPY(IModRepositoryBridge) Q_SIGNALS: @@ -69,29 +68,40 @@ class QDLLEXPORT IModRepositoryBridge : public QObject * @brief sent when the description for a mod is reported by the repository * @param modID id of the mod for which the request was made * @param userData the data that was included in the request - * @param resultData result data. this is a variant map. keys are strings. Value is usually also a string, wrapped in a variant. - * @note valid keys might change as the repository page is updated. For nexus, the following keys are valid as of this writing: - * 'allow_view', 'ip', 'one_week_ratings', 'date', 'pm_notify', 'OLD_mid', 'OLD_u_downloads', 'game_id', 'OLD_perm_use', 'mod_page_uri', - * 'allow_topics', 'has_hot_image', 'id', 'two_weeks_ratings', 'description', 'lastupdate', 'perm_convert', 'author', 'OLD_image', - * 'translation_of', 'OLD_mname', 'version', 'allow_rating', 'perm_useinstructions', 'featured_count', 'donate', 'type', 'perm_credits', - * 'hidden_reason', 'OLD_views', 'perm_upload', 'has_back_image', 'adult', 'allow_images', 'OLD_endorsements', 'OLD_size', 'name', - * 'commenting', 'moderate', 'language', 'perm_others', 'lastcomment', 'OLD_readme', 'summary', 'perm_modify', 'OLD_downloads', - * 'lock_comments', 'suggested_category', 'allow_tagging', 'published', 'perm_notes', 'category_id', 'thread_id', 'perm_use', 'wizard_steps' - * @note in the python interface use the onDescriptionAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal - * @note this interface is going to be changed at some point to replace resultData with a less "dynamic" data structure + * @param resultData result data. this is a variant map. keys are strings. Value is + * usually also a string, wrapped in a variant. + * @note valid keys might change as the repository page is updated. For nexus, the + * following keys are valid as of this writing: 'allow_view', 'ip', + * 'one_week_ratings', 'date', 'pm_notify', 'OLD_mid', 'OLD_u_downloads', 'game_id', + * 'OLD_perm_use', 'mod_page_uri', 'allow_topics', 'has_hot_image', 'id', + * 'two_weeks_ratings', 'description', 'lastupdate', 'perm_convert', 'author', + * 'OLD_image', 'translation_of', 'OLD_mname', 'version', 'allow_rating', + * 'perm_useinstructions', 'featured_count', 'donate', 'type', 'perm_credits', + * 'hidden_reason', 'OLD_views', 'perm_upload', 'has_back_image', 'adult', + * 'allow_images', 'OLD_endorsements', 'OLD_size', 'name', 'commenting', 'moderate', + * 'language', 'perm_others', 'lastcomment', 'OLD_readme', 'summary', 'perm_modify', + * 'OLD_downloads', 'lock_comments', 'suggested_category', 'allow_tagging', + * 'published', 'perm_notes', 'category_id', 'thread_id', 'perm_use', 'wizard_steps' + * @note in the python interface use the onDescriptionAvailable call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal + * @note this interface is going to be changed at some point to replace resultData + * with a less "dynamic" data structure */ - void descriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData); + void descriptionAvailable(QString gameName, int modID, QVariant userData, + QVariant resultData); /** * @brief sent when the list of files for a mod is reported by the repository * @param modID id of the mod for which the request was made * @param userData the data that was included in the request * @param resultData a list of (already decoded) file information objects - * @note in the python interface use the onFilesAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal + * @note in the python interface use the onFilesAvailable call to register a callback + * for this signal. The signature of your callback must match the signature of this + * signal */ - void filesAvailable(QString gameName, int modID, QVariant userData, const QList &resultData); + void filesAvailable(QString gameName, int modID, QVariant userData, + const QList& resultData); /** * @brief sent when information about a file is reported by the repository @@ -99,16 +109,21 @@ class QDLLEXPORT IModRepositoryBridge : public QObject * @param fileID id of the the file for which information was requested * @param userData the data that was included in the request * @param resultData a variant map of information about the file. - * @note valid keys might change as the repository page is updated. For nexus, the following keys are valid as of this writing: - * 'count', 'requirements_alert', 'u_count', 'description', 'uri', 'size', 'owner_id', 'primary', 'manager', 'version', 'date', - * 'game_id', 'mod_id', 'category_id', 'id', 'name' - * @note in the python interface use the onFileInfoAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal - * @note if you intend to download this file you don't have to request this information manually. call IDownloadManager::startDownloadNexusFile - * and let the download manager figure things out - * @note this interface is going to be changed at some point to replace resultData with a less "dynamic" data structure + * @note valid keys might change as the repository page is updated. For nexus, the + * following keys are valid as of this writing: 'count', 'requirements_alert', + * 'u_count', 'description', 'uri', 'size', 'owner_id', 'primary', 'manager', + * 'version', 'date', 'game_id', 'mod_id', 'category_id', 'id', 'name' + * @note in the python interface use the onFileInfoAvailable call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal + * @note if you intend to download this file you don't have to request this + * information manually. call IDownloadManager::startDownloadNexusFile and let the + * download manager figure things out + * @note this interface is going to be changed at some point to replace resultData + * with a less "dynamic" data structure */ - void fileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData); + void fileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, + QVariant resultData); /** * @brief sent when the list of download urls for a file is returned by the repository @@ -116,48 +131,59 @@ class QDLLEXPORT IModRepositoryBridge : public QObject * @param fileID id of the file for which the downloads * @param userData the data that was included in the request * @param resultData a variant map of information about the url - * @note this function is not exposed to python. please use IDownloadManager::startDownloadNexusFile to download a file, this - * lets the download manager figure out the best server according to user preference and stuff - * @note this interface is going to be changed at some point to replace resultData with a less "dynamic" data structure + * @note this function is not exposed to python. please use + * IDownloadManager::startDownloadNexusFile to download a file, this lets the download + * manager figure out the best server according to user preference and stuff + * @note this interface is going to be changed at some point to replace resultData + * with a less "dynamic" data structure */ - void downloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData); + void downloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, + QVariant resultData); /** * @brief sent when the endorsement data is returned from the API * @param userData the data that was included in the request * @param resultData new endorsement state as a boolean (wrapped in a qvariant) - * @note in the python interface use the onEndorsementsAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal + * @note in the python interface use the onEndorsementsAvailable call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal */ void endorsementsAvailable(QVariant userData, QVariant resultData); /** - * @brief sent when the endorsement state of a mod was changed (only sent as a result of our request) + * @brief sent when the endorsement state of a mod was changed (only sent as a result + * of our request) * @param modID id of the mod for which the request was made * @param userData the data that was included in the request * @param resultData new endorsement state as a boolean (wrapped in a qvariant) - * @note in the python interface use the onEndorsementToggled call to register a callback for this signal. The signature of - * your callback must match the signature of this signal - * @note this interface is going to be changed at some point to replace resultData with a boolean + * @note in the python interface use the onEndorsementToggled call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal + * @note this interface is going to be changed at some point to replace resultData + * with a boolean */ - void endorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData); + void endorsementToggled(QString gameName, int modID, QVariant userData, + QVariant resultData); /** - * @brief sent when the tracked mod data is returned from the API - * @param userData the data that was included in the request - * @param resultData new tracked state as a list of maps (keys: domain_name, mod_id) - * @note in the python interface use the ontrackedModsAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal - */ + * @brief sent when the tracked mod data is returned from the API + * @param userData the data that was included in the request + * @param resultData new tracked state as a list of maps (keys: domain_name, mod_id) + * @note in the python interface use the ontrackedModsAvailable call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal + */ void trackedModsAvailable(QVariant userData, QVariant resultData); /** - * @brief sent when the tracking state of a mod was changed (only sent as a result of our request) + * @brief sent when the tracking state of a mod was changed (only sent as a result of + * our request) * @param modID id of the mod for which the request was made * @param userData the data that was included in the request * @param tracked new tracking state - * @note in the python interface use the onTrackingToggled call to register a callback for this signal. The signature of - * your callback must match the signature of this signal + * @note in the python interface use the onTrackingToggled call to register a callback + * for this signal. The signature of your callback must match the signature of this + * signal */ void trackingToggled(QString gameName, int modID, QVariant userData, bool tracked); @@ -174,16 +200,18 @@ class QDLLEXPORT IModRepositoryBridge : public QObject /** * @brief sent when a request to nexus failed * @param modID id of the mod for which the request was made - * @param fileID id of the file for which the request was made (ignore if the request was for the mod in general) + * @param fileID id of the file for which the request was made (ignore if the request + * was for the mod in general) * @param userData the data that was included in the request * @param errorMessage textual description of the problem - * @note in the python interface use the onDescriptionAvailable call to register a callback for this signal. The signature of - * your callback must match the signature of this signal + * @note in the python interface use the onDescriptionAvailable call to register a + * callback for this signal. The signature of your callback must match the signature + * of this signal */ - void requestFailed(QString gameName, int modID, int fileID, QVariant userData, int errorCode, const QString &errorMessage); - + void requestFailed(QString gameName, int modID, int fileID, QVariant userData, + int errorCode, const QString& errorMessage); }; -} +} // namespace MOBase -#endif // INEXUSBRIDGE_H +#endif // INEXUSBRIDGE_H diff --git a/src/imoinfo.cpp b/src/imoinfo.cpp index 7576276b..c14cbe0a 100644 --- a/src/imoinfo.cpp +++ b/src/imoinfo.cpp @@ -10,8 +10,7 @@ QString IOrganizer::getPluginDataPath() return g_pluginDataPath; } -} // namespace - +} // namespace MOBase namespace MOBase::details { @@ -21,4 +20,4 @@ void setPluginDataPath(const QString& s) g_pluginDataPath = s; } -} \ No newline at end of file +} // namespace MOBase::details diff --git a/src/imoinfo.h b/src/imoinfo.h index 66d25874..fb00047a 100644 --- a/src/imoinfo.h +++ b/src/imoinfo.h @@ -1,513 +1,550 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IMOINFO_H -#define IMOINFO_H - -#include -#include -#include -#include -#include -#include - -#include "guessedvalue.h" -#include "imodlist.h" -#include "iprofile.h" -#include "versioninfo.h" - -namespace MOBase { - -class IFileTree; -class IModInterface; -class IModRepositoryBridge; -class IDownloadManager; -class IPluginList; -class IPlugin; -class IPluginGame; - -/** - * @brief Interface to class that provides information about the running session - * of Mod Organizer to be used by plugins - * - * When MO requires plugins but does not have a valid instance loaded (such as - * on first start in the instance creation dialog), init() will not be called at - * all, except for proxy plugins. - * - * In the case of proxy plugins, init() is called with a null IOrganizer. - */ -class QDLLEXPORT IOrganizer: public QObject -{ - Q_OBJECT - -public: - - /** - * @brief information about a virtualised file - */ - struct FileInfo { - QString filePath; /// full path to the file - QString archive; /// name of the archive if this file is in a BSA, otherwise this is empty. - QStringList origins; /// list of origins containing this file. the first one is the highest priority one - }; - -public: - - virtual ~IOrganizer() {} - - // the directory for plugin data, typically plugins/data - // - static QString getPluginDataPath(); - - /** - * @return create a new nexus interface class - */ - virtual IModRepositoryBridge *createNexusBridge() const = 0; - - /** - * @return name of the active profile or an empty string if no profile is loaded (yet) - */ - virtual QString profileName() const = 0; - - /** - * @return the (absolute) path to the active profile or an empty string if no profile is loaded (yet) - */ - virtual QString profilePath() const = 0; - - /** - * @return the (absolute) path to the download directory - */ - virtual QString downloadsPath() const = 0; - - /** - * @return the (absolute) path to the overwrite directory - */ - virtual QString overwritePath() const = 0; - - /** - * @return the (absolute) path to the base directory - */ - virtual QString basePath() const = 0; - - /** - * @return the (absolute) path to the mods directory - */ - virtual QString modsPath() const = 0; - - /** - * @return the running version of Mod Organizer - */ - virtual VersionInfo appVersion() const = 0; - - /** - * @brief create a new mod with the specified name - * @param name name of the new mod - * @return an interface that can be used to modify the mod. nullptr if the user canceled - * @note a popup asking the user to merge, rename or replace the mod is displayed if the mod already exists. - * That has to happen on the main thread and MO2 will deadlock if it happens on any other. - * If this needs to be called from another thread, use IModList::getMod() to verify the mod-name is unused first - */ - virtual IModInterface *createMod(GuessedValue &name) = 0; - - /** - * @brief get the game plugin matching the specified game - * @param gameName name of the game short name - * @return a game plugin, or nullptr if there is no match - */ - virtual IPluginGame *getGame(const QString &gameName) const = 0; - - /** - * @brief let the organizer know that a mod has changed - * @param the mod that has changed - */ - virtual void modDataChanged(IModInterface *mod) = 0; - - /** - * @brief Check if a plugin is enabled. - * - * @param pluginName Plugin to check. - * - * @return true if the plugin is enabled, false otherwise. - */ - virtual bool isPluginEnabled(IPlugin* plugin) const = 0; - - /** - * @brief Check if a plugin is enabled. - * - * @param pluginName Name of the plugin to check. - * - * @return true if the plugin is enabled, false otherwise. - */ - virtual bool isPluginEnabled(QString const& pluginName) const = 0; - - /** - * @brief Retrieve the specified setting for a plugin. - * - * @param pluginName Name of the plugin for which to retrieve a setting. This should always be IPlugin::name() unless you have a really good reason - * to access settings of another mod. You can not access settings for a plugin that isn't installed. - * @param key identifier of the setting - * @return the setting - * @note an invalid qvariant is returned if the setting has not been declared - */ - virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const = 0; - - /** - * @brief Set the specified setting for a plugin. - * - * This automatically emit pluginSettingChanged(), so you do not have to do it yourself. - * - * @param pluginName Name of the plugin for which to change a value. This should always be IPlugin::name() unless you have a really good reason - * to access data of another mod AND if you can verify that plugin is actually installed. - * @param key Identifier of the setting. - * @param value Value to set. - * - * @throw an exception is thrown if pluginName doesn't refer to an installed plugin. - */ - virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) = 0; - - /** - * @brief retrieve the specified persistent value for a plugin - * @param pluginName name of the plugin for which to retrieve a value. This should always be IPlugin::name() unless you have a really good reason - * to access data of another mod. - * @param key identifier of the value - * @param def default value to return if the key is not (yet) set - * @return the value - * @note A persistent is an arbitrary value that the plugin can set and retrieve that is persistently stored by the - * main application. There is no UI for the user to change this value but (s)he can directly access the storage - */ - virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const = 0; - - /** - * @brief set the specified persistent value for a plugin - * @param pluginName name of the plugin for which to change a value. This should always be IPlugin::name() unless you have a really good reason - * to access data of another mod AND if you can verify that plugin is actually installed - * @param key identifier of the value - * @param value value to set - * @param sync if true the storage is immediately written to disc. This costs performance but is safer against data loss - * @throw an exception is thrown if pluginName doesn't refer to an installed plugin - */ - virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true) = 0; - - /** - * @return path to a directory where plugin data should be stored. - */ - virtual QString pluginDataPath() const = 0; - - /** - * @brief install a mod archive at the specified location - * @param fileName absolute file name of the mod to install - * @param nameSuggestion suggested name for this mod. This can still be changed by the user - * @return interface to the newly installed mod or nullptr if no installation took place (failure or use canceled - */ - virtual IModInterface *installMod(const QString &fileName, const QString &nameSuggestion = QString()) = 0; - - /** - * @brief resolves a path relative to the virtual data directory to its absolute real path - * @param fileName path to resolve - * @return the absolute real path or an empty string - */ - virtual QString resolvePath(const QString &fileName) const = 0; - - /** - * @brief retrieves a list of (virtual) subdirectories for a path (relative to the data directory) - * @param directoryName relative path to the directory to list - * @return a list of directory names - */ - virtual QStringList listDirectories(const QString &directoryName) const = 0; - - /** - * @brief find files in the virtual directory matching the filename filter - * @param path the path to search in - * @param filter filter function to match against - * @return a list of matching files - */ - virtual QStringList findFiles(const QString &path, const std::function &filter) const = 0; - - /** - * @brief find files in the virtual directory matching the filename filter - * @param path the path to search in - * @param filters list of glob filters to match against - * @return a list of matching files - */ - virtual QStringList findFiles(const QString& path, const QStringList& filters) const = 0; - - /** - * @brief retrieve the file origins for the speicified file. The origins are listed with their internal name - * @return list of origins that contain the specified file, sorted by their priority - * @note the internal name of a mod can differ from the display name for disambiguation - */ - virtual QStringList getFileOrigins(const QString &fileName) const = 0; - - /** - * @brief find files in the virtual directory matching the specified complex filter - * @param path the path to search in - * @param filter filter function to match against - * @return a list of matching files - * @note this function is more expensive than the one filtering by name so use the other one if it suffices - */ - virtual QList findFileInfos(const QString &path, const std::function &filter) const = 0; - - /** - * @return a IFileTree representing the virtual file tree. - */ - virtual std::shared_ptr virtualFileTree() const = 0; - - /** - * @return interface to the download manager - */ - virtual MOBase::IDownloadManager *downloadManager() const = 0; - - /** - * @return interface to the list of plugins (esps, esms, and esls) - */ - virtual MOBase::IPluginList *pluginList() const = 0; - - /** - * @return interface to the list of mods - */ - virtual MOBase::IModList *modList() const = 0; - - /** - * @return interface to the active profile - */ - virtual MOBase::IProfile *profile() const = 0; - - /** - * @brief runs a program using the virtual filesystem - * - * @param executable either the name of an executable configured in MO, or - * a path to an executable; if relative, it is resolved - * against the game directory - * - * @param args arguments to pass to the executable; if this is empty - * and `executable` refers to a configured executable, - * its arguments are used - * - * @param cwd working directory for the executable; if this is empty, - * it is set to either the cwd set by the user in the - * configured executable (if any) or the directory of the - * executable - * - * @param profile name of the profile to use; defaults to the active - * profile - * - * @param forcedCustomOverwrite the name of the mod to set as the custom - * overwrite directory, regardless of what the - * profile has configured - * - * @param ignoreCustomOverwrite if `executable` is the name of a configured - * executable, ignores the executable's custom - * overwrite - * - * @return a handle to the process that was started or INVALID_HANDLE_VALUE - * if the application failed to start. - */ - virtual HANDLE startApplication( - const QString &executable, - const QStringList &args = QStringList(), - const QString &cwd = "", - const QString &profile = "", - const QString &forcedCustomOverwrite = "", - bool ignoreCustomOverwrite = false) = 0; - - /** - * @brief blocks until the given process has completed - * - * @param handle the process to wait for - * @param refresh whether MO should refresh after the process completed - * @param exitCode the exit code of the process after it ended - * - * @return true if the process completed successfully - * - * @note this will always show the lock overlay, regardless of whether the - * user has disabled locking in the setting, so use this with care; - * note that the lock overlay will always allow the user to unlock, in - * which case this will return false - */ - virtual bool waitForApplication( - HANDLE handle, bool refresh = true, LPDWORD exitCode = nullptr) const = 0; - - /** - * @brief Refresh the internal mods file structure from disk. This includes the mod list, the plugin - * list, data tab and other smaller things like problems button (same as pressing F5). - * - * @note The main part of the refresh of the mods file strcuture, modlist and pluginlist is done - * asynchronously, so you should not expect them to be up-to-date when this function returns. - * - * @param saveChanges If true, the relevant profile information is saved first (enabled mods and their order). - */ - virtual void refresh(bool saveChanges = true) = 0; - - /** - * @brief get the currently managed game info - */ - virtual MOBase::IPluginGame const *managedGame() const = 0; - - /** - * @brief Add a new callback to be called when an application is about to be run. - * - * Parameters of the callback: - * - Path (absolute) to the application to be run. - * - * The callback can return false to prevent the application from being launched. - * - * @param func Function to be called when an application is run. - */ - virtual bool onAboutToRun(const std::function& func) = 0; - - /** - * @brief Add a new callback to be called when an has finished running. - * - * Parameters of the callback: - * - Path (absolute) to the application that has finished running. - * - Exit code of the application. - * - * - * @param func Function to be called when an application is run. - */ - virtual bool onFinishedRun(const std::function& func) = 0; - - /** - * @brief Add a new callback to be called when the user interface has been initialized. - * - * Parameters of the callback: - * - The main window of the application. - * - * @param func Function to be called when the user interface has been initialized. - */ - virtual bool onUserInterfaceInitialized(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a new profile is created. - * - * Parameters of the callback: - * - The created profile (can be a temporary object, so it should not be stored). - * - * @param func Function to be called when a profile is created. - * - */ - virtual bool onProfileCreated(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a profile is renamed. - * - * Parameters of the callback: - * - The renamed profile. - * - The old name of the profile. - * - The new name of the profile. - * - * @param func Function to be called when a profile is renamed. - * - */ - virtual bool onProfileRenamed(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a profile is removed. - * - * Parameters of the callback: - * - The name of the removed profile. - * - * The function is called after the profile has been removed, so the profile is not accessible anymore. - * - * @param func Function to be called when a profile is removed. - * - */ - virtual bool onProfileRemoved(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when the current profile is changed. - * - * Parameters of the callback: - * - The old profile. Can be a null pointer if no profile was set (e.g. at startup). - * - The new profile, cannot be null. - * - * The function is called when the profile is changed but some operations related to - * the profile might not be finished when this is called (e.g., the virtual file system - * might not be up-to-date). - * - * @param func Function to be called when the current profile change. - * - */ - virtual bool onProfileChanged(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a plugin setting is changed. - * - * Parameters of the callback: - * - Name of the plugin. - * - Name of the setting. - * - Old value of the setting. Can be a default-constructed (invalid) QVariant if the setting - * did not exist before. - * - New value of the setting. Can be a default-constructed (invalid) QVariant if the setting - * has been removed. - * - * @param func Function to be called when a plugin setting is changed. - */ - virtual bool onPluginSettingChanged(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a plugin is enabled. - * - * Parameters of the callback: - * - The enabled plugin. - * - * @param func Function to be called when a plugin is enabled. - */ - virtual bool onPluginEnabled(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when the specified plugin is enabled. - * - * @param name Name of the plugin to watch. - * @param func Function to be called when a plugin is enabled. - */ - virtual bool onPluginEnabled(const QString& pluginName, std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when a plugin is disabled. - * - * Parameters of the callback: - * - The disabled plugin. - * - * @param func Function to be called when a plugin is disabled. - */ - virtual bool onPluginDisabled(std::function const& func) = 0; - - /** - * @brief Add a new callback to be called when the specified plugin is disabled. - * - * @param name Name of the plugin to watch. - * @param func Function to be called when a plugin is disabled. - */ - virtual bool onPluginDisabled(const QString& pluginName, std::function const& func) = 0; - -}; - -} // namespace MOBase - - -namespace MOBase::details -{ - // called from MO - QDLLEXPORT void setPluginDataPath(const QString& s); -} - -#endif // IMOINFO_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IMOINFO_H +#define IMOINFO_H + +#include +#include +#include +#include +#include +#include + +#include "guessedvalue.h" +#include "imodlist.h" +#include "iprofile.h" +#include "versioninfo.h" + +namespace MOBase +{ + +class IFileTree; +class IModInterface; +class IModRepositoryBridge; +class IDownloadManager; +class IPluginList; +class IPlugin; +class IPluginGame; + +/** + * @brief Interface to class that provides information about the running session + * of Mod Organizer to be used by plugins + * + * When MO requires plugins but does not have a valid instance loaded (such as + * on first start in the instance creation dialog), init() will not be called at + * all, except for proxy plugins. + * + * In the case of proxy plugins, init() is called with a null IOrganizer. + */ +class QDLLEXPORT IOrganizer : public QObject +{ + Q_OBJECT + +public: + /** + * @brief information about a virtualised file + */ + struct FileInfo + { + QString filePath; /// full path to the file + QString archive; /// name of the archive if this file is in a BSA, otherwise this + /// is empty. + QStringList origins; /// list of origins containing this file. the first one is the + /// highest priority one + }; + +public: + virtual ~IOrganizer() {} + + // the directory for plugin data, typically plugins/data + // + static QString getPluginDataPath(); + + /** + * @return create a new nexus interface class + */ + virtual IModRepositoryBridge* createNexusBridge() const = 0; + + /** + * @return name of the active profile or an empty string if no profile is loaded (yet) + */ + virtual QString profileName() const = 0; + + /** + * @return the (absolute) path to the active profile or an empty string if no profile + * is loaded (yet) + */ + virtual QString profilePath() const = 0; + + /** + * @return the (absolute) path to the download directory + */ + virtual QString downloadsPath() const = 0; + + /** + * @return the (absolute) path to the overwrite directory + */ + virtual QString overwritePath() const = 0; + + /** + * @return the (absolute) path to the base directory + */ + virtual QString basePath() const = 0; + + /** + * @return the (absolute) path to the mods directory + */ + virtual QString modsPath() const = 0; + + /** + * @return the running version of Mod Organizer + */ + virtual VersionInfo appVersion() const = 0; + + /** + * @brief create a new mod with the specified name + * @param name name of the new mod + * @return an interface that can be used to modify the mod. nullptr if the user + * canceled + * @note a popup asking the user to merge, rename or replace the mod is displayed if + * the mod already exists. That has to happen on the main thread and MO2 will deadlock + * if it happens on any other. If this needs to be called from another thread, use + * IModList::getMod() to verify the mod-name is unused first + */ + virtual IModInterface* createMod(GuessedValue& name) = 0; + + /** + * @brief get the game plugin matching the specified game + * @param gameName name of the game short name + * @return a game plugin, or nullptr if there is no match + */ + virtual IPluginGame* getGame(const QString& gameName) const = 0; + + /** + * @brief let the organizer know that a mod has changed + * @param the mod that has changed + */ + virtual void modDataChanged(IModInterface* mod) = 0; + + /** + * @brief Check if a plugin is enabled. + * + * @param pluginName Plugin to check. + * + * @return true if the plugin is enabled, false otherwise. + */ + virtual bool isPluginEnabled(IPlugin* plugin) const = 0; + + /** + * @brief Check if a plugin is enabled. + * + * @param pluginName Name of the plugin to check. + * + * @return true if the plugin is enabled, false otherwise. + */ + virtual bool isPluginEnabled(QString const& pluginName) const = 0; + + /** + * @brief Retrieve the specified setting for a plugin. + * + * @param pluginName Name of the plugin for which to retrieve a setting. This should + * always be IPlugin::name() unless you have a really good reason to access settings + * of another mod. You can not access settings for a plugin that isn't installed. + * @param key identifier of the setting + * @return the setting + * @note an invalid qvariant is returned if the setting has not been declared + */ + virtual QVariant pluginSetting(const QString& pluginName, + const QString& key) const = 0; + + /** + * @brief Set the specified setting for a plugin. + * + * This automatically emit pluginSettingChanged(), so you do not have to do it + * yourself. + * + * @param pluginName Name of the plugin for which to change a value. This should + * always be IPlugin::name() unless you have a really good reason to access data of + * another mod AND if you can verify that plugin is actually installed. + * @param key Identifier of the setting. + * @param value Value to set. + * + * @throw an exception is thrown if pluginName doesn't refer to an installed plugin. + */ + virtual void setPluginSetting(const QString& pluginName, const QString& key, + const QVariant& value) = 0; + + /** + * @brief retrieve the specified persistent value for a plugin + * @param pluginName name of the plugin for which to retrieve a value. This should + * always be IPlugin::name() unless you have a really good reason to access data of + * another mod. + * @param key identifier of the value + * @param def default value to return if the key is not (yet) set + * @return the value + * @note A persistent is an arbitrary value that the plugin can set and retrieve that + * is persistently stored by the main application. There is no UI for the user to + * change this value but (s)he can directly access the storage + */ + virtual QVariant persistent(const QString& pluginName, const QString& key, + const QVariant& def = QVariant()) const = 0; + + /** + * @brief set the specified persistent value for a plugin + * @param pluginName name of the plugin for which to change a value. This should + * always be IPlugin::name() unless you have a really good reason to access data of + * another mod AND if you can verify that plugin is actually installed + * @param key identifier of the value + * @param value value to set + * @param sync if true the storage is immediately written to disc. This costs + * performance but is safer against data loss + * @throw an exception is thrown if pluginName doesn't refer to an installed plugin + */ + virtual void setPersistent(const QString& pluginName, const QString& key, + const QVariant& value, bool sync = true) = 0; + + /** + * @return path to a directory where plugin data should be stored. + */ + virtual QString pluginDataPath() const = 0; + + /** + * @brief install a mod archive at the specified location + * @param fileName absolute file name of the mod to install + * @param nameSuggestion suggested name for this mod. This can still be changed by the + * user + * @return interface to the newly installed mod or nullptr if no installation took + * place (failure or use canceled + */ + virtual IModInterface* installMod(const QString& fileName, + const QString& nameSuggestion = QString()) = 0; + + /** + * @brief resolves a path relative to the virtual data directory to its absolute real + * path + * @param fileName path to resolve + * @return the absolute real path or an empty string + */ + virtual QString resolvePath(const QString& fileName) const = 0; + + /** + * @brief retrieves a list of (virtual) subdirectories for a path (relative to the + * data directory) + * @param directoryName relative path to the directory to list + * @return a list of directory names + */ + virtual QStringList listDirectories(const QString& directoryName) const = 0; + + /** + * @brief find files in the virtual directory matching the filename filter + * @param path the path to search in + * @param filter filter function to match against + * @return a list of matching files + */ + virtual QStringList + findFiles(const QString& path, + const std::function& filter) const = 0; + + /** + * @brief find files in the virtual directory matching the filename filter + * @param path the path to search in + * @param filters list of glob filters to match against + * @return a list of matching files + */ + virtual QStringList findFiles(const QString& path, + const QStringList& filters) const = 0; + + /** + * @brief retrieve the file origins for the speicified file. The origins are listed + * with their internal name + * @return list of origins that contain the specified file, sorted by their priority + * @note the internal name of a mod can differ from the display name for + * disambiguation + */ + virtual QStringList getFileOrigins(const QString& fileName) const = 0; + + /** + * @brief find files in the virtual directory matching the specified complex filter + * @param path the path to search in + * @param filter filter function to match against + * @return a list of matching files + * @note this function is more expensive than the one filtering by name so use the + * other one if it suffices + */ + virtual QList + findFileInfos(const QString& path, + const std::function& filter) const = 0; + + /** + * @return a IFileTree representing the virtual file tree. + */ + virtual std::shared_ptr virtualFileTree() const = 0; + + /** + * @return interface to the download manager + */ + virtual MOBase::IDownloadManager* downloadManager() const = 0; + + /** + * @return interface to the list of plugins (esps, esms, and esls) + */ + virtual MOBase::IPluginList* pluginList() const = 0; + + /** + * @return interface to the list of mods + */ + virtual MOBase::IModList* modList() const = 0; + + /** + * @return interface to the active profile + */ + virtual MOBase::IProfile* profile() const = 0; + + /** + * @brief runs a program using the virtual filesystem + * + * @param executable either the name of an executable configured in MO, or + * a path to an executable; if relative, it is resolved + * against the game directory + * + * @param args arguments to pass to the executable; if this is empty + * and `executable` refers to a configured executable, + * its arguments are used + * + * @param cwd working directory for the executable; if this is empty, + * it is set to either the cwd set by the user in the + * configured executable (if any) or the directory of the + * executable + * + * @param profile name of the profile to use; defaults to the active + * profile + * + * @param forcedCustomOverwrite the name of the mod to set as the custom + * overwrite directory, regardless of what the + * profile has configured + * + * @param ignoreCustomOverwrite if `executable` is the name of a configured + * executable, ignores the executable's custom + * overwrite + * + * @return a handle to the process that was started or INVALID_HANDLE_VALUE + * if the application failed to start. + */ + virtual HANDLE startApplication(const QString& executable, + const QStringList& args = QStringList(), + const QString& cwd = "", const QString& profile = "", + const QString& forcedCustomOverwrite = "", + bool ignoreCustomOverwrite = false) = 0; + + /** + * @brief blocks until the given process has completed + * + * @param handle the process to wait for + * @param refresh whether MO should refresh after the process completed + * @param exitCode the exit code of the process after it ended + * + * @return true if the process completed successfully + * + * @note this will always show the lock overlay, regardless of whether the + * user has disabled locking in the setting, so use this with care; + * note that the lock overlay will always allow the user to unlock, in + * which case this will return false + */ + virtual bool waitForApplication(HANDLE handle, bool refresh = true, + LPDWORD exitCode = nullptr) const = 0; + + /** + * @brief Refresh the internal mods file structure from disk. This includes the mod + * list, the plugin list, data tab and other smaller things like problems button (same + * as pressing F5). + * + * @note The main part of the refresh of the mods file strcuture, modlist and + * pluginlist is done asynchronously, so you should not expect them to be up-to-date + * when this function returns. + * + * @param saveChanges If true, the relevant profile information is saved first + * (enabled mods and their order). + */ + virtual void refresh(bool saveChanges = true) = 0; + + /** + * @brief get the currently managed game info + */ + virtual MOBase::IPluginGame const* managedGame() const = 0; + + /** + * @brief Add a new callback to be called when an application is about to be run. + * + * Parameters of the callback: + * - Path (absolute) to the application to be run. + * + * The callback can return false to prevent the application from being launched. + * + * @param func Function to be called when an application is run. + */ + virtual bool onAboutToRun(const std::function& func) = 0; + + /** + * @brief Add a new callback to be called when an has finished running. + * + * Parameters of the callback: + * - Path (absolute) to the application that has finished running. + * - Exit code of the application. + * + * + * @param func Function to be called when an application is run. + */ + virtual bool + onFinishedRun(const std::function& func) = 0; + + /** + * @brief Add a new callback to be called when the user interface has been + * initialized. + * + * Parameters of the callback: + * - The main window of the application. + * + * @param func Function to be called when the user interface has been initialized. + */ + virtual bool + onUserInterfaceInitialized(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a new profile is created. + * + * Parameters of the callback: + * - The created profile (can be a temporary object, so it should not be stored). + * + * @param func Function to be called when a profile is created. + * + */ + virtual bool onProfileCreated(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a profile is renamed. + * + * Parameters of the callback: + * - The renamed profile. + * - The old name of the profile. + * - The new name of the profile. + * + * @param func Function to be called when a profile is renamed. + * + */ + virtual bool onProfileRenamed( + std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a profile is removed. + * + * Parameters of the callback: + * - The name of the removed profile. + * + * The function is called after the profile has been removed, so the profile is not + * accessible anymore. + * + * @param func Function to be called when a profile is removed. + * + */ + virtual bool onProfileRemoved(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when the current profile is changed. + * + * Parameters of the callback: + * - The old profile. Can be a null pointer if no profile was set (e.g. at startup). + * - The new profile, cannot be null. + * + * The function is called when the profile is changed but some operations related to + * the profile might not be finished when this is called (e.g., the virtual file + * system might not be up-to-date). + * + * @param func Function to be called when the current profile change. + * + */ + virtual bool + onProfileChanged(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a plugin setting is changed. + * + * Parameters of the callback: + * - Name of the plugin. + * - Name of the setting. + * - Old value of the setting. Can be a default-constructed (invalid) QVariant if + * the setting did not exist before. + * - New value of the setting. Can be a default-constructed (invalid) QVariant if + * the setting has been removed. + * + * @param func Function to be called when a plugin setting is changed. + */ + virtual bool onPluginSettingChanged( + std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a plugin is enabled. + * + * Parameters of the callback: + * - The enabled plugin. + * + * @param func Function to be called when a plugin is enabled. + */ + virtual bool onPluginEnabled(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when the specified plugin is enabled. + * + * @param name Name of the plugin to watch. + * @param func Function to be called when a plugin is enabled. + */ + virtual bool onPluginEnabled(const QString& pluginName, + std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when a plugin is disabled. + * + * Parameters of the callback: + * - The disabled plugin. + * + * @param func Function to be called when a plugin is disabled. + */ + virtual bool onPluginDisabled(std::function const& func) = 0; + + /** + * @brief Add a new callback to be called when the specified plugin is disabled. + * + * @param name Name of the plugin to watch. + * @param func Function to be called when a plugin is disabled. + */ + virtual bool onPluginDisabled(const QString& pluginName, + std::function const& func) = 0; +}; + +} // namespace MOBase + +namespace MOBase::details +{ +// called from MO +QDLLEXPORT void setPluginDataPath(const QString& s); +} // namespace MOBase::details + +#endif // IMOINFO_H diff --git a/src/iplugin.h b/src/iplugin.h index 899a9179..aae89dcc 100644 --- a/src/iplugin.h +++ b/src/iplugin.h @@ -1,141 +1,146 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGIN_H -#define IPLUGIN_H - - -#include "versioninfo.h" -#include "imoinfo.h" -#include "pluginsetting.h" -#include "pluginrequirements.h" -#include -#include -#include -#include - -namespace MOBase { - -class IPlugin -{ -public: - - // For easier access in child class: - using Requirements = PluginRequirementFactory; - -public: - virtual ~IPlugin() {} - - /** - * @brief Initialize the plugin. - * - * Note that this function may never be called if no IOrganizer is available - * at that time, such as when creating the first instance in MO. For proxy - * plugins, init() is always called, but given a null IOrganizer. - * - * Plugins will probably want to store the organizer pointer. It is guaranteed - * to be valid as long as the plugin is loaded. - * - * These functions may be called before init(): - * - name() - * - see IPluginGame for more - * - * @return false if the plugin could not be initialized, true otherwise. - */ - virtual bool init(IOrganizer *organizer) = 0; - - /** - * this function may be called before init() - * - * @return the internal name of this plugin (used for example in the settings menu). - * - * @note Please ensure you use a name that will not change. Do NOT include a version number in the - * name. Do NOT use a localizable string (tr()) here. Settings for example are tied to this name, - * if you rename your plugin you lose settings users made. - */ - virtual QString name() const = 0; - - /** - * @return the localized name for this plugin. - * - * @note Unlike name(), this method can (and should!) return a localized name for the plugin. - * @note This method returns name() by default. - */ - virtual QString localizedName() const { return name(); } - - /** - * @brief Retrieve the name of the master plugin of this plugin. - * - * It is often easier to implement a functionality as multiple plugins in MO2, but ship the - * plugins together, e.g. as a Python module or using `createFunctions()`. In this case, having - * a master plugin (one of the plugin, or a separate one) tells MO2 that these plugins are - * linked and should also be displayed together in the UI. If MO2 ever implements automatic - * updates for plugins, the `master()` plugin will also be used for this purpose. - * - * @return the name of the master plugin of this plugin, or an empty string if this plugin does not have - * a master. - */ - virtual QString master() const { return ""; } - - /** - * @brief Retrieve the requirements for the plugins. - * - * This method is called right after init(). - * - * @return the requirements for this plugin. - */ - virtual std::vector> requirements() const { return {}; } - - /** - * @return the author of this plugin. - */ - virtual QString author() const = 0; - - /** - * @return a short description of the plugin to be displayed to the user. - */ - virtual QString description() const = 0; - - /** - * @return the version of the plugin. This can be used to detect outdated versions of plugins. - */ - virtual VersionInfo version() const = 0; - - /** - * @return the list of configurable settings for this plugin (in the user interface). The list may be - * empty. - * - * @note Plugin can store "hidden" (from the user) settings using IOrganizer::persistent / IOrganizer::setPersistent. - */ - virtual QList settings() const = 0; - - /** - * @return whether the plugin should be enabled by default - */ - virtual bool enabledByDefault() const { return true; } - -}; - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPlugin, "com.tannin.ModOrganizer.Plugin/2.0") - -#endif // IPLUGIN_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGIN_H +#define IPLUGIN_H + +#include "imoinfo.h" +#include "pluginrequirements.h" +#include "pluginsetting.h" +#include "versioninfo.h" +#include +#include +#include +#include + +namespace MOBase +{ + +class IPlugin +{ +public: + // For easier access in child class: + using Requirements = PluginRequirementFactory; + +public: + virtual ~IPlugin() {} + + /** + * @brief Initialize the plugin. + * + * Note that this function may never be called if no IOrganizer is available + * at that time, such as when creating the first instance in MO. For proxy + * plugins, init() is always called, but given a null IOrganizer. + * + * Plugins will probably want to store the organizer pointer. It is guaranteed + * to be valid as long as the plugin is loaded. + * + * These functions may be called before init(): + * - name() + * - see IPluginGame for more + * + * @return false if the plugin could not be initialized, true otherwise. + */ + virtual bool init(IOrganizer* organizer) = 0; + + /** + * this function may be called before init() + * + * @return the internal name of this plugin (used for example in the settings menu). + * + * @note Please ensure you use a name that will not change. Do NOT include a version + * number in the name. Do NOT use a localizable string (tr()) here. Settings for + * example are tied to this name, if you rename your plugin you lose settings users + * made. + */ + virtual QString name() const = 0; + + /** + * @return the localized name for this plugin. + * + * @note Unlike name(), this method can (and should!) return a localized name for the + * plugin. + * @note This method returns name() by default. + */ + virtual QString localizedName() const { return name(); } + + /** + * @brief Retrieve the name of the master plugin of this plugin. + * + * It is often easier to implement a functionality as multiple plugins in MO2, but + * ship the plugins together, e.g. as a Python module or using `createFunctions()`. In + * this case, having a master plugin (one of the plugin, or a separate one) tells MO2 + * that these plugins are linked and should also be displayed together in the UI. If + * MO2 ever implements automatic updates for plugins, the `master()` plugin will also + * be used for this purpose. + * + * @return the name of the master plugin of this plugin, or an empty string if this + * plugin does not have a master. + */ + virtual QString master() const { return ""; } + + /** + * @brief Retrieve the requirements for the plugins. + * + * This method is called right after init(). + * + * @return the requirements for this plugin. + */ + virtual std::vector> requirements() const + { + return {}; + } + + /** + * @return the author of this plugin. + */ + virtual QString author() const = 0; + + /** + * @return a short description of the plugin to be displayed to the user. + */ + virtual QString description() const = 0; + + /** + * @return the version of the plugin. This can be used to detect outdated versions of + * plugins. + */ + virtual VersionInfo version() const = 0; + + /** + * @return the list of configurable settings for this plugin (in the user interface). + * The list may be empty. + * + * @note Plugin can store "hidden" (from the user) settings using + * IOrganizer::persistent / IOrganizer::setPersistent. + */ + virtual QList settings() const = 0; + + /** + * @return whether the plugin should be enabled by default + */ + virtual bool enabledByDefault() const { return true; } +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPlugin, "com.tannin.ModOrganizer.Plugin/2.0") + +#endif // IPLUGIN_H diff --git a/src/iplugindiagnose.h b/src/iplugindiagnose.h index 12dd3c9b..5a9340ce 100644 --- a/src/iplugindiagnose.h +++ b/src/iplugindiagnose.h @@ -1,108 +1,103 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2013 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGINDIAGNOSE_H -#define IPLUGINDIAGNOSE_H - - -#include -#include -#include -#include -#include - -namespace MOBase { - - -/** - * @brief A plugin that creates problem reports to be displayed in the UI. - * This can be used to report problems related to the same plugin (which implements further - * interfaces) or as a stand-alone diagnosis tool. - * This does not derive from IPlugin to prevent multiple inheritance issues. For stand-alone - * diagnosis plugins, derive from IPlugin and IPluginDiagnose - */ -class IPluginDiagnose { -public: - - /** - * @return a list of keys of active problems - * @note this is not expected to be called if isActive returns false - */ - virtual std::vector activeProblems() const = 0; - - /** - * @brief retrieve a short description for the specified problem for the overview page. HTML syntax is supported. - * @param key the identifier of the problem as reported by activeProblems() - * @return a (short) description text - * @throw should throw an exception if the key is not valid - */ - virtual QString shortDescription(unsigned int key) const = 0; - - /** - * @brief retrieve the full description for the specified problem. HTML syntax is supported. - * @param key the identifier of the problem as reported by activeProblems() - * @return a (long) description text - * @throw should throw an exception if the key is not valid - */ - virtual QString fullDescription(unsigned int key) const = 0; - - /** - * @param key the identifier of the problem as reported by activeProblems() - * @return true if this plugin provides a guide to fix the issue - * @throw should throw an exception if the key is not valid - */ - virtual bool hasGuidedFix(unsigned int key) const = 0; - - /** - * @brief start the guided fix for the specified problem - * @param key the identifier of the problem as reported by activeProblems() - * @throw should throw an exception if the key is not valid or if there is no guided fix for the issue - */ - virtual void startGuidedFix(unsigned int key) const = 0; - - /** - * @brief Register the callback to be called when this plugin is invalidated. - * - * Only one callback can be activate at a time. - */ - void onInvalidated(std::function callback) { - m_OnInvalidated = callback; - } - - virtual ~IPluginDiagnose() { } - -protected: - - void invalidate() { - m_OnInvalidated(); - } - -private: - - std::function m_OnInvalidated; - -}; - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginDiagnose, "com.tannin.ModOrganizer.PluginDiagnose/1.1") - -#endif // IPLUGINDIAGNOSE_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2013 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINDIAGNOSE_H +#define IPLUGINDIAGNOSE_H + +#include +#include +#include +#include +#include + +namespace MOBase +{ + +/** + * @brief A plugin that creates problem reports to be displayed in the UI. + * This can be used to report problems related to the same plugin (which implements + * further interfaces) or as a stand-alone diagnosis tool. This does not derive from + * IPlugin to prevent multiple inheritance issues. For stand-alone diagnosis plugins, + * derive from IPlugin and IPluginDiagnose + */ +class IPluginDiagnose +{ +public: + /** + * @return a list of keys of active problems + * @note this is not expected to be called if isActive returns false + */ + virtual std::vector activeProblems() const = 0; + + /** + * @brief retrieve a short description for the specified problem for the overview + * page. HTML syntax is supported. + * @param key the identifier of the problem as reported by activeProblems() + * @return a (short) description text + * @throw should throw an exception if the key is not valid + */ + virtual QString shortDescription(unsigned int key) const = 0; + + /** + * @brief retrieve the full description for the specified problem. HTML syntax is + * supported. + * @param key the identifier of the problem as reported by activeProblems() + * @return a (long) description text + * @throw should throw an exception if the key is not valid + */ + virtual QString fullDescription(unsigned int key) const = 0; + + /** + * @param key the identifier of the problem as reported by activeProblems() + * @return true if this plugin provides a guide to fix the issue + * @throw should throw an exception if the key is not valid + */ + virtual bool hasGuidedFix(unsigned int key) const = 0; + + /** + * @brief start the guided fix for the specified problem + * @param key the identifier of the problem as reported by activeProblems() + * @throw should throw an exception if the key is not valid or if there is no guided + * fix for the issue + */ + virtual void startGuidedFix(unsigned int key) const = 0; + + /** + * @brief Register the callback to be called when this plugin is invalidated. + * + * Only one callback can be activate at a time. + */ + void onInvalidated(std::function callback) { m_OnInvalidated = callback; } + + virtual ~IPluginDiagnose() {} + +protected: + void invalidate() { m_OnInvalidated(); } + +private: + std::function m_OnInvalidated; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginDiagnose, + "com.tannin.ModOrganizer.PluginDiagnose/1.1") + +#endif // IPLUGINDIAGNOSE_H diff --git a/src/ipluginfilemapper.h b/src/ipluginfilemapper.h index 64fe22e1..350aa71c 100644 --- a/src/ipluginfilemapper.h +++ b/src/ipluginfilemapper.h @@ -18,34 +18,32 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef IPLUGINFILEMAPPER_H #define IPLUGINFILEMAPPER_H - #include "filemapping.h" #include "iplugin.h" -namespace MOBase { - +namespace MOBase +{ /** * brief A plugin that adds virtual file links * This does not derive from IPlugin to prevent multiple inheritance issues. * For stand-alone mapping plugins, derive from IPlugin and IPluginDiagnose */ -class IPluginFileMapper { +class IPluginFileMapper +{ public: - /** * @return a list of file maps */ virtual MappingType mappings() const = 0; - }; -} // namespace MOBase +} // namespace MOBase -Q_DECLARE_INTERFACE(MOBase::IPluginFileMapper, "com.tannin.ModOrganizer.PluginFileMapper/2.0") +Q_DECLARE_INTERFACE(MOBase::IPluginFileMapper, + "com.tannin.ModOrganizer.PluginFileMapper/2.0") -#endif // IPLUGINDIAGNOSE_H +#endif // IPLUGINDIAGNOSE_H diff --git a/src/iplugingame.h b/src/iplugingame.h index d4f7add4..675ed294 100644 --- a/src/iplugingame.h +++ b/src/iplugingame.h @@ -1,342 +1,355 @@ -#ifndef IPLUGINGAME_H -#define IPLUGINGAME_H - - -#include "iplugin.h" -#include "isavegame.h" -#include "executableinfo.h" - -class QIcon; -class QUrl; -class QString; - -#include -#include -#include -#include -#include -#include - -namespace MOBase { - -// Game plugins can be loaded without an IOrganizer being available, in which -// case detectGame() is called, but not init(). -// -// These functions may be called before init() (after detectGame()): -// - gameName() -// - isInstalled() -// - gameIcon() -// - gameDirectory() -// - dataDirectory() -// - gameVariants() -// - looksValid() -// - see IPlugin::init() for more -// -// -class IPluginGame : public QObject, public IPlugin -{ - Q_INTERFACES(IPlugin) - -public: - enum class LoadOrderMechanism { - FileTime, - PluginsTxt - }; - - enum class SortMechanism { - NONE, - MLOX, - BOSS, - LOOT - }; - - enum ProfileSetting { - MODS = 0x01, - CONFIGURATION = 0x02, - SAVEGAMES = 0x04, - PREFER_DEFAULTS = 0x08 - }; - - Q_DECLARE_FLAGS(ProfileSettings, ProfileSetting) - -public: - - // Game plugin should not have requirements: - std::vector> requirements() const final override { return {}; } - - // Game plugin can not be disabled - bool enabledByDefault() const final override { return true; } - - /** - * this function may be called before init() - * - * @return name of the game - */ - virtual QString gameName() const = 0; - - template - T *feature() const { - auto list = featureList(); - auto iter = list.find(typeid(T)); - if (iter != list.end()) { - try { - return std::any_cast(iter->second); - } catch (const std::bad_any_cast&) { - // don't use log::error() here so log.h and fmt aren't pulled into - // plugins - qCritical( - "failed to retrieve feature type %s (got %s)", - typeid(T).name(), typeid(iter->second).name()); - return nullptr; - } - } else { - return nullptr; - } - } - - /** - * @brief Detect the game. - * - * This method is the first method called for game plugins (before init()). The - * following methods can be called after detectGame() but before init(): - * - gameName() - * - isInstalled() - * - gameIcon() - * - gameDirectory() - * - dataDirectory() - * - gameVariants() - * - looksValid() - * - see IPlugin::init() for more - */ - virtual void detectGame() = 0; - - /** - * @brief initialize a profile for this game - * @param directory the directory where the profile is to be initialized - * @param settings parameters for how the profile should be initialized - * @note the MO app does not yet support virtualizing only specific aspects but plugins should be written with this future functionality in mind - * @note this function will be used to initially create a profile, potentially to repair it or upgrade/downgrade it so the implementations - * have to gracefully handle the case that the directory already contains files! - */ - virtual void initializeProfile(const QDir &directory, ProfileSettings settings) const = 0; - - /** - * @brief List save games in the specified folder. - * - * @param folder The folder containing the saves. - * - * @return the list of saves in the specified folder. - */ - /** - * @return file extension of save games for this game - */ - virtual std::vector> listSaves(QDir folder) const = 0; - - /** - * this function may be called before init() - * - * @return true if this game has been discovered as installed, false otherwise - */ - virtual bool isInstalled() const = 0; - - /** - * this function may be called before init() - * - * @return an icon for this game - */ - virtual QIcon gameIcon() const = 0; - - /** - * this function may be called before init() - * - * @return directory to the game installation - */ - virtual QDir gameDirectory() const = 0; - - /** - * this function may be called before init() - * - * @return directory where the game expects to find its data files - */ - virtual QDir dataDirectory() const = 0; - - /** - * this function may be called before init() - * - * @return directories where we may find data files outside the main location - */ - virtual QMap secondaryDataDirectories() const = 0; - - /** - * @brief set the path to the managed game - * @param path to the game - * @note this will be called by by MO to set the concrete path of the game. This is particularly - * relevant if the path wasn't auto-detected but had to be set manually by the user - */ - virtual void setGamePath(const QString &path) = 0; - - /** - * @return directory of the documents folder where configuration files and such for this game reside - */ - virtual QDir documentsDirectory() const = 0; - - /** - * @return path to where save games are stored. - */ - virtual QDir savesDirectory() const = 0; - - /** - * @return list of automatically discovered executables of the game itself and tools surrounding it - */ - virtual QList executables() const = 0; - - /** - * @brief Get the default list of libraries that can be force loaded with executables - */ - virtual QList executableForcedLoads() const = 0; - - /** - * @return steam app id for this game. Should be empty for games not available on steam - * @note if a game is available in multiple versions those might have different app ids. - * the plugin should try to return the right one - */ - virtual QString steamAPPId() const = 0; - - /** - * @return list of plugins that are part of the game and not considered optional - */ - virtual QStringList primaryPlugins() const = 0; - - /** - * this function may be called before init() - * - * @return list of game variants - * @note if there are multiple variants of a game (and the variants make a difference to the - * plugin) like a regular one and a GOTY-edition the plugin can return a list of them and - * the user gets to chose which one he owns. - */ - virtual QStringList gameVariants() const = 0; - - /** - * @brief if there are multiple game variants (returned by gameVariants) this will get called - * on start with the user-selected game edition - * @param variant the game edition selected by the user - */ - virtual void setGameVariant(const QString &variant) = 0; - - /** - * @brief Get the name of the executable that gets run - */ - virtual QString binaryName() const = 0; - - /** - * @brief Get the 'short' name of the game - * - * the short name of the game is used for - save ames, registry entries and - * nexus mod pages as far as I can see. - */ - virtual QString gameShortName() const = 0; - - /** - * @brief Get any primary alternative 'short' name for the game - * - * this is used to determine if a Nexus (or other) download source should be considered - * a 'primary' source for the game so that it isn't flagged as an alternative source - */ - virtual QStringList primarySources() const = 0; - - /** - * @brief Get any valid 'short' name for the game - * - * this is used to determine if a Nexus download is valid for the current game - * not all game variants have their own nexus pages and others can handle downloads - * from other nexus game pages and should be allowed - * - * the short name should be considered the primary handler for a directly supported game - * for puroses of auto-launching an instance - */ - virtual QStringList validShortNames() const = 0; - - /** - * @brief Get the 'short' name of the game - * - * the short name of the game is used for - save ames, registry entries and - * nexus mod pages as far as I can see. - */ - virtual QString gameNexusName() const = 0; - - /** - * @brief Get the list of .ini files this game uses - * - * @note It is important that the 'main' .ini file comes first in this list - */ - virtual QStringList iniFiles() const = 0; - - /** - * @brief Get a list of esp/esm files that are part of known dlcs - */ - virtual QStringList DLCPlugins() const = 0; - - /** - * @brief Get the current list of active Creation Club plugins - */ - virtual QStringList CCPlugins() const = 0; - - /* - * @brief determine the load order mechanism used by this game. - * - * @note this may throw an exception if the mechanism can't be determined - */ - virtual LoadOrderMechanism loadOrderMechanism() const = 0; - - /** - * @brief determine the sorting mech - */ - virtual SortMechanism sortMechanism() const = 0; - - /** - * @brief Get the Nexus ID of Mod Organizer - */ - virtual int nexusModOrganizerID() const = 0; - - /** - * @brief Get the Nexus Game ID - */ - virtual int nexusGameID() const = 0; - - /** - * this function may be called before init() - * - * @brief See if the supplied directory looks like a valid game - */ - virtual bool looksValid(QDir const &) const = 0; - - /** - * @brief Get version of program - */ - virtual QString gameVersion() const = 0; - - /** - * @brief Get the name of the game launcher - */ - virtual QString getLauncherName() const = 0; - - /** - * @brief Get a URL for the support page for the game - */ - virtual QString getSupportURL() const { return ""; } - -protected: - - virtual std::map featureList() const = 0; - -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(IPluginGame::ProfileSettings) - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginGame, "com.tannin.ModOrganizer.PluginGame/2.0") -Q_DECLARE_METATYPE(MOBase::IPluginGame const *) - -#endif // IPLUGINGAME_H +#ifndef IPLUGINGAME_H +#define IPLUGINGAME_H + +#include "executableinfo.h" +#include "iplugin.h" +#include "isavegame.h" + +class QIcon; +class QUrl; +class QString; + +#include +#include +#include +#include +#include +#include + +namespace MOBase +{ + +// Game plugins can be loaded without an IOrganizer being available, in which +// case detectGame() is called, but not init(). +// +// These functions may be called before init() (after detectGame()): +// - gameName() +// - isInstalled() +// - gameIcon() +// - gameDirectory() +// - dataDirectory() +// - gameVariants() +// - looksValid() +// - see IPlugin::init() for more +// +// +class IPluginGame : public QObject, public IPlugin +{ + Q_INTERFACES(IPlugin) + +public: + enum class LoadOrderMechanism + { + FileTime, + PluginsTxt + }; + + enum class SortMechanism + { + NONE, + MLOX, + BOSS, + LOOT + }; + + enum ProfileSetting + { + MODS = 0x01, + CONFIGURATION = 0x02, + SAVEGAMES = 0x04, + PREFER_DEFAULTS = 0x08 + }; + + Q_DECLARE_FLAGS(ProfileSettings, ProfileSetting) + +public: + // Game plugin should not have requirements: + std::vector> + requirements() const final override + { + return {}; + } + + // Game plugin can not be disabled + bool enabledByDefault() const final override { return true; } + + /** + * this function may be called before init() + * + * @return name of the game + */ + virtual QString gameName() const = 0; + + template + T* feature() const + { + auto list = featureList(); + auto iter = list.find(typeid(T)); + if (iter != list.end()) { + try { + return std::any_cast(iter->second); + } catch (const std::bad_any_cast&) { + // don't use log::error() here so log.h and fmt aren't pulled into + // plugins + qCritical("failed to retrieve feature type %s (got %s)", typeid(T).name(), + typeid(iter->second).name()); + return nullptr; + } + } else { + return nullptr; + } + } + + /** + * @brief Detect the game. + * + * This method is the first method called for game plugins (before init()). The + * following methods can be called after detectGame() but before init(): + * - gameName() + * - isInstalled() + * - gameIcon() + * - gameDirectory() + * - dataDirectory() + * - gameVariants() + * - looksValid() + * - see IPlugin::init() for more + */ + virtual void detectGame() = 0; + + /** + * @brief initialize a profile for this game + * @param directory the directory where the profile is to be initialized + * @param settings parameters for how the profile should be initialized + * @note the MO app does not yet support virtualizing only specific aspects but + * plugins should be written with this future functionality in mind + * @note this function will be used to initially create a profile, potentially to + * repair it or upgrade/downgrade it so the implementations have to gracefully handle + * the case that the directory already contains files! + */ + virtual void initializeProfile(const QDir& directory, + ProfileSettings settings) const = 0; + + /** + * @brief List save games in the specified folder. + * + * @param folder The folder containing the saves. + * + * @return the list of saves in the specified folder. + */ + /** + * @return file extension of save games for this game + */ + virtual std::vector> + listSaves(QDir folder) const = 0; + + /** + * this function may be called before init() + * + * @return true if this game has been discovered as installed, false otherwise + */ + virtual bool isInstalled() const = 0; + + /** + * this function may be called before init() + * + * @return an icon for this game + */ + virtual QIcon gameIcon() const = 0; + + /** + * this function may be called before init() + * + * @return directory to the game installation + */ + virtual QDir gameDirectory() const = 0; + + /** + * this function may be called before init() + * + * @return directory where the game expects to find its data files + */ + virtual QDir dataDirectory() const = 0; + + /** + * this function may be called before init() + * + * @return directories where we may find data files outside the main location + */ + virtual QMap secondaryDataDirectories() const = 0; + + /** + * @brief set the path to the managed game + * @param path to the game + * @note this will be called by by MO to set the concrete path of the game. This is + * particularly relevant if the path wasn't auto-detected but had to be set manually + * by the user + */ + virtual void setGamePath(const QString& path) = 0; + + /** + * @return directory of the documents folder where configuration files and such for + * this game reside + */ + virtual QDir documentsDirectory() const = 0; + + /** + * @return path to where save games are stored. + */ + virtual QDir savesDirectory() const = 0; + + /** + * @return list of automatically discovered executables of the game itself and tools + * surrounding it + */ + virtual QList executables() const = 0; + + /** + * @brief Get the default list of libraries that can be force loaded with executables + */ + virtual QList executableForcedLoads() const = 0; + + /** + * @return steam app id for this game. Should be empty for games not available on + * steam + * @note if a game is available in multiple versions those might have different app + * ids. the plugin should try to return the right one + */ + virtual QString steamAPPId() const = 0; + + /** + * @return list of plugins that are part of the game and not considered optional + */ + virtual QStringList primaryPlugins() const = 0; + + /** + * this function may be called before init() + * + * @return list of game variants + * @note if there are multiple variants of a game (and the variants make a difference + * to the plugin) like a regular one and a GOTY-edition the plugin can return a list + * of them and the user gets to chose which one he owns. + */ + virtual QStringList gameVariants() const = 0; + + /** + * @brief if there are multiple game variants (returned by gameVariants) this will get + * called on start with the user-selected game edition + * @param variant the game edition selected by the user + */ + virtual void setGameVariant(const QString& variant) = 0; + + /** + * @brief Get the name of the executable that gets run + */ + virtual QString binaryName() const = 0; + + /** + * @brief Get the 'short' name of the game + * + * the short name of the game is used for - save ames, registry entries and + * nexus mod pages as far as I can see. + */ + virtual QString gameShortName() const = 0; + + /** + * @brief Get any primary alternative 'short' name for the game + * + * this is used to determine if a Nexus (or other) download source should be + * considered a 'primary' source for the game so that it isn't flagged as an + * alternative source + */ + virtual QStringList primarySources() const = 0; + + /** + * @brief Get any valid 'short' name for the game + * + * this is used to determine if a Nexus download is valid for the current game + * not all game variants have their own nexus pages and others can handle downloads + * from other nexus game pages and should be allowed + * + * the short name should be considered the primary handler for a directly supported + * game for puroses of auto-launching an instance + */ + virtual QStringList validShortNames() const = 0; + + /** + * @brief Get the 'short' name of the game + * + * the short name of the game is used for - save ames, registry entries and + * nexus mod pages as far as I can see. + */ + virtual QString gameNexusName() const = 0; + + /** + * @brief Get the list of .ini files this game uses + * + * @note It is important that the 'main' .ini file comes first in this list + */ + virtual QStringList iniFiles() const = 0; + + /** + * @brief Get a list of esp/esm files that are part of known dlcs + */ + virtual QStringList DLCPlugins() const = 0; + + /** + * @brief Get the current list of active Creation Club plugins + */ + virtual QStringList CCPlugins() const = 0; + + /* + * @brief determine the load order mechanism used by this game. + * + * @note this may throw an exception if the mechanism can't be determined + */ + virtual LoadOrderMechanism loadOrderMechanism() const = 0; + + /** + * @brief determine the sorting mech + */ + virtual SortMechanism sortMechanism() const = 0; + + /** + * @brief Get the Nexus ID of Mod Organizer + */ + virtual int nexusModOrganizerID() const = 0; + + /** + * @brief Get the Nexus Game ID + */ + virtual int nexusGameID() const = 0; + + /** + * this function may be called before init() + * + * @brief See if the supplied directory looks like a valid game + */ + virtual bool looksValid(QDir const&) const = 0; + + /** + * @brief Get version of program + */ + virtual QString gameVersion() const = 0; + + /** + * @brief Get the name of the game launcher + */ + virtual QString getLauncherName() const = 0; + + /** + * @brief Get a URL for the support page for the game + */ + virtual QString getSupportURL() const { return ""; } + +protected: + virtual std::map featureList() const = 0; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(IPluginGame::ProfileSettings) + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginGame, "com.tannin.ModOrganizer.PluginGame/2.0") +Q_DECLARE_METATYPE(MOBase::IPluginGame const*) + +#endif // IPLUGINGAME_H diff --git a/src/iplugininstaller.cpp b/src/iplugininstaller.cpp index 2455d94f..79e62472 100644 --- a/src/iplugininstaller.cpp +++ b/src/iplugininstaller.cpp @@ -1,18 +1,18 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with Mod Organizer. If not, see . -*/ +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with Mod Organizer. If not, see . +*/ diff --git a/src/iplugininstaller.h b/src/iplugininstaller.h index bf94e114..80d6fdc7 100644 --- a/src/iplugininstaller.h +++ b/src/iplugininstaller.h @@ -1,155 +1,156 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGININSTALLER_H -#define IPLUGININSTALLER_H - -#include - -#include "iplugin.h" -#include "imodinterface.h" -#include "ifiletree.h" - -namespace MOBase { - - -class IInstallationManager; - - -class IPluginInstaller : public IPlugin { - - Q_INTERFACES(IPlugin) - -public: - - enum EInstallResult { - RESULT_SUCCESS, - RESULT_FAILED, - RESULT_CANCELED, - RESULT_MANUALREQUESTED, - RESULT_NOTATTEMPTED, - RESULT_SUCCESSCANCEL - }; - -public: - - IPluginInstaller() : m_ParentWidget(nullptr), m_InstallationManager(nullptr) {} - - /** - * @brief Retrieve the priority of this installer. If multiple installers are able - * to handle an archive, the one with the highest priority wins. - * - * @return the priority of this installer. - */ - virtual unsigned int priority() const = 0; - - /** - * @return true if this plugin should be treated as a manual installer if the user - * explicitly requested one. A manual installer should offer the user maximum amount of - * customizability. - */ - virtual bool isManualInstaller() const = 0; - - /** - * @brief Method calls at the start of the installation process, before any other methods. - * This method is only called once per installation process, even for recursive - * installations (e.g. with the bundle installer). - * - * @param archive Path to the archive that is going to be installed. - * @param reinstallation True if this is a reinstallation, false otherwise. - * @param mod A currently installed mod corresponding to the archive being installed, or a null - * if there is no such mod. - * - * @note If `reinstallation` is true, then the given mod is the mod being reinstalled (the one - * selected by the user). If `reinstallation` is false and `currentMod` is not null, then - * it corresponds to a mod MO2 thinks corresponds to the archive (e.g. based on matching Nexus ID - * or name). - * @note The default implementation does nothing. - */ - virtual void onInstallationStart( - [[maybe_unused]] QString const &archive, - [[maybe_unused]] bool reinstallation, - [[maybe_unused]] IModInterface *currentMod) {} - - /** - * @brief Method calls at the end of the installation process. This method is only called once - * per installation process, even for recursive installations (e.g. with the bundle installer). - * - * @param result The result of the installation. - * @param mod If the installation succeeded (result is RESULT_SUCCESS), contains the newly - * installed mod, otherwise it contains a null pointer. - * - * @note The default implementation does nothing. - */ - virtual void onInstallationEnd( - [[maybe_unused]] EInstallResult result, - [[maybe_unused]] IModInterface *newMod) {} - - /** - * @brief Test if the archive represented by the tree parameter can be installed through this - * installer. - * - * @param tree a directory tree representing the archive. - * - * @return true if this installer can handle the archive. - */ - virtual bool isArchiveSupported(std::shared_ptr tree) const = 0; - - /** - * @brief Sets the widget that the tool should use as the parent whenever - * it creates a new modal dialog. - * - * @param widget The new parent widget. - */ - virtual void setParentWidget(QWidget *widget) { m_ParentWidget = widget; } - - /** - * @brief Sets the installation manager responsible for the installation process - * it can be used by plugins to access utility functions. - * - * @param manager The new installation manager. - */ - void setInstallationManager(IInstallationManager *manager) { m_InstallationManager = manager; } - -protected: - - /** - * @return the parent widget that the tool should use to create new dialogs and widgets. - */ - QWidget *parentWidget() const { return m_ParentWidget; } - - /** - * @return the manager responsible for the installation process. - */ - IInstallationManager *manager() const { return m_InstallationManager; } - -private: - - QWidget *m_ParentWidget; - IInstallationManager *m_InstallationManager; - -}; - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginInstaller, "com.tannin.ModOrganizer.PluginInstaller/1.0") - -#endif // IPLUGININSTALLER_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGININSTALLER_H +#define IPLUGININSTALLER_H + +#include + +#include "ifiletree.h" +#include "imodinterface.h" +#include "iplugin.h" + +namespace MOBase +{ + +class IInstallationManager; + +class IPluginInstaller : public IPlugin +{ + + Q_INTERFACES(IPlugin) + +public: + enum EInstallResult + { + RESULT_SUCCESS, + RESULT_FAILED, + RESULT_CANCELED, + RESULT_MANUALREQUESTED, + RESULT_NOTATTEMPTED, + RESULT_SUCCESSCANCEL + }; + +public: + IPluginInstaller() : m_ParentWidget(nullptr), m_InstallationManager(nullptr) {} + + /** + * @brief Retrieve the priority of this installer. If multiple installers are able + * to handle an archive, the one with the highest priority wins. + * + * @return the priority of this installer. + */ + virtual unsigned int priority() const = 0; + + /** + * @return true if this plugin should be treated as a manual installer if the user + * explicitly requested one. A manual installer should offer the user maximum amount + * of customizability. + */ + virtual bool isManualInstaller() const = 0; + + /** + * @brief Method calls at the start of the installation process, before any other + * methods. This method is only called once per installation process, even for + * recursive installations (e.g. with the bundle installer). + * + * @param archive Path to the archive that is going to be installed. + * @param reinstallation True if this is a reinstallation, false otherwise. + * @param mod A currently installed mod corresponding to the archive being installed, + * or a null if there is no such mod. + * + * @note If `reinstallation` is true, then the given mod is the mod being reinstalled + * (the one selected by the user). If `reinstallation` is false and `currentMod` is + * not null, then it corresponds to a mod MO2 thinks corresponds to the archive (e.g. + * based on matching Nexus ID or name). + * @note The default implementation does nothing. + */ + virtual void onInstallationStart([[maybe_unused]] QString const& archive, + [[maybe_unused]] bool reinstallation, + [[maybe_unused]] IModInterface* currentMod) + {} + + /** + * @brief Method calls at the end of the installation process. This method is only + * called once per installation process, even for recursive installations (e.g. with + * the bundle installer). + * + * @param result The result of the installation. + * @param mod If the installation succeeded (result is RESULT_SUCCESS), contains the + * newly installed mod, otherwise it contains a null pointer. + * + * @note The default implementation does nothing. + */ + virtual void onInstallationEnd([[maybe_unused]] EInstallResult result, + [[maybe_unused]] IModInterface* newMod) + {} + + /** + * @brief Test if the archive represented by the tree parameter can be installed + * through this installer. + * + * @param tree a directory tree representing the archive. + * + * @return true if this installer can handle the archive. + */ + virtual bool isArchiveSupported(std::shared_ptr tree) const = 0; + + /** + * @brief Sets the widget that the tool should use as the parent whenever + * it creates a new modal dialog. + * + * @param widget The new parent widget. + */ + virtual void setParentWidget(QWidget* widget) { m_ParentWidget = widget; } + + /** + * @brief Sets the installation manager responsible for the installation process + * it can be used by plugins to access utility functions. + * + * @param manager The new installation manager. + */ + void setInstallationManager(IInstallationManager* manager) + { + m_InstallationManager = manager; + } + +protected: + /** + * @return the parent widget that the tool should use to create new dialogs and + * widgets. + */ + QWidget* parentWidget() const { return m_ParentWidget; } + + /** + * @return the manager responsible for the installation process. + */ + IInstallationManager* manager() const { return m_InstallationManager; } + +private: + QWidget* m_ParentWidget; + IInstallationManager* m_InstallationManager; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginInstaller, + "com.tannin.ModOrganizer.PluginInstaller/1.0") + +#endif // IPLUGININSTALLER_H diff --git a/src/iplugininstallercustom.h b/src/iplugininstallercustom.h index 2da26d90..204639f2 100644 --- a/src/iplugininstallercustom.h +++ b/src/iplugininstallercustom.h @@ -1,77 +1,79 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGININSTALLERCUSTOM_H -#define IPLUGININSTALLERCUSTOM_H - - -#include "iplugininstaller.h" -#include "guessedvalue.h" - - -namespace MOBase { - -/** - * Custom installer for mods. Custom installers receive the archive name and have to go - * from there. They have to be able to extract the archive themself. - * Plugins implementing this interface have to contain the following line in the class declaration: - * Q_Interfaces(IPlugin IPluginInstaller IPluginInstallerCustom) - */ -class IPluginInstallerCustom : public QObject, public IPluginInstaller { - - Q_INTERFACES(IPluginInstaller) - -public: - - /** - * @brief test if the archive represented by the file name can be installed through this installer - * @param filename of the archive - * @return true if this installer can handle the archive - * @note this is only called if the archive couldn't be opened by the caller, otherwise - * IPluginInstaller::isArchiveSupported(const DirectoryTree &tree) is called - */ - virtual bool isArchiveSupported(const QString &archiveName) const = 0; - - /** - * @return returns a list of file extensions that may be supported by this installer - */ - virtual std::set supportedExtensions() const = 0; - - /** - * install call - * @param modName name of the mod to install. As an input parameter this is the suggested name - * (i.e. from meta data) The installer may change this parameter to rename the mod) - * @param filename of the archive - * @param version version of the mod. May be empty if the version is not yet known. The plugin is responsible - * for setting the version on the created mod - * @param nexusID id of the mod or -1 if unknown. The plugin is responsible for setting the mod id for the created mod - * @return result of the installation process - */ - virtual EInstallResult install(GuessedValue &modName, QString gameName, const QString &archiveName, - const QString &version, int nexusID) = 0; - -}; - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginInstallerCustom, "com.tannin.ModOrganizer.PluginInstallerCustom/1.0") - -#endif // IPLUGININSTALLERCUSTOM_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGININSTALLERCUSTOM_H +#define IPLUGININSTALLERCUSTOM_H + +#include "guessedvalue.h" +#include "iplugininstaller.h" + +namespace MOBase +{ + +/** + * Custom installer for mods. Custom installers receive the archive name and have to go + * from there. They have to be able to extract the archive themself. + * Plugins implementing this interface have to contain the following line in the class + * declaration: Q_Interfaces(IPlugin IPluginInstaller IPluginInstallerCustom) + */ +class IPluginInstallerCustom : public QObject, public IPluginInstaller +{ + + Q_INTERFACES(IPluginInstaller) + +public: + /** + * @brief test if the archive represented by the file name can be installed through + * this installer + * @param filename of the archive + * @return true if this installer can handle the archive + * @note this is only called if the archive couldn't be opened by the caller, + * otherwise IPluginInstaller::isArchiveSupported(const DirectoryTree &tree) is called + */ + virtual bool isArchiveSupported(const QString& archiveName) const = 0; + + /** + * @return returns a list of file extensions that may be supported by this installer + */ + virtual std::set supportedExtensions() const = 0; + + /** + * install call + * @param modName name of the mod to install. As an input parameter this is the + * suggested name (i.e. from meta data) The installer may change this parameter to + * rename the mod) + * @param filename of the archive + * @param version version of the mod. May be empty if the version is not yet known. + * The plugin is responsible for setting the version on the created mod + * @param nexusID id of the mod or -1 if unknown. The plugin is responsible for + * setting the mod id for the created mod + * @return result of the installation process + */ + virtual EInstallResult install(GuessedValue& modName, QString gameName, + const QString& archiveName, const QString& version, + int nexusID) = 0; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginInstallerCustom, + "com.tannin.ModOrganizer.PluginInstallerCustom/1.0") + +#endif // IPLUGININSTALLERCUSTOM_H diff --git a/src/iplugininstallersimple.h b/src/iplugininstallersimple.h index 83cebbb9..a8795fc0 100644 --- a/src/iplugininstallersimple.h +++ b/src/iplugininstallersimple.h @@ -1,65 +1,69 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGININSTALLERSIMPLE_H -#define IPLUGININSTALLERSIMPLE_H - -#include "iplugininstaller.h" -#include "guessedvalue.h" - -namespace MOBase { - -/** - * Simple installer for mods. Simple installers only deal with an in-memory structure - * representing the archive and can modify what to install where by editing this structure. - * Actually extracting the archive is handled by the caller - * Plugins implementing this interface have to contain the following line in the class declaration: - * Q_Interfaces(IPlugin IPluginInstaller IPluginInstallerCustom) - */ -class IPluginInstallerSimple : public QObject, public IPluginInstaller { - - Q_INTERFACES(IPluginInstaller) - -public: - - /** - * install call for the simple mode. The installer only needs to restructure the tree parameter, - * the caller does the rest - * @param modName name of the mod to install. As an input parameter this is the suggested name - * (i.e. from meta data) The installer may change this parameter to rename the mod) - * @param tree in-memory representation of the archive content - * @param version version of the mod. May be empty if the version is not yet known. Can be updated if the - * plugin can determine the version - * @param nexusID id of the mod or -1 if unknown. May be updated if the plugin can determine the mod id - * @return the result of the installation process. If "ERROR_NOTATTEMPTED" is returned, further - * installers will work with the modified tree. This may be useful when implementing a sort - * of filter, but usually tree should remain unchanged in that case. - */ - virtual EInstallResult install(GuessedValue &modName, std::shared_ptr &tree, - QString &version, int &nexusID) = 0; - -}; - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginInstallerSimple, "com.tannin.ModOrganizer.PluginInstallerSimple/1.0") - -#endif // IPLUGININSTALLERSIMPLE_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGININSTALLERSIMPLE_H +#define IPLUGININSTALLERSIMPLE_H + +#include "guessedvalue.h" +#include "iplugininstaller.h" + +namespace MOBase +{ + +/** + * Simple installer for mods. Simple installers only deal with an in-memory structure + * representing the archive and can modify what to install where by editing this + * structure. Actually extracting the archive is handled by the caller Plugins + * implementing this interface have to contain the following line in the class + * declaration: Q_Interfaces(IPlugin IPluginInstaller IPluginInstallerCustom) + */ +class IPluginInstallerSimple : public QObject, public IPluginInstaller +{ + + Q_INTERFACES(IPluginInstaller) + +public: + /** + * install call for the simple mode. The installer only needs to restructure the tree + * parameter, the caller does the rest + * @param modName name of the mod to install. As an input parameter this is the + * suggested name (i.e. from meta data) The installer may change this parameter to + * rename the mod) + * @param tree in-memory representation of the archive content + * @param version version of the mod. May be empty if the version is not yet known. + * Can be updated if the plugin can determine the version + * @param nexusID id of the mod or -1 if unknown. May be updated if the plugin can + * determine the mod id + * @return the result of the installation process. If "ERROR_NOTATTEMPTED" is + * returned, further installers will work with the modified tree. This may be useful + * when implementing a sort of filter, but usually tree should remain unchanged in + * that case. + */ + virtual EInstallResult install(GuessedValue& modName, + std::shared_ptr& tree, QString& version, + int& nexusID) = 0; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginInstallerSimple, + "com.tannin.ModOrganizer.PluginInstallerSimple/1.0") + +#endif // IPLUGININSTALLERSIMPLE_H diff --git a/src/ipluginlist.h b/src/ipluginlist.h index 12a0e2e5..41c8dbdc 100644 --- a/src/ipluginlist.h +++ b/src/ipluginlist.h @@ -1,190 +1,209 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2013 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef IPLUGINLIST_H -#define IPLUGINLIST_H - -#include - -class QString; - -#include -#include - -namespace MOBase { - -class IPluginList { - -public: - - enum PluginState { - STATE_MISSING, - STATE_INACTIVE, - STATE_ACTIVE - }; - - Q_DECLARE_FLAGS(PluginStates, PluginState) - -public: - - virtual ~IPluginList() {} - - /** - * @return list of plugin names - */ - virtual QStringList pluginNames() const = 0; - - /** - * @brief retrieve the state of a plugin - * @param name filename of the plugin (without path but with file extension) - * @return one of the possible plugin states: missing, inactive or active - */ - virtual PluginStates state(const QString &name) const = 0; - - /** - * @brief set the state of a plugin - * @param name filename of the plugin (without path but with file extensions) - * @param state new state of the plugin. should be active or inactive - */ - virtual void setState(const QString &name, PluginStates state) = 0; - - /** - * @brief retrieve the priority of a plugin - * @param name filename of the plugin (without path but with file extension) - * @return the priority (the higher the more important). Returns -1 if the plugin doesn't exist - */ - virtual int priority(const QString &name) const = 0; - - /** - * @brief Change the priority of a plugin. - * - * @param name Filename of the plugin (without path but with file extension). - * @param newPriority New priority of the plugin. - * - * @return true on success, false if the priority change was not possible. This is usually because - * one of the parameters is invalid. The function returns true even if the plugin was not moved - * at the specified priority (e.g. when trying to move a non-master plugin before a master one). - */ - virtual bool setPriority(const QString& name, int newPriority) = 0; - - /** - * @brief retrieve the load order of a plugin - * @param name filename of the plugin (without path but with file extension) - * @return the load order of a plugin (the order in which the game loads it). If all plugins are enabled this is the same as the priority - * but disabled plugins will have a load order of -1. This also returns -1 if the plugin doesn't exist - */ - virtual int loadOrder(const QString &name) const = 0; - - /** - * @brief sets the load order of the plugin list. - * @param the new load order, specified by the list of plugin names, sorted. - * @note plugins not included in the list will be placed at highest priority - * in the order they were before - */ - virtual void setLoadOrder(const QStringList &pluginList) = 0; - - /** - * @brief determine if a plugin is a master file (basically a library, referenced by other plugins) - * @param name filename of the plugin (without path but with file extension) - * @return true if the file is a master, false if it isn't OR if the file doesn't exist. - * @note deprecated - */ - [[deprecated]] virtual bool isMaster(const QString& name) const = 0; - - /** - * @brief retrieve the list of masters required for this plugin - * @param name filename of the plugin (without path but with file extension) - * @return list of masters (filenames with extension, no path) - */ - virtual QStringList masters(const QString &name) const = 0; - - /** - * @brief retrieve the name of the origin of a plugin. This is either the (internal!) name of a mod or "overwrite" or "data" - * @param name filename of the plugin (without path but with file extension) - * @return name of the origin or an empty string if the plugin doesn't exist - * @note the internal name of a mod can differ from the display name for disambiguation - */ - virtual QString origin(const QString &name) const = 0; - - /** - * @brief invoked whenever the application felt it necessary to refresh the list (i.e. because of external changes) - */ - virtual bool onRefreshed(const std::function &callback) = 0; - - /** - * @brief invoked whenever a plugin has changed priority - */ - virtual bool onPluginMoved(const std::function &func) = 0; - - /** - * @brief Installs a handler for the event that the state of plugin changed (active/inactive). - * - * Parameters of the callback: - * - Map containing the plugins whose states have changed. Keys are plugin names and values are mod states. - * - * @param func The signal to be called when the states of any plugins change. - * - * @return true if the handler was successfully installed, false otherwise (there is as of now no known reason this should fail). - */ - virtual bool onPluginStateChanged(const std::function&)>& func) = 0; - - /** - * @brief determine if a plugin has the .esm extension (basically a library, referenced by other plugins) - * @param name filename of the plugin (without path but with file extension) - * @return true if the file has the .esm extension, false if it isn't OR if the file doesn't exist. - * @note in gamebryo games, a master file will usually have a .esm file - * extension but technically an esp can be flagged as master and an esm might - * not be - */ - virtual bool hasMasterExtension(const QString& name) const = 0; - - /** - * @brief determine if a plugin has the .esl extension - * @param name filename of the plugin (without path but with file extension) - * @return true if the file has the .esl extension, false if it isn't OR if the file doesn't exist. - * @note in gamebryo games, a light file will usually have a .esl file - * extension but technically an esp can be flagged as light and an esm might - * not be - */ - virtual bool hasLightExtension(const QString& name) const = 0; - - /** - * @brief determine if a plugin is flagged as master (basically a library, referenced by other plugins) - * @param name filename of the plugin (without path but with file extension) - * @return true if the file is flagged as master, false if it isn't OR if the file doesn't exist. - * @note in gamebryo games, a master file will usually have a .esm file - * extension but technically an esp can be flagged as master and an esm might - * not be - */ - virtual bool isMasterFlagged(const QString& name) const = 0; - - /** - * @brief determine if a plugin is flagged as light - * @param name filename of the plugin (without path but with file extension) - * @return true if the file is flagged as light, false if it isn't OR if the file doesn't exist. - * @note in gamebryo games, a light file will usually have a .esl file - */ - virtual bool isLightFlagged(const QString& name) const = 0; - -}; - -} - -#endif // IPLUGINLIST_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2013 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINLIST_H +#define IPLUGINLIST_H + +#include + +class QString; + +#include +#include + +namespace MOBase +{ + +class IPluginList +{ + +public: + enum PluginState + { + STATE_MISSING, + STATE_INACTIVE, + STATE_ACTIVE + }; + + Q_DECLARE_FLAGS(PluginStates, PluginState) + +public: + virtual ~IPluginList() {} + + /** + * @return list of plugin names + */ + virtual QStringList pluginNames() const = 0; + + /** + * @brief retrieve the state of a plugin + * @param name filename of the plugin (without path but with file extension) + * @return one of the possible plugin states: missing, inactive or active + */ + virtual PluginStates state(const QString& name) const = 0; + + /** + * @brief set the state of a plugin + * @param name filename of the plugin (without path but with file extensions) + * @param state new state of the plugin. should be active or inactive + */ + virtual void setState(const QString& name, PluginStates state) = 0; + + /** + * @brief retrieve the priority of a plugin + * @param name filename of the plugin (without path but with file extension) + * @return the priority (the higher the more important). Returns -1 if the plugin + * doesn't exist + */ + virtual int priority(const QString& name) const = 0; + + /** + * @brief Change the priority of a plugin. + * + * @param name Filename of the plugin (without path but with file extension). + * @param newPriority New priority of the plugin. + * + * @return true on success, false if the priority change was not possible. This is + * usually because one of the parameters is invalid. The function returns true even if + * the plugin was not moved at the specified priority (e.g. when trying to move a + * non-master plugin before a master one). + */ + virtual bool setPriority(const QString& name, int newPriority) = 0; + + /** + * @brief retrieve the load order of a plugin + * @param name filename of the plugin (without path but with file extension) + * @return the load order of a plugin (the order in which the game loads it). If all + * plugins are enabled this is the same as the priority but disabled plugins will have + * a load order of -1. This also returns -1 if the plugin doesn't exist + */ + virtual int loadOrder(const QString& name) const = 0; + + /** + * @brief sets the load order of the plugin list. + * @param the new load order, specified by the list of plugin names, sorted. + * @note plugins not included in the list will be placed at highest priority + * in the order they were before + */ + virtual void setLoadOrder(const QStringList& pluginList) = 0; + + /** + * @brief determine if a plugin is a master file (basically a library, referenced by + * other plugins) + * @param name filename of the plugin (without path but with file extension) + * @return true if the file is a master, false if it isn't OR if the file doesn't + * exist. + * @note deprecated + */ + [[deprecated]] virtual bool isMaster(const QString& name) const = 0; + + /** + * @brief retrieve the list of masters required for this plugin + * @param name filename of the plugin (without path but with file extension) + * @return list of masters (filenames with extension, no path) + */ + virtual QStringList masters(const QString& name) const = 0; + + /** + * @brief retrieve the name of the origin of a plugin. This is either the (internal!) + * name of a mod or "overwrite" or "data" + * @param name filename of the plugin (without path but with file extension) + * @return name of the origin or an empty string if the plugin doesn't exist + * @note the internal name of a mod can differ from the display name for + * disambiguation + */ + virtual QString origin(const QString& name) const = 0; + + /** + * @brief invoked whenever the application felt it necessary to refresh the list (i.e. + * because of external changes) + */ + virtual bool onRefreshed(const std::function& callback) = 0; + + /** + * @brief invoked whenever a plugin has changed priority + */ + virtual bool + onPluginMoved(const std::function& func) = 0; + + /** + * @brief Installs a handler for the event that the state of plugin changed + * (active/inactive). + * + * Parameters of the callback: + * - Map containing the plugins whose states have changed. Keys are plugin names and + * values are mod states. + * + * @param func The signal to be called when the states of any plugins change. + * + * @return true if the handler was successfully installed, false otherwise (there is + * as of now no known reason this should fail). + */ + virtual bool onPluginStateChanged( + const std::function&)>& func) = 0; + + /** + * @brief determine if a plugin has the .esm extension (basically a library, + * referenced by other plugins) + * @param name filename of the plugin (without path but with file extension) + * @return true if the file has the .esm extension, false if it isn't OR if the file + * doesn't exist. + * @note in gamebryo games, a master file will usually have a .esm file + * extension but technically an esp can be flagged as master and an esm might + * not be + */ + virtual bool hasMasterExtension(const QString& name) const = 0; + + /** + * @brief determine if a plugin has the .esl extension + * @param name filename of the plugin (without path but with file extension) + * @return true if the file has the .esl extension, false if it isn't OR if the file + * doesn't exist. + * @note in gamebryo games, a light file will usually have a .esl file + * extension but technically an esp can be flagged as light and an esm might + * not be + */ + virtual bool hasLightExtension(const QString& name) const = 0; + + /** + * @brief determine if a plugin is flagged as master (basically a library, referenced + * by other plugins) + * @param name filename of the plugin (without path but with file extension) + * @return true if the file is flagged as master, false if it isn't OR if the file + * doesn't exist. + * @note in gamebryo games, a master file will usually have a .esm file + * extension but technically an esp can be flagged as master and an esm might + * not be + */ + virtual bool isMasterFlagged(const QString& name) const = 0; + + /** + * @brief determine if a plugin is flagged as light + * @param name filename of the plugin (without path but with file extension) + * @return true if the file is flagged as light, false if it isn't OR if the file + * doesn't exist. + * @note in gamebryo games, a light file will usually have a .esl file + */ + virtual bool isLightFlagged(const QString& name) const = 0; +}; + +} // namespace MOBase + +#endif // IPLUGINLIST_H diff --git a/src/ipluginmodpage.h b/src/ipluginmodpage.h index ec01b3f6..78630d9f 100644 --- a/src/ipluginmodpage.h +++ b/src/ipluginmodpage.h @@ -1,95 +1,92 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2013 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGINMODPAGE_H -#define IPLUGINMODPAGE_H - -#include "iplugin.h" -#include "modrepositoryfileinfo.h" -#include - -namespace MOBase { - - -class IPluginModPage : public QObject, public IPlugin { - Q_INTERFACES(IPlugin) -public: - - /** - * @return name of the Page as displayed in the ui - */ - virtual QString displayName() const = 0; - - /** - * @return icon to be displayed with the page - */ - virtual QIcon icon() const = 0; - - /** - * @return url to open when the user wants to visit this mod page - */ - virtual QUrl pageURL() const = 0; - - /** - * @return true if the page should be opened in the integrated browser - * @note unless the page provides a special means of starting downloads (like the nxm:// url schema on nexus) - * it will not be possible to handle downloads unless the integrated browser is used! - */ - virtual bool useIntegratedBrowser() const = 0; - - /** - * @brief test if the plugin handles a download - * @param pageURL url of the page that contained the donwload link - * @param downloadURL the actual download link - * @param fileInfo if the plugin can derive information from the urls it can store them here and they will be passed along - * with the download and be made available on installation - * @return true if this plugin wants to handle the specified download - */ - virtual bool handlesDownload(const QUrl &pageURL, const QUrl &downloadURL, ModRepositoryFileInfo &fileInfo) const = 0; - - /** - * @brief sets the widget that the tool should use as the parent whenever - * it creates a new modal dialog - * @param widget the new parent widget - */ - virtual void setParentWidget(QWidget *widget) { m_ParentWidget = widget; } - -protected: - - /** - * @brief getter for the parent widget - * @return parent widget - */ - QWidget *parentWidget() const { return m_ParentWidget; } - -private: - - QWidget *m_ParentWidget; - -}; - - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginModPage, "com.tannin.ModOrganizer.PluginModPage/1.0") - - -#endif // IPLUGINMODPAGE_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2013 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINMODPAGE_H +#define IPLUGINMODPAGE_H + +#include "iplugin.h" +#include "modrepositoryfileinfo.h" +#include + +namespace MOBase +{ + +class IPluginModPage : public QObject, public IPlugin +{ + Q_INTERFACES(IPlugin) +public: + /** + * @return name of the Page as displayed in the ui + */ + virtual QString displayName() const = 0; + + /** + * @return icon to be displayed with the page + */ + virtual QIcon icon() const = 0; + + /** + * @return url to open when the user wants to visit this mod page + */ + virtual QUrl pageURL() const = 0; + + /** + * @return true if the page should be opened in the integrated browser + * @note unless the page provides a special means of starting downloads (like the + * nxm:// url schema on nexus) it will not be possible to handle downloads unless the + * integrated browser is used! + */ + virtual bool useIntegratedBrowser() const = 0; + + /** + * @brief test if the plugin handles a download + * @param pageURL url of the page that contained the donwload link + * @param downloadURL the actual download link + * @param fileInfo if the plugin can derive information from the urls it can store + * them here and they will be passed along with the download and be made available on + * installation + * @return true if this plugin wants to handle the specified download + */ + virtual bool handlesDownload(const QUrl& pageURL, const QUrl& downloadURL, + ModRepositoryFileInfo& fileInfo) const = 0; + + /** + * @brief sets the widget that the tool should use as the parent whenever + * it creates a new modal dialog + * @param widget the new parent widget + */ + virtual void setParentWidget(QWidget* widget) { m_ParentWidget = widget; } + +protected: + /** + * @brief getter for the parent widget + * @return parent widget + */ + QWidget* parentWidget() const { return m_ParentWidget; } + +private: + QWidget* m_ParentWidget; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginModPage, "com.tannin.ModOrganizer.PluginModPage/1.0") + +#endif // IPLUGINMODPAGE_H diff --git a/src/ipluginpreview.h b/src/ipluginpreview.h index acba3cef..2af51562 100644 --- a/src/ipluginpreview.h +++ b/src/ipluginpreview.h @@ -1,57 +1,54 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2014 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGINPREVIEW_H -#define IPLUGINPREVIEW_H - - -#include "iplugin.h" - -namespace MOBase { - - -class IPluginPreview : public QObject, public IPlugin { - Q_INTERFACES(IPlugin) -public: - - /** - * @return returns a set of file extensions that may be supported - */ - virtual std::set supportedExtensions() const = 0; - - /** - * @brief generate a preview widget for the specified file - * @param fileName name of the file to preview - * @param maxSize maximum size of the generated widget - * @return a widget showing the file - */ - virtual QWidget *genFilePreview(const QString &fileName, const QSize &maxSize) const = 0; - -private: - -}; - - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginPreview, "com.tannin.ModOrganizer.PluginPreview/1.0") - -#endif // IPLUGINPREVIEW_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2014 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINPREVIEW_H +#define IPLUGINPREVIEW_H + +#include "iplugin.h" + +namespace MOBase +{ + +class IPluginPreview : public QObject, public IPlugin +{ + Q_INTERFACES(IPlugin) +public: + /** + * @return returns a set of file extensions that may be supported + */ + virtual std::set supportedExtensions() const = 0; + + /** + * @brief generate a preview widget for the specified file + * @param fileName name of the file to preview + * @param maxSize maximum size of the generated widget + * @return a widget showing the file + */ + virtual QWidget* genFilePreview(const QString& fileName, + const QSize& maxSize) const = 0; + +private: +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginPreview, "com.tannin.ModOrganizer.PluginPreview/1.0") + +#endif // IPLUGINPREVIEW_H diff --git a/src/ipluginproxy.h b/src/ipluginproxy.h index fa7922c5..b0b8d843 100644 --- a/src/ipluginproxy.h +++ b/src/ipluginproxy.h @@ -1,87 +1,83 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef IPLUGINPROXY_H -#define IPLUGINPROXY_H - -#include -#include -#include - -#include "iplugin.h" - - -namespace MOBase { - -class IPluginProxy : public IPlugin { -public: - - IPluginProxy() : m_ParentWidget(nullptr) {} - - /** - * @brief List the plugins managed by this proxy in the given - * folder. - * - * @param pluginPath Path containing the plugins. - * - * @return list of plugin identifiers that supported by this proxy. - */ - virtual QStringList pluginList(const QDir& pluginPath) const = 0; - - /** - * @brief Load the plugins corresponding to the given identifier. - * - * @param identifier Identifier of the proxied plugin to load. - * - * @return a list of QObject, one for each plugins in the given identifier. - */ - virtual QList load(const QString& identifier) = 0; - - /** - * @brief Unload the plugins corresponding to the given identifier. - * - * @param identifier Identifier of the proxied plugin to unload. - */ - virtual void unload(const QString& identifier) = 0; - - /** - * @brief Sets the widget that the tool should use as the parent whenever - * it creates a new modal dialog. - * - * @param widget The new parent widget. - */ - void setParentWidget(QWidget *widget) { m_ParentWidget = widget; } - -protected: - - QWidget *parentWidget() const { return m_ParentWidget; } - -private: - - QWidget *m_ParentWidget; - -}; - - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginProxy, "com.tannin.ModOrganizer.PluginProxy/1.0") - -#endif // IPLUGINPROXY_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINPROXY_H +#define IPLUGINPROXY_H + +#include +#include +#include + +#include "iplugin.h" + +namespace MOBase +{ + +class IPluginProxy : public IPlugin +{ +public: + IPluginProxy() : m_ParentWidget(nullptr) {} + + /** + * @brief List the plugins managed by this proxy in the given + * folder. + * + * @param pluginPath Path containing the plugins. + * + * @return list of plugin identifiers that supported by this proxy. + */ + virtual QStringList pluginList(const QDir& pluginPath) const = 0; + + /** + * @brief Load the plugins corresponding to the given identifier. + * + * @param identifier Identifier of the proxied plugin to load. + * + * @return a list of QObject, one for each plugins in the given identifier. + */ + virtual QList load(const QString& identifier) = 0; + + /** + * @brief Unload the plugins corresponding to the given identifier. + * + * @param identifier Identifier of the proxied plugin to unload. + */ + virtual void unload(const QString& identifier) = 0; + + /** + * @brief Sets the widget that the tool should use as the parent whenever + * it creates a new modal dialog. + * + * @param widget The new parent widget. + */ + void setParentWidget(QWidget* widget) { m_ParentWidget = widget; } + +protected: + QWidget* parentWidget() const { return m_ParentWidget; } + +private: + QWidget* m_ParentWidget; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginProxy, "com.tannin.ModOrganizer.PluginProxy/1.0") + +#endif // IPLUGINPROXY_H diff --git a/src/iplugintool.h b/src/iplugintool.h index 7d9a92bb..303ab367 100644 --- a/src/iplugintool.h +++ b/src/iplugintool.h @@ -1,93 +1,87 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef IPLUGINTOOL_H -#define IPLUGINTOOL_H - - -#include "iplugin.h" -#include - -namespace MOBase { - - -class IPluginTool : public QObject, public virtual IPlugin { - Q_INTERFACES(IPlugin) -public: - - IPluginTool() : m_ParentWidget(nullptr) {} - - /** - * @return name of the tool as displayed in the ui - */ - virtual QString displayName() const = 0; - - /** - * @brief For IPluginTool, this returns displayName(). - * - */ - virtual QString localizedName() const { return displayName(); } - - /** - * @return tooltip string - */ - - virtual QString tooltip() const = 0; - /** - * @return icon to be displayed with the tool - */ - virtual QIcon icon() const = 0; - - /** - * @brief sets the widget that the tool should use as the parent whenever - * it creates a new modal dialog - * @param widget the new parent widget - */ - virtual void setParentWidget(QWidget *widget) { m_ParentWidget = widget; } - -public Q_SLOTS: - - /** - * @brief called when the user clicks to start the tool. - * @note This must not throw an exception! - */ - virtual void display() const = 0; - -protected: - - /** - * @brief getter for the parent widget - * @return parent widget - */ - QWidget *parentWidget() const { return m_ParentWidget; } - -private: - - QWidget *m_ParentWidget; - -}; - - -} // namespace MOBase - -Q_DECLARE_INTERFACE(MOBase::IPluginTool, "com.tannin.ModOrganizer.PluginTool/1.0") - -#endif // IPLUGINTOOL_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef IPLUGINTOOL_H +#define IPLUGINTOOL_H + +#include "iplugin.h" +#include + +namespace MOBase +{ + +class IPluginTool : public QObject, public virtual IPlugin +{ + Q_INTERFACES(IPlugin) +public: + IPluginTool() : m_ParentWidget(nullptr) {} + + /** + * @return name of the tool as displayed in the ui + */ + virtual QString displayName() const = 0; + + /** + * @brief For IPluginTool, this returns displayName(). + * + */ + virtual QString localizedName() const { return displayName(); } + + /** + * @return tooltip string + */ + + virtual QString tooltip() const = 0; + /** + * @return icon to be displayed with the tool + */ + virtual QIcon icon() const = 0; + + /** + * @brief sets the widget that the tool should use as the parent whenever + * it creates a new modal dialog + * @param widget the new parent widget + */ + virtual void setParentWidget(QWidget* widget) { m_ParentWidget = widget; } + +public Q_SLOTS: + + /** + * @brief called when the user clicks to start the tool. + * @note This must not throw an exception! + */ + virtual void display() const = 0; + +protected: + /** + * @brief getter for the parent widget + * @return parent widget + */ + QWidget* parentWidget() const { return m_ParentWidget; } + +private: + QWidget* m_ParentWidget; +}; + +} // namespace MOBase + +Q_DECLARE_INTERFACE(MOBase::IPluginTool, "com.tannin.ModOrganizer.PluginTool/1.0") + +#endif // IPLUGINTOOL_H diff --git a/src/iprofile.h b/src/iprofile.h index 0e3639a7..1706e3ed 100644 --- a/src/iprofile.h +++ b/src/iprofile.h @@ -1,43 +1,41 @@ -#ifndef IPROFILE -#define IPROFILE - - -#include -#include - -namespace MOBase { - - -class IProfile { - -public: - - virtual ~IProfile() {} - - virtual QString name() const = 0; - virtual QString absolutePath() const = 0; - virtual bool localSavesEnabled() const = 0; - virtual bool localSettingsEnabled() const = 0; - virtual bool invalidationActive(bool *supported) const = 0; - - /** - * @brief Retrieve the absolute file path to the corresponding INI file for this - * profile. - * - * @param iniFile INI file to retrieve a path for. This can either be the - * name of a file or a path to the absolute file outside of the profile. - * - * @return the absolute path for the given INI file for this profile. - * - * @note If iniFile does not correspond to a file in the list of INI files for the - * current game (as returned by IPluginGame::iniFiles), the path to the global - * file will be returned (if iniFile is absolute, iniFile is returned, otherwiise - the path is assumed relative to the game documents directory). - */ - virtual QString absoluteIniFilePath(QString iniFile) const = 0; -}; - -} // namespace MOBase - - -#endif // IPROFILE +#ifndef IPROFILE +#define IPROFILE + +#include +#include + +namespace MOBase +{ + +class IProfile +{ + +public: + virtual ~IProfile() {} + + virtual QString name() const = 0; + virtual QString absolutePath() const = 0; + virtual bool localSavesEnabled() const = 0; + virtual bool localSettingsEnabled() const = 0; + virtual bool invalidationActive(bool* supported) const = 0; + + /** + * @brief Retrieve the absolute file path to the corresponding INI file for this + * profile. + * + * @param iniFile INI file to retrieve a path for. This can either be the + * name of a file or a path to the absolute file outside of the profile. + * + * @return the absolute path for the given INI file for this profile. + * + * @note If iniFile does not correspond to a file in the list of INI files for the + * current game (as returned by IPluginGame::iniFiles), the path to the global + * file will be returned (if iniFile is absolute, iniFile is returned, otherwiise + the path is assumed relative to the game documents directory). + */ + virtual QString absoluteIniFilePath(QString iniFile) const = 0; +}; + +} // namespace MOBase + +#endif // IPROFILE diff --git a/src/isavegame.h b/src/isavegame.h index 23d5208a..2f694462 100644 --- a/src/isavegame.h +++ b/src/isavegame.h @@ -6,7 +6,8 @@ class QString; class QDateTime; -namespace MOBase { +namespace MOBase +{ /** Base class for information about what is in a save game */ class ISaveGame @@ -48,11 +49,10 @@ class ISaveGame * Note: This must return the actual list, not the potential list. */ virtual QStringList allFiles() const = 0; - }; -} +} // namespace MOBase -Q_DECLARE_METATYPE(MOBase::ISaveGame const *) +Q_DECLARE_METATYPE(MOBase::ISaveGame const*) -#endif // SAVEGAMEINFO_H +#endif // SAVEGAMEINFO_H diff --git a/src/isavegameinfowidget.h b/src/isavegameinfowidget.h index 84dfdae6..d0620b0b 100644 --- a/src/isavegameinfowidget.h +++ b/src/isavegameinfowidget.h @@ -7,7 +7,8 @@ class QFile; -namespace MOBase { +namespace MOBase +{ /** Base class for a save game info widget. * @@ -16,16 +17,14 @@ namespace MOBase { class ISaveGameInfoWidget : public QWidget { public: - ISaveGameInfoWidget(QWidget *parent = 0) : - QWidget(parent) - {} + ISaveGameInfoWidget(QWidget* parent = 0) : QWidget(parent) {} virtual ~ISaveGameInfoWidget() {} /** Set the save file to display in the widget */ - virtual void setSave(ISaveGame const &) = 0; + virtual void setSave(ISaveGame const&) = 0; }; -} +} // namespace MOBase -#endif // ISAVEGAMEINFOWIDGET_H +#endif // ISAVEGAMEINFOWIDGET_H diff --git a/src/json.cpp b/src/json.cpp index e700112d..24bd0a5f 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -1,522 +1,557 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.cpp - */ - -#include "json.h" - -namespace QtJson { - static QString sanitizeString(QString str); - static QByteArray join(const QList &list, const QByteArray &sep); - static QVariant parseValue(const QString &json, int &index, bool &success); - static QVariant parseObject(const QString &json, int &index, bool &success); - static QVariant parseArray(const QString &json, int &index, bool &success); - static QVariant parseString(const QString &json, int &index, bool &success); - static QVariant parseNumber(const QString &json, int &index); - static int lastIndexOfNumber(const QString &json, int index); - static void eatWhitespace(const QString &json, int &index); - static int lookAhead(const QString &json, int index); - static int nextToken(const QString &json, int &index); - - template - QByteArray serializeMap(const T &map, bool &success) { - QByteArray str = "{ "; - QList pairs; - for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { - QByteArray serializedValue = serialize(it.value()); - if (serializedValue.isNull()) { - success = false; - break; - } - pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; - } - - str += join(pairs, ", "); - str += " }"; - return str; - } - - - /** - * parse - */ - QVariant parse(const QString &json) { - bool success = true; - return parse(json, success); - } - - /** - * parse - */ - QVariant parse(const QString &json, bool &success) { - success = true; - - // Return an empty QVariant if the JSON data is either null or empty - if (!json.isNull() || !json.isEmpty()) { - QString data = json; - // We'll start from index 0 - int index = 0; - - // Parse the first value - QVariant value = parseValue(data, index, success); - - // Return the parsed value - return value; - } else { - // Return the empty QVariant - return QVariant(); - } - } - - QByteArray serialize(const QVariant &data) { - bool success = true; - return serialize(data, success); - } - - QByteArray serialize(const QVariant &data, bool &success) { - QByteArray str; - success = true; - - if (!data.isValid()) { // invalid or null? - str = "null"; - } else if ((data.typeId() == QMetaType::Type::QVariantList) || - (data.typeId() == QMetaType::Type::QStringList)) { // variant is a list? - QList values; - const QVariantList list = data.toList(); - Q_FOREACH(const QVariant& v, list) { - QByteArray serializedValue = serialize(v); - if (serializedValue.isNull()) { - success = false; - break; - } - values << serializedValue; - } - - str = "[ " + join( values, ", " ) + " ]"; - } else if (data.typeId() == QMetaType::Type::QVariantHash) { // variant is a hash? - str = serializeMap<>(data.toHash(), success); - } else if (data.typeId() == QMetaType::Type::QVariantMap) { // variant is a map? - str = serializeMap<>(data.toMap(), success); - } else if ((data.typeId() == QMetaType::Type::QString) || - (data.typeId() == QMetaType::Type::QByteArray)) {// a string or a byte array? - str = sanitizeString(data.toString()).toUtf8(); - } else if (data.typeId() == QMetaType::Type::Double) { // double? - double value = data.toDouble(); - if ((value - value) == 0.0) { - str = QByteArray::number(value, 'g'); - if (!str.contains(".") && ! str.contains("e")) { - str += ".0"; - } - } else { - success = false; - } - } else if (data.typeId() == QMetaType::Type::Bool) { // boolean value? - str = data.toBool() ? "true" : "false"; - } else if (data.typeId() == QMetaType::Type::ULongLong) { // large unsigned number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { // any signed number? - str = QByteArray::number(data.value()); - } else if (data.canConvert()) { //TODO: this code is never executed - str = QString::number(data.value()).toUtf8(); - } else if (data.canConvert()) { // can value be converted to string? - // this will catch QDate, QDateTime, QUrl, ... - str = sanitizeString(data.toString()).toUtf8(); - } else { - success = false; - } - - if (success) { - return str; - } else { - return QByteArray(); - } - } - - QString serializeStr(const QVariant &data) { - return QString::fromUtf8(serialize(data)); - } - - QString serializeStr(const QVariant &data, bool &success) { - return QString::fromUtf8(serialize(data, success)); - } - - - /** - * \enum JsonToken - */ - enum JsonToken { - JsonTokenNone = 0, - JsonTokenCurlyOpen = 1, - JsonTokenCurlyClose = 2, - JsonTokenSquaredOpen = 3, - JsonTokenSquaredClose = 4, - JsonTokenColon = 5, - JsonTokenComma = 6, - JsonTokenString = 7, - JsonTokenNumber = 8, - JsonTokenTrue = 9, - JsonTokenFalse = 10, - JsonTokenNull = 11 - }; - - static QString sanitizeString(QString str) { - str.replace(QLatin1String("\\"), QLatin1String("\\\\")); - str.replace(QLatin1String("\""), QLatin1String("\\\"")); - str.replace(QLatin1String("\b"), QLatin1String("\\b")); - str.replace(QLatin1String("\f"), QLatin1String("\\f")); - str.replace(QLatin1String("\n"), QLatin1String("\\n")); - str.replace(QLatin1String("\r"), QLatin1String("\\r")); - str.replace(QLatin1String("\t"), QLatin1String("\\t")); - return QString(QLatin1String("\"%1\"")).arg(str); - } - - static QByteArray join(const QList &list, const QByteArray &sep) { - QByteArray res; - Q_FOREACH(const QByteArray &i, list) { - if (!res.isEmpty()) { - res += sep; - } - res += i; - } - return res; - } - - /** - * parseValue - */ - static QVariant parseValue(const QString &json, int &index, bool &success) { - // Determine what kind of data we should parse by - // checking out the upcoming token - switch(lookAhead(json, index)) { - case JsonTokenString: - return parseString(json, index, success); - case JsonTokenNumber: - return parseNumber(json, index); - case JsonTokenCurlyOpen: - return parseObject(json, index, success); - case JsonTokenSquaredOpen: - return parseArray(json, index, success); - case JsonTokenTrue: - nextToken(json, index); - return QVariant(true); - case JsonTokenFalse: - nextToken(json, index); - return QVariant(false); - case JsonTokenNull: - nextToken(json, index); - return QVariant(); - case JsonTokenNone: - break; - } - - // If there were no tokens, flag the failure and return an empty QVariant - success = false; - return QVariant(); - } - - /** - * parseObject - */ - static QVariant parseObject(const QString &json, int &index, bool &success) { - QVariantMap map; - int token; - - // Get rid of the whitespace and increment index - nextToken(json, index); - - // Loop through all of the key/value pairs of the object - bool done = false; - while (!done) { - // Get the upcoming token - token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantMap(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenCurlyClose) { - nextToken(json, index); - return map; - } else { - // Parse the key/value pair's name - QString name = parseString(json, index, success).toString(); - - if (!success) { - return QVariantMap(); - } - - // Get the next token - token = nextToken(json, index); - - // If the next token is not a colon, flag the failure - // return an empty QVariant - if (token != JsonTokenColon) { - success = false; - return QVariant(QVariantMap()); - } - - // Parse the key/value pair's value - QVariant value = parseValue(json, index, success); - - if (!success) { - return QVariantMap(); - } - - // Assign the value to the key in the map - map[name] = value; - } - } - - // Return the map successfully - return QVariant(map); - } - - /** - * parseArray - */ - static QVariant parseArray(const QString &json, int &index, bool &success) { - QVariantList list; - - nextToken(json, index); - - bool done = false; - while(!done) { - int token = lookAhead(json, index); - - if (token == JsonTokenNone) { - success = false; - return QVariantList(); - } else if (token == JsonTokenComma) { - nextToken(json, index); - } else if (token == JsonTokenSquaredClose) { - nextToken(json, index); - break; - } else { - QVariant value = parseValue(json, index, success); - if (!success) { - return QVariantList(); - } - list.push_back(value); - } - } - - return QVariant(list); - } - - /** - * parseString - */ - static QVariant parseString(const QString &json, int &index, bool &success) { - QString s; - QChar c; - - eatWhitespace(json, index); - - c = json[index++]; - - bool complete = false; - while(!complete) { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - complete = true; - break; - } else if (c == '\\') { - if (index == json.size()) { - break; - } - - c = json[index++]; - - if (c == '\"') { - s.append('\"'); - } else if (c == '\\') { - s.append('\\'); - } else if (c == '/') { - s.append('/'); - } else if (c == 'b') { - s.append('\b'); - } else if (c == 'f') { - s.append('\f'); - } else if (c == 'n') { - s.append('\n'); - } else if (c == 'r') { - s.append('\r'); - } else if (c == 't') { - s.append('\t'); - } else if (c == 'u') { - qsizetype remainingLength = json.size() - index; - if (remainingLength >= 4) { - QString unicodeStr = json.mid(index, 4); - - int symbol = unicodeStr.toInt(0, 16); - - s.append(QChar(symbol)); - - index += 4; - } else { - break; - } - } - } else { - s.append(c); - } - } - - if (!complete) { - success = false; - return QVariant(); - } - - return QVariant(s); - } - - /** - * parseNumber - */ - static QVariant parseNumber(const QString &json, int &index) { - eatWhitespace(json, index); - - int lastIndex = lastIndexOfNumber(json, index); - int charLength = (lastIndex - index) + 1; - QString numberStr; - - numberStr = json.mid(index, charLength); - - index = lastIndex + 1; - bool ok; - - if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(nullptr)); - } else if (numberStr.startsWith('-')) { - int i = numberStr.toInt(&ok); - if (!ok) { - qlonglong ll = numberStr.toLongLong(&ok); - return ok ? ll : QVariant(numberStr); - } - return i; - } else { - uint u = numberStr.toUInt(&ok); - if (!ok) { - qulonglong ull = numberStr.toULongLong(&ok); - return ok ? ull : QVariant(numberStr); - } - return u; - } - } - - /** - * lastIndexOfNumber - */ - static int lastIndexOfNumber(const QString &json, int index) { - int lastIndex; - - for(lastIndex = index; lastIndex < json.size(); lastIndex++) { - if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) { - break; - } - } - - return lastIndex -1; - } - - /** - * eatWhitespace - */ - static void eatWhitespace(const QString &json, int &index) { - for(; index < json.size(); index++) { - if (QString(" \t\n\r").indexOf(json[index]) == -1) { - break; - } - } - } - - /** - * lookAhead - */ - static int lookAhead(const QString &json, int index) { - int saveIndex = index; - return nextToken(json, saveIndex); - } - - /** - * nextToken - */ - static int nextToken(const QString &json, int &index) { - eatWhitespace(json, index); - - if (index == json.size()) { - return JsonTokenNone; - } - - QChar c = json[index]; - index++; - switch(c.toLatin1()) { - case '{': return JsonTokenCurlyOpen; - case '}': return JsonTokenCurlyClose; - case '[': return JsonTokenSquaredOpen; - case ']': return JsonTokenSquaredClose; - case ',': return JsonTokenComma; - case '"': return JsonTokenString; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': return JsonTokenNumber; - case ':': return JsonTokenColon; - } - index--; // ^ WTF? - - qsizetype remainingLength = json.size() - index; - - // True - if (remainingLength >= 4) { - if (json[index] == 't' && json[index + 1] == 'r' && - json[index + 2] == 'u' && json[index + 3] == 'e') { - index += 4; - return JsonTokenTrue; - } - } - - // False - if (remainingLength >= 5) { - if (json[index] == 'f' && json[index + 1] == 'a' && - json[index + 2] == 'l' && json[index + 3] == 's' && - json[index + 4] == 'e') { - index += 5; - return JsonTokenFalse; - } - } - - // Null - if (remainingLength >= 4) { - if (json[index] == 'n' && json[index + 1] == 'u' && - json[index + 2] == 'l' && json[index + 3] == 'l') { - index += 4; - return JsonTokenNull; - } - } - - return JsonTokenNone; - } -} //end namespace +/** + * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and + * vice-versa. Copyright (C) 2011 Eeli Reilin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file json.cpp + */ + +#include "json.h" + +namespace QtJson +{ +static QString sanitizeString(QString str); +static QByteArray join(const QList& list, const QByteArray& sep); +static QVariant parseValue(const QString& json, int& index, bool& success); +static QVariant parseObject(const QString& json, int& index, bool& success); +static QVariant parseArray(const QString& json, int& index, bool& success); +static QVariant parseString(const QString& json, int& index, bool& success); +static QVariant parseNumber(const QString& json, int& index); +static int lastIndexOfNumber(const QString& json, int index); +static void eatWhitespace(const QString& json, int& index); +static int lookAhead(const QString& json, int index); +static int nextToken(const QString& json, int& index); + +template +QByteArray serializeMap(const T& map, bool& success) +{ + QByteArray str = "{ "; + QList pairs; + for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; + ++it) { + QByteArray serializedValue = serialize(it.value()); + if (serializedValue.isNull()) { + success = false; + break; + } + pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue; + } + + str += join(pairs, ", "); + str += " }"; + return str; +} + +/** + * parse + */ +QVariant parse(const QString& json) +{ + bool success = true; + return parse(json, success); +} + +/** + * parse + */ +QVariant parse(const QString& json, bool& success) +{ + success = true; + + // Return an empty QVariant if the JSON data is either null or empty + if (!json.isNull() || !json.isEmpty()) { + QString data = json; + // We'll start from index 0 + int index = 0; + + // Parse the first value + QVariant value = parseValue(data, index, success); + + // Return the parsed value + return value; + } else { + // Return the empty QVariant + return QVariant(); + } +} + +QByteArray serialize(const QVariant& data) +{ + bool success = true; + return serialize(data, success); +} + +QByteArray serialize(const QVariant& data, bool& success) +{ + QByteArray str; + success = true; + + if (!data.isValid()) { // invalid or null? + str = "null"; + } else if ((data.typeId() == QMetaType::Type::QVariantList) || + (data.typeId() == QMetaType::Type::QStringList)) { // variant is a list? + QList values; + const QVariantList list = data.toList(); + Q_FOREACH (const QVariant& v, list) { + QByteArray serializedValue = serialize(v); + if (serializedValue.isNull()) { + success = false; + break; + } + values << serializedValue; + } + + str = "[ " + join(values, ", ") + " ]"; + } else if (data.typeId() == QMetaType::Type::QVariantHash) { // variant is a hash? + str = serializeMap<>(data.toHash(), success); + } else if (data.typeId() == QMetaType::Type::QVariantMap) { // variant is a map? + str = serializeMap<>(data.toMap(), success); + } else if ((data.typeId() == QMetaType::Type::QString) || + (data.typeId() == + QMetaType::Type::QByteArray)) { // a string or a byte array? + str = sanitizeString(data.toString()).toUtf8(); + } else if (data.typeId() == QMetaType::Type::Double) { // double? + double value = data.toDouble(); + if ((value - value) == 0.0) { + str = QByteArray::number(value, 'g'); + if (!str.contains(".") && !str.contains("e")) { + str += ".0"; + } + } else { + success = false; + } + } else if (data.typeId() == QMetaType::Type::Bool) { // boolean value? + str = data.toBool() ? "true" : "false"; + } else if (data.typeId() == QMetaType::Type::ULongLong) { // large unsigned number? + str = QByteArray::number(data.value()); + } else if (data.canConvert()) { // any signed number? + str = QByteArray::number(data.value()); + } else if (data.canConvert()) { // TODO: this code is never executed + str = QString::number(data.value()).toUtf8(); + } else if (data.canConvert()) { // can value be converted to string? + // this will catch QDate, QDateTime, QUrl, ... + str = sanitizeString(data.toString()).toUtf8(); + } else { + success = false; + } + + if (success) { + return str; + } else { + return QByteArray(); + } +} + +QString serializeStr(const QVariant& data) +{ + return QString::fromUtf8(serialize(data)); +} + +QString serializeStr(const QVariant& data, bool& success) +{ + return QString::fromUtf8(serialize(data, success)); +} + +/** + * \enum JsonToken + */ +enum JsonToken +{ + JsonTokenNone = 0, + JsonTokenCurlyOpen = 1, + JsonTokenCurlyClose = 2, + JsonTokenSquaredOpen = 3, + JsonTokenSquaredClose = 4, + JsonTokenColon = 5, + JsonTokenComma = 6, + JsonTokenString = 7, + JsonTokenNumber = 8, + JsonTokenTrue = 9, + JsonTokenFalse = 10, + JsonTokenNull = 11 +}; + +static QString sanitizeString(QString str) +{ + str.replace(QLatin1String("\\"), QLatin1String("\\\\")); + str.replace(QLatin1String("\""), QLatin1String("\\\"")); + str.replace(QLatin1String("\b"), QLatin1String("\\b")); + str.replace(QLatin1String("\f"), QLatin1String("\\f")); + str.replace(QLatin1String("\n"), QLatin1String("\\n")); + str.replace(QLatin1String("\r"), QLatin1String("\\r")); + str.replace(QLatin1String("\t"), QLatin1String("\\t")); + return QString(QLatin1String("\"%1\"")).arg(str); +} + +static QByteArray join(const QList& list, const QByteArray& sep) +{ + QByteArray res; + Q_FOREACH (const QByteArray& i, list) { + if (!res.isEmpty()) { + res += sep; + } + res += i; + } + return res; +} + +/** + * parseValue + */ +static QVariant parseValue(const QString& json, int& index, bool& success) +{ + // Determine what kind of data we should parse by + // checking out the upcoming token + switch (lookAhead(json, index)) { + case JsonTokenString: + return parseString(json, index, success); + case JsonTokenNumber: + return parseNumber(json, index); + case JsonTokenCurlyOpen: + return parseObject(json, index, success); + case JsonTokenSquaredOpen: + return parseArray(json, index, success); + case JsonTokenTrue: + nextToken(json, index); + return QVariant(true); + case JsonTokenFalse: + nextToken(json, index); + return QVariant(false); + case JsonTokenNull: + nextToken(json, index); + return QVariant(); + case JsonTokenNone: + break; + } + + // If there were no tokens, flag the failure and return an empty QVariant + success = false; + return QVariant(); +} + +/** + * parseObject + */ +static QVariant parseObject(const QString& json, int& index, bool& success) +{ + QVariantMap map; + int token; + + // Get rid of the whitespace and increment index + nextToken(json, index); + + // Loop through all of the key/value pairs of the object + bool done = false; + while (!done) { + // Get the upcoming token + token = lookAhead(json, index); + + if (token == JsonTokenNone) { + success = false; + return QVariantMap(); + } else if (token == JsonTokenComma) { + nextToken(json, index); + } else if (token == JsonTokenCurlyClose) { + nextToken(json, index); + return map; + } else { + // Parse the key/value pair's name + QString name = parseString(json, index, success).toString(); + + if (!success) { + return QVariantMap(); + } + + // Get the next token + token = nextToken(json, index); + + // If the next token is not a colon, flag the failure + // return an empty QVariant + if (token != JsonTokenColon) { + success = false; + return QVariant(QVariantMap()); + } + + // Parse the key/value pair's value + QVariant value = parseValue(json, index, success); + + if (!success) { + return QVariantMap(); + } + + // Assign the value to the key in the map + map[name] = value; + } + } + + // Return the map successfully + return QVariant(map); +} + +/** + * parseArray + */ +static QVariant parseArray(const QString& json, int& index, bool& success) +{ + QVariantList list; + + nextToken(json, index); + + bool done = false; + while (!done) { + int token = lookAhead(json, index); + + if (token == JsonTokenNone) { + success = false; + return QVariantList(); + } else if (token == JsonTokenComma) { + nextToken(json, index); + } else if (token == JsonTokenSquaredClose) { + nextToken(json, index); + break; + } else { + QVariant value = parseValue(json, index, success); + if (!success) { + return QVariantList(); + } + list.push_back(value); + } + } + + return QVariant(list); +} + +/** + * parseString + */ +static QVariant parseString(const QString& json, int& index, bool& success) +{ + QString s; + QChar c; + + eatWhitespace(json, index); + + c = json[index++]; + + bool complete = false; + while (!complete) { + if (index == json.size()) { + break; + } + + c = json[index++]; + + if (c == '\"') { + complete = true; + break; + } else if (c == '\\') { + if (index == json.size()) { + break; + } + + c = json[index++]; + + if (c == '\"') { + s.append('\"'); + } else if (c == '\\') { + s.append('\\'); + } else if (c == '/') { + s.append('/'); + } else if (c == 'b') { + s.append('\b'); + } else if (c == 'f') { + s.append('\f'); + } else if (c == 'n') { + s.append('\n'); + } else if (c == 'r') { + s.append('\r'); + } else if (c == 't') { + s.append('\t'); + } else if (c == 'u') { + qsizetype remainingLength = json.size() - index; + if (remainingLength >= 4) { + QString unicodeStr = json.mid(index, 4); + + int symbol = unicodeStr.toInt(0, 16); + + s.append(QChar(symbol)); + + index += 4; + } else { + break; + } + } + } else { + s.append(c); + } + } + + if (!complete) { + success = false; + return QVariant(); + } + + return QVariant(s); +} + +/** + * parseNumber + */ +static QVariant parseNumber(const QString& json, int& index) +{ + eatWhitespace(json, index); + + int lastIndex = lastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + QString numberStr; + + numberStr = json.mid(index, charLength); + + index = lastIndex + 1; + bool ok; + + if (numberStr.contains('.')) { + return QVariant(numberStr.toDouble(nullptr)); + } else if (numberStr.startsWith('-')) { + int i = numberStr.toInt(&ok); + if (!ok) { + qlonglong ll = numberStr.toLongLong(&ok); + return ok ? ll : QVariant(numberStr); + } + return i; + } else { + uint u = numberStr.toUInt(&ok); + if (!ok) { + qulonglong ull = numberStr.toULongLong(&ok); + return ok ? ull : QVariant(numberStr); + } + return u; + } +} + +/** + * lastIndexOfNumber + */ +static int lastIndexOfNumber(const QString& json, int index) +{ + int lastIndex; + + for (lastIndex = index; lastIndex < json.size(); lastIndex++) { + if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) { + break; + } + } + + return lastIndex - 1; +} + +/** + * eatWhitespace + */ +static void eatWhitespace(const QString& json, int& index) +{ + for (; index < json.size(); index++) { + if (QString(" \t\n\r").indexOf(json[index]) == -1) { + break; + } + } +} + +/** + * lookAhead + */ +static int lookAhead(const QString& json, int index) +{ + int saveIndex = index; + return nextToken(json, saveIndex); +} + +/** + * nextToken + */ +static int nextToken(const QString& json, int& index) +{ + eatWhitespace(json, index); + + if (index == json.size()) { + return JsonTokenNone; + } + + QChar c = json[index]; + index++; + switch (c.toLatin1()) { + case '{': + return JsonTokenCurlyOpen; + case '}': + return JsonTokenCurlyClose; + case '[': + return JsonTokenSquaredOpen; + case ']': + return JsonTokenSquaredClose; + case ',': + return JsonTokenComma; + case '"': + return JsonTokenString; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return JsonTokenNumber; + case ':': + return JsonTokenColon; + } + index--; // ^ WTF? + + qsizetype remainingLength = json.size() - index; + + // True + if (remainingLength >= 4) { + if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && + json[index + 3] == 'e') { + index += 4; + return JsonTokenTrue; + } + } + + // False + if (remainingLength >= 5) { + if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && + json[index + 3] == 's' && json[index + 4] == 'e') { + index += 5; + return JsonTokenFalse; + } + } + + // Null + if (remainingLength >= 4) { + if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && + json[index + 3] == 'l') { + index += 4; + return JsonTokenNull; + } + } + + return JsonTokenNone; +} +} // namespace QtJson diff --git a/src/json.h b/src/json.h index 56c76126..ad41bbc0 100644 --- a/src/json.h +++ b/src/json.h @@ -1,95 +1,95 @@ -/** - * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. - * Copyright (C) 2011 Eeli Reilin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file json.h - */ - -#ifndef JSON_H -#define JSON_H - -#include -#include -#include - - -/** - * \namespace QtJson - * \brief A JSON data parser - * - * Json parses a JSON data into a QVariant hierarchy. - */ -namespace QtJson { - typedef QVariantMap JsonObject; - typedef QVariantList JsonArray; - - /** - * Parse a JSON string - * - * \param json The JSON data - */ - QVariant parse(const QString &json); - - /** - * Parse a JSON string - * - * \param json The JSON data - * \param success The success of the parsing - */ - QVariant parse(const QString &json, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QByteArray Textual JSON representation in UTF-8 - */ - QByteArray serialize(const QVariant &data, bool &success); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data); - - /** - * This method generates a textual JSON representation - * - * \param data The JSON data generated by the parser. - * \param success The success of the serialization - * - * \return QString Textual JSON representation - */ - QString serializeStr(const QVariant &data, bool &success); -} - -#endif //JSON_H +/** + * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and + * vice-versa. Copyright (C) 2011 Eeli Reilin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file json.h + */ + +#ifndef JSON_H +#define JSON_H + +#include +#include +#include + +/** + * \namespace QtJson + * \brief A JSON data parser + * + * Json parses a JSON data into a QVariant hierarchy. + */ +namespace QtJson +{ +typedef QVariantMap JsonObject; +typedef QVariantList JsonArray; + +/** + * Parse a JSON string + * + * \param json The JSON data + */ +QVariant parse(const QString& json); + +/** + * Parse a JSON string + * + * \param json The JSON data + * \param success The success of the parsing + */ +QVariant parse(const QString& json, bool& success); + +/** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QByteArray Textual JSON representation in UTF-8 + */ +QByteArray serialize(const QVariant& data); + +/** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QByteArray Textual JSON representation in UTF-8 + */ +QByteArray serialize(const QVariant& data, bool& success); + +/** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QString Textual JSON representation + */ +QString serializeStr(const QVariant& data); + +/** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QString Textual JSON representation + */ +QString serializeStr(const QVariant& data, bool& success); +} // namespace QtJson + +#endif // JSON_H diff --git a/src/lineeditclear.cpp b/src/lineeditclear.cpp index 1e32e1a0..4d86a526 100644 --- a/src/lineeditclear.cpp +++ b/src/lineeditclear.cpp @@ -1,51 +1,50 @@ -/**************************************************************************** -** -** Copyright (c) 2007 Trolltech ASA -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - - -#include "lineeditclear.h" -#include -#include - -namespace MOBase { - - -LineEditClear::LineEditClear(QWidget *parent) - : QLineEdit(parent) -{ - clearButton = new QToolButton(this); - QPixmap pixmap(":/MO/gui/edit_clear"); - clearButton->setIcon(QIcon(pixmap)); - clearButton->setIconSize(pixmap.size()); - clearButton->setCursor(Qt::ArrowCursor); - clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); - clearButton->hide(); - connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1)); -/* QSize msz = minimumSizeHint(); - setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2), - qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2));*/ -} - - -void LineEditClear::resizeEvent(QResizeEvent *) -{ - QSize sz = clearButton->sizeHint(); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - clearButton->move(rect().right() - frameWidth - sz.width(), - (rect().bottom() + 1 - sz.height())/2); -} - -void LineEditClear::updateCloseButton(const QString& text) -{ - clearButton->setVisible(!text.isEmpty()); -} - -} // namespace MOBase +/**************************************************************************** +** +** Copyright (c) 2007 Trolltech ASA +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#include "lineeditclear.h" +#include +#include + +namespace MOBase +{ + +LineEditClear::LineEditClear(QWidget* parent) : QLineEdit(parent) +{ + clearButton = new QToolButton(this); + QPixmap pixmap(":/MO/gui/edit_clear"); + clearButton->setIcon(QIcon(pixmap)); + clearButton->setIconSize(pixmap.size()); + clearButton->setCursor(Qt::ArrowCursor); + clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); + clearButton->hide(); + connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(this, SIGNAL(textChanged(const QString&)), this, + SLOT(updateCloseButton(const QString&))); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + setStyleSheet(QString("QLineEdit { padding-right: %1px; } ") + .arg(clearButton->sizeHint().width() + frameWidth + 1)); + /* QSize msz = minimumSizeHint(); + setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + + 2), qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2));*/ +} + +void LineEditClear::resizeEvent(QResizeEvent*) +{ + QSize sz = clearButton->sizeHint(); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + clearButton->move(rect().right() - frameWidth - sz.width(), + (rect().bottom() + 1 - sz.height()) / 2); +} + +void LineEditClear::updateCloseButton(const QString& text) +{ + clearButton->setVisible(!text.isEmpty()); +} + +} // namespace MOBase diff --git a/src/lineeditclear.h b/src/lineeditclear.h index 779e12f8..dfded641 100644 --- a/src/lineeditclear.h +++ b/src/lineeditclear.h @@ -1,40 +1,40 @@ -/**************************************************************************** -** -** Copyright (c) 2007 Trolltech ASA -** -** Use, modification and distribution is allowed without limitation, -** warranty, liability or support of any kind. -** -****************************************************************************/ - -#ifndef LINEEDITCLEAR_H -#define LINEEDITCLEAR_H - -#include "dllimport.h" -#include - -class QToolButton; - -namespace MOBase { - -class QDLLEXPORT LineEditClear : public QLineEdit -{ - Q_OBJECT - -public: - LineEditClear(QWidget *parent = 0); - -protected: - void resizeEvent(QResizeEvent *); - -private slots: - void updateCloseButton(const QString &text); - -private: - QToolButton *clearButton; -}; - - -} // namespace MOBase - -#endif // LINEEDITCLEAR_H +/**************************************************************************** +** +** Copyright (c) 2007 Trolltech ASA +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#ifndef LINEEDITCLEAR_H +#define LINEEDITCLEAR_H + +#include "dllimport.h" +#include + +class QToolButton; + +namespace MOBase +{ + +class QDLLEXPORT LineEditClear : public QLineEdit +{ + Q_OBJECT + +public: + LineEditClear(QWidget* parent = 0); + +protected: + void resizeEvent(QResizeEvent*); + +private slots: + void updateCloseButton(const QString& text); + +private: + QToolButton* clearButton; +}; + +} // namespace MOBase + +#endif // LINEEDITCLEAR_H diff --git a/src/linklabel.cpp b/src/linklabel.cpp index 3c03bf18..3ff6252d 100644 --- a/src/linklabel.cpp +++ b/src/linklabel.cpp @@ -2,10 +2,7 @@ QColor LinkLabel::m_linkColor; -LinkLabel::LinkLabel(QWidget* parent) - : QLabel(parent) -{ -} +LinkLabel::LinkLabel(QWidget* parent) : QLabel(parent) {} QColor LinkLabel::linkColor() const { diff --git a/src/linklabel.h b/src/linklabel.h index 3f7fb426..80fa9580 100644 --- a/src/linklabel.h +++ b/src/linklabel.h @@ -26,7 +26,7 @@ class QDLLEXPORT LinkLabel : public QLabel Q_PROPERTY(QColor linkColor READ linkColor WRITE setLinkColor); public: - LinkLabel(QWidget* parent=nullptr); + LinkLabel(QWidget* parent = nullptr); QColor linkColor() const; void setLinkColor(const QColor& c); @@ -35,4 +35,4 @@ class QDLLEXPORT LinkLabel : public QLabel static QColor m_linkColor; }; -#endif // UIBASE_LINKLABEL_INCLUDED +#endif // UIBASE_LINKLABEL_INCLUDED diff --git a/src/log.cpp b/src/log.cpp index 207d5f37..6f6f0fb9 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -1,26 +1,25 @@ -#include "pch.h" #include "log.h" +#include "pch.h" #include "utility.h" #include #pragma warning(push) -#pragma warning(disable: 4668) +#pragma warning(disable : 4668) #include #pragma warning(pop) #pragma warning(push) -#pragma warning(disable: 4365) +#pragma warning(disable : 4365) #define SPDLOG_WCHAR_FILENAMES 1 #include -#include #include -#include +#include #include +#include #include -#include +#include #pragma warning(pop) - namespace MOBase::log { @@ -29,58 +28,50 @@ static std::unique_ptr g_default; spdlog::level::level_enum toSpdlog(Levels lv) { - switch (lv) - { - case Debug: - return spdlog::level::debug; + switch (lv) { + case Debug: + return spdlog::level::debug; - case Warning: - return spdlog::level::warn; + case Warning: + return spdlog::level::warn; - case Error: - return spdlog::level::err; + case Error: + return spdlog::level::err; - case Info: // fall-through - default: - return spdlog::level::info; + case Info: // fall-through + default: + return spdlog::level::info; } } Levels fromSpdlog(spdlog::level::level_enum lv) { - switch (lv) - { - case spdlog::level::trace: - case spdlog::level::debug: - return Debug; + switch (lv) { + case spdlog::level::trace: + case spdlog::level::debug: + return Debug; - case spdlog::level::warn: - return Warning; + case spdlog::level::warn: + return Warning; - case spdlog::level::critical: // fall-through - case spdlog::level::err: - return Error; + case spdlog::level::critical: // fall-through + case spdlog::level::err: + return Error; - case spdlog::level::info: // fall-through - case spdlog::level::off: - case spdlog::level::n_levels: // to please MSVC - default: - return Info; + case spdlog::level::info: // fall-through + case spdlog::level::off: + case spdlog::level::n_levels: // to please MSVC + default: + return Info; } } class CallbackSink : public spdlog::sinks::base_sink { public: - CallbackSink(Callback* f) - : m_f(f) - { - } + CallbackSink(Callback* f) : m_f(f) {} - void setCallback(Callback* f) - { - m_f = f; - } + void setCallback(Callback* f) { m_f = f; } protected: void sink_it_(const spdlog::details::log_msg& m) override @@ -97,14 +88,15 @@ class CallbackSink : public spdlog::sinks::base_sink return; } - try - { - auto g = Guard([&]{ active = false; }); + try { + auto g = Guard([&] { + active = false; + }); active = true; Entry e; - e.time = m.time; - e.level = fromSpdlog(m.level); + e.time = m.time; + e.level = fromSpdlog(m.level); e.message = fmt::to_string(m.payload); spdlog::memory_buf_t formatted; @@ -118,15 +110,9 @@ class CallbackSink : public spdlog::sinks::base_sink } (*m_f)(std::move(e)); - } - catch(std::exception& e) - { - fprintf( - stderr, "uncaugh exception in logging callback, %s\n", - e.what()); - } - catch(...) - { + } catch (std::exception& e) { + fprintf(stderr, "uncaugh exception in logging callback, %s\n", e.what()); + } catch (...) { fprintf(stderr, "uncaught exception in logging callback\n"); } } @@ -140,34 +126,27 @@ class CallbackSink : public spdlog::sinks::base_sink std::atomic m_f; }; - -File::File() : - type(None), - maxSize(0), maxFiles(0), - dailyHour(0), dailyMinute(0) -{ -} +File::File() : type(None), maxSize(0), maxFiles(0), dailyHour(0), dailyMinute(0) {} File File::daily(fs::path file, int hour, int minute) { File fl; - fl.type = Daily; - fl.file = std::move(file); - fl.dailyHour = hour; + fl.type = Daily; + fl.file = std::move(file); + fl.dailyHour = hour; fl.dailyMinute = minute; return fl; } -File File::rotating( - fs::path file, std::size_t maxSize, std::size_t maxFiles) +File File::rotating(fs::path file, std::size_t maxSize, std::size_t maxFiles) { File fl; - fl.type = Rotating; - fl.file = std::move(file); - fl.maxSize = maxSize; + fl.type = Rotating; + fl.file = std::move(file); + fl.maxSize = maxSize; fl.maxFiles = maxFiles; return fl; @@ -185,48 +164,38 @@ File File::single(std::filesystem::path file) spdlog::sink_ptr createFileSink(const File& f) { - try - { - switch (f.type) - { - case File::Daily: - { - return std::make_shared( + try { + switch (f.type) { + case File::Daily: { + return std::make_shared( f.file.native(), f.dailyHour, f.dailyMinute); - } + } - case File::Rotating: - { - return std::make_shared( + case File::Rotating: { + return std::make_shared( f.file.native(), f.maxSize, f.maxFiles); - } + } - case File::Single: - { - return std::make_shared( - f.file.native(), true); - } + case File::Single: { + return std::make_shared(f.file.native(), true); + } - case File::None: // fall-through - default: - return {}; + case File::None: // fall-through + default: + return {}; } - } - catch(spdlog::spdlog_ex& e) - { + } catch (spdlog::spdlog_ex& e) { std::cerr << "failed to create file log, " << e.what() << "\n"; return {}; } } - -Logger::Logger(LoggerConfiguration conf_moved) - : m_conf(std::move(conf_moved)) +Logger::Logger(LoggerConfiguration conf_moved) : m_conf(std::move(conf_moved)) { createLogger(m_conf.name); - const auto timeType = m_conf.utc ? - spdlog::pattern_time_type::utc : spdlog::pattern_time_type::local; + const auto timeType = + m_conf.utc ? spdlog::pattern_time_type::utc : spdlog::pattern_time_type::local; m_logger->set_level(toSpdlog(m_conf.maxLevel)); m_logger->set_pattern(m_conf.pattern, timeType); @@ -261,16 +230,13 @@ void Logger::setFile(const File& f) } if (f.type != File::None) { - try - { + try { m_file = createFileSink(f); if (m_file) { addSink(m_file); } - } - catch(spdlog::spdlog_ex& e) - { + } catch (spdlog::spdlog_ex& e) { error(e.what()); } } @@ -288,44 +254,43 @@ void Logger::setCallback(Callback* f) void Logger::addToBlacklist(const std::string& filter, const std::string& replacement) { - if (filter.length() <= 0 || replacement.length() <= 0) { - // nothing to do - return; - } + if (filter.length() <= 0 || replacement.length() <= 0) { + // nothing to do + return; + } - bool present = false; - for (BlacklistEntry& e : m_conf.blacklist) { - if (boost::algorithm::iequals(e.filter, filter)) { - e.replacement = replacement; - present = true; - break; - } - } - if (!present) { - m_conf.blacklist.push_back(BlacklistEntry(filter, replacement)); + bool present = false; + for (BlacklistEntry& e : m_conf.blacklist) { + if (boost::algorithm::iequals(e.filter, filter)) { + e.replacement = replacement; + present = true; + break; } + } + if (!present) { + m_conf.blacklist.push_back(BlacklistEntry(filter, replacement)); + } } void Logger::removeFromBlacklist(const std::string& filter) { - if (filter.length() <= 0) { - // nothing to do - return; - } + if (filter.length() <= 0) { + // nothing to do + return; + } - for (auto it = m_conf.blacklist.begin(); it != m_conf.blacklist.end(); ) { - if (boost::algorithm::iequals(it->filter, filter)) { - it = m_conf.blacklist.erase(it); - } - else { - ++it; - } + for (auto it = m_conf.blacklist.begin(); it != m_conf.blacklist.end();) { + if (boost::algorithm::iequals(it->filter, filter)) { + it = m_conf.blacklist.erase(it); + } else { + ++it; } + } } void Logger::resetBlacklist() { - m_conf.blacklist.clear(); + m_conf.blacklist.clear(); } void Logger::createLogger(const std::string& name) @@ -334,15 +299,17 @@ void Logger::createLogger(const std::string& name) DWORD console_mode; if (::GetConsoleMode(::GetStdHandle(STD_ERROR_HANDLE), &console_mode) != 0) { - using sink_type = spdlog::sinks::wincolor_stderr_sink_mt; - m_console.reset(new sink_type); - - if (auto* cs = dynamic_cast(m_console.get())) { - cs->set_color(spdlog::level::info, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - cs->set_color(spdlog::level::debug, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - } + using sink_type = spdlog::sinks::wincolor_stderr_sink_mt; + m_console.reset(new sink_type); + + if (auto* cs = dynamic_cast(m_console.get())) { + cs->set_color(spdlog::level::info, + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + cs->set_color(spdlog::level::debug, + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + } - addSink(m_console); + addSink(m_console); } m_logger.reset(new spdlog::logger(name, m_sinks)); @@ -368,26 +335,24 @@ void Logger::addSink(std::shared_ptr sink) auto* ds = static_cast*>(m_sinks.get()); - const auto timeType = m_conf.utc ? - spdlog::pattern_time_type::utc : spdlog::pattern_time_type::local; + const auto timeType = + m_conf.utc ? spdlog::pattern_time_type::utc : spdlog::pattern_time_type::local; - sink->set_formatter(std::make_unique( - m_conf.pattern, timeType)); + sink->set_formatter( + std::make_unique(m_conf.pattern, timeType)); ds->add_sink(sink); } - QString levelToString(Levels level) { const auto spdlogLevel = toSpdlog(level); - const auto sv = spdlog::level::to_string_view(spdlogLevel); + const auto sv = spdlog::level::to_string_view(spdlogLevel); const std::string s(sv.begin(), sv.end()); return QString::fromStdString(s); } - void createDefault(LoggerConfiguration conf) { g_default = std::make_unique(conf); @@ -399,8 +364,7 @@ Logger& getDefault() return *g_default; } -} // namespace - +} // namespace MOBase::log namespace MOBase::log::details { @@ -427,15 +391,12 @@ std::string converter::convert(const QSize& s) std::string converter::convert(const QRect& r) { - return fmt::format( - "QRect({},{}-{},{})", r.left(), r.top(), r.right(), r.bottom()); + return fmt::format("QRect({},{}-{},{})", r.left(), r.top(), r.right(), r.bottom()); } std::string converter::convert(const QColor& c) { - return fmt::format( - "QColor({}, {}, {}, {})", - c.red(), c.green(), c.blue(), c.alpha()); + return fmt::format("QColor({}, {}, {}, {})", c.red(), c.green(), c.blue(), c.alpha()); } std::string converter::convert(const QByteArray& v) @@ -445,19 +406,17 @@ std::string converter::convert(const QByteArray& v) std::string converter::convert(const QVariant& v) { - return fmt::format( - "QVariant(type={}, value='{}')", - v.typeName(), (v.typeId() == QMetaType::Type::QByteArray ? - "(binary)" : v.toString().toStdString())); + return fmt::format("QVariant(type={}, value='{}')", v.typeName(), + (v.typeId() == QMetaType::Type::QByteArray + ? "(binary)" + : v.toString().toStdString())); } - void doLogImpl(spdlog::logger& lg, Levels lv, const std::string& s) noexcept { - try - { + try { const char* start = s.c_str(); - const char* p = start; + const char* p = start; for (;;) { while (*p && *p != '\n') { @@ -474,18 +433,16 @@ void doLogImpl(spdlog::logger& lg, Levels lv, const std::string& s) noexcept ++p; start = p; } - } - catch(...) - { + } catch (...) { // eat it } } -void ireplace_all(std::string& input, std::string const& search, std::string const& replace) noexcept +void ireplace_all(std::string& input, std::string const& search, + std::string const& replace) noexcept { // call boost here to avoid bringing the boost include in the header boost::algorithm::ireplace_all(input, search, replace); } - -} // namespace +} // namespace MOBase::log::details diff --git a/src/log.h b/src/log.h index deaa6916..a0b21f69 100644 --- a/src/log.h +++ b/src/log.h @@ -1,14 +1,14 @@ #pragma once -#include -#include -#include +#include #include +#include +#include #include #include -#include -#include -#include +#include +#include +#include #pragma warning(push) #pragma warning(disable : 4061 4459 4574 4582) @@ -18,8 +18,14 @@ #include "dllimport.h" -namespace spdlog { class logger; } -namespace spdlog::sinks { class sink; } +namespace spdlog +{ +class logger; +} +namespace spdlog::sinks +{ +class sink; +} namespace MOBase::log { @@ -34,12 +40,11 @@ enum Levels struct BlacklistEntry { - std::string filter; - std::string replacement; + std::string filter; + std::string replacement; }; -} // namespace - +} // namespace MOBase::log namespace MOBase::log::details { @@ -52,10 +57,7 @@ namespace MOBase::log::details template struct converter { - static const T& convert(const T& t) - { - return t; - } + static const T& convert(const T& t) { return t; } }; template <> @@ -76,7 +78,6 @@ struct QDLLEXPORT converter static std::string convert(const QStringView& s); }; - template <> struct QDLLEXPORT converter { @@ -111,63 +112,51 @@ struct QDLLEXPORT converter template struct QDLLEXPORT converter>> { - static auto convert(const T& v) - { - return static_cast>(v); - } + static auto convert(const T& v) { return static_cast>(v); } }; -void QDLLEXPORT doLogImpl( - spdlog::logger& lg, Levels lv, const std::string& s) noexcept; +void QDLLEXPORT doLogImpl(spdlog::logger& lg, Levels lv, const std::string& s) noexcept; -void QDLLEXPORT ireplace_all(std::string& input, std::string const& search, std::string const& replace) noexcept; +void QDLLEXPORT ireplace_all(std::string& input, std::string const& search, + std::string const& replace) noexcept; template -void doLog( - spdlog::logger& logger, Levels lv, const std::vector bl, F&& format, Args&&... args) noexcept +void doLog(spdlog::logger& logger, Levels lv, + const std::vector bl, F&& format, + Args&&... args) noexcept { std::string s; // format errors are logged without much information to avoid throwing again - try - { - if constexpr (sizeof... (Args) == 0) { + try { + if constexpr (sizeof...(Args) == 0) { s = fmt::format("{}", std::forward(format)); - } - else { - s = fmt::vformat( - std::forward(format), - fmt::make_format_args( - converter>::convert(std::forward(args))...)); + } else { + s = fmt::vformat(std::forward(format), + fmt::make_format_args(converter>::convert( + std::forward(args))...)); } // check the blacklist for (const BlacklistEntry& entry : bl) { ireplace_all(s, entry.filter, entry.replacement); } - } - catch(fmt::format_error&) - { - s = "format error while logging"; + } catch (fmt::format_error&) { + s = "format error while logging"; lv = Levels::Error; - } - catch(std::exception&) - { - s = "exception while formatting for logging"; + } catch (std::exception&) { + s = "exception while formatting for logging"; lv = Levels::Error; - } - catch(...) - { - s = "unknown exception while formatting for logging"; + } catch (...) { + s = "unknown exception while formatting for logging"; lv = Levels::Error; } doLogImpl(logger, lv, s); } -} // namespace - +} // namespace MOBase::log::details namespace MOBase::log { @@ -187,8 +176,8 @@ struct QDLLEXPORT File static File daily(std::filesystem::path file, int hour, int minute); - static File rotating( - std::filesystem::path file, std::size_t maxSize, std::size_t maxFiles); + static File rotating(std::filesystem::path file, std::size_t maxSize, + std::size_t maxFiles); static File single(std::filesystem::path file); @@ -198,7 +187,6 @@ struct QDLLEXPORT File int dailyHour, dailyMinute; }; - struct Entry { std::chrono::system_clock::time_point time; @@ -207,7 +195,7 @@ struct Entry std::string formattedMessage; }; -using Callback = void (Entry); +using Callback = void(Entry); struct LoggerConfiguration { @@ -218,7 +206,6 @@ struct LoggerConfiguration std::vector blacklist; }; - class QDLLEXPORT Logger { public: @@ -263,8 +250,8 @@ class QDLLEXPORT Logger template void log(Levels lv, F&& format, Args&&... args) noexcept { - details::doLog( - *m_logger, lv, m_conf.blacklist, std::forward(format), std::forward(args)...); + details::doLog(*m_logger, lv, m_conf.blacklist, std::forward(format), + std::forward(args)...); } private: @@ -280,44 +267,37 @@ class QDLLEXPORT Logger QDLLEXPORT void createDefault(LoggerConfiguration conf); QDLLEXPORT Logger& getDefault(); - template void debug(F&& format, Args&&... args) noexcept { - getDefault().debug( - std::forward(format), std::forward(args)...); + getDefault().debug(std::forward(format), std::forward(args)...); } template void info(F&& format, Args&&... args) noexcept { - getDefault().info( - std::forward(format), std::forward(args)...); + getDefault().info(std::forward(format), std::forward(args)...); } template void warn(F&& format, Args&&... args) noexcept { - getDefault().warn( - std::forward(format), std::forward(args)...); + getDefault().warn(std::forward(format), std::forward(args)...); } template void error(F&& format, Args&&... args) noexcept { - getDefault().error( - std::forward(format), std::forward(args)...); + getDefault().error(std::forward(format), std::forward(args)...); } template void log(Levels lv, F&& format, Args&&... args) noexcept { - getDefault().log( - lv, std::forward(format), std::forward(args)...); + getDefault().log(lv, std::forward(format), std::forward(args)...); } - // QDLLEXPORT QString levelToString(Levels level); -} // namespace +} // namespace MOBase::log diff --git a/src/memoizedlock.h b/src/memoizedlock.h index f91e8689..18884846 100644 --- a/src/memoizedlock.h +++ b/src/memoizedlock.h @@ -8,7 +8,8 @@ #include #include -namespace MOBase { +namespace MOBase +{ /** * Class that can be used to perform thread-safe memoization. @@ -24,37 +25,37 @@ namespace MOBase { * @tparam Fn Type of the callback. */ template > -class MemoizedLocked { +class MemoizedLocked +{ public: - template - MemoizedLocked(Callable&& callable, T value = {}) : - m_Fn{ std::forward(callable) }, m_Value{ std::move(value) } { } + MemoizedLocked(Callable&& callable, T value = {}) + : m_Fn{std::forward(callable)}, m_Value{std::move(value)} + {} template - T& value(Args&&... args) const { + T& value(Args&&... args) const + { if (m_NeedUpdating) { std::scoped_lock lock(m_Mutex); if (m_NeedUpdating) { - m_Value = std::invoke(m_Fn, std::forward(args)...); + m_Value = std::invoke(m_Fn, std::forward(args)...); m_NeedUpdating = false; } } return m_Value; } - void invalidate() { - m_NeedUpdating = true; - } + void invalidate() { m_NeedUpdating = true; } private: mutable std::mutex m_Mutex; - mutable std::atomic m_NeedUpdating{ true }; + mutable std::atomic m_NeedUpdating{true}; Fn m_Fn; mutable T m_Value; }; -} +} // namespace MOBase -#endif \ No newline at end of file +#endif diff --git a/src/moassert.h b/src/moassert.h index 85bd361b..94ba6efa 100644 --- a/src/moassert.h +++ b/src/moassert.h @@ -7,11 +7,10 @@ namespace MOBase { template -inline void MOAssert( - T&& t, const char* exp, const char* file, int line, const char* func) +inline void MOAssert(T&& t, const char* exp, const char* file, int line, + const char* func) { - if (!t) - { + if (!t) { log::error("assertion failed: {}:{} {}: '{}'", file, line, func, exp); if (IsDebuggerPresent()) { @@ -20,9 +19,8 @@ inline void MOAssert( } } -} // namespace - +} // namespace MOBase #define MO_ASSERT(v) MOAssert(v, #v, __FILE__, __LINE__, __FUNCSIG__) -#endif // UIBASE_MOASSERT_INCLUDED +#endif // UIBASE_MOASSERT_INCLUDED diff --git a/src/modrepositoryfileinfo.cpp b/src/modrepositoryfileinfo.cpp index 51ac0430..2da73379 100644 --- a/src/modrepositoryfileinfo.cpp +++ b/src/modrepositoryfileinfo.cpp @@ -1,71 +1,72 @@ -#include "modrepositoryfileinfo.h" -#include "json.h" - - -MOBase::ModRepositoryFileInfo::ModRepositoryFileInfo(const ModRepositoryFileInfo &reference) - : QObject(reference.parent()), name(reference.name), uri(reference.uri), description(reference.description), - version(reference.version), categoryID(reference.categoryID), modName(reference.modName), - gameName(reference.gameName), modID(reference.modID), fileID(reference.fileID), fileSize(reference.fileSize), - fileCategory(reference.fileCategory), - repository(reference.repository), userData(reference.userData) -{ -} - -MOBase::ModRepositoryFileInfo::ModRepositoryFileInfo(QString gameName, int modID, int fileID) - : name(), uri(), description(), version(), categoryID(0), modName(), gameName(gameName), modID(modID), fileID(fileID), - fileSize(0), fileCategory(TYPE_UNKNOWN), repository(), userData() - -{ - -} - - -MOBase::ModRepositoryFileInfo MOBase::ModRepositoryFileInfo::createFromJson(const QString &data) -{ - QVariantList result = QtJson::parse(data).toList(); - - while (result.length() < 15) { - result.append(QVariant()); - } - - ModRepositoryFileInfo newInfo; - - newInfo.gameName = result.at(0).toString(); - newInfo.fileID = result.at(1).toInt(); - newInfo.name = result.at(2).toString(); - newInfo.uri = result.at(3).toString(); - newInfo.version.parse(result.at(4).toString()); - newInfo.description = result.at(5).toString(); - newInfo.categoryID = result.at(6).toInt(); - newInfo.fileSize = result.at(7).toUInt(); - newInfo.modID = result.at(8).toInt(); - newInfo.modName = result.at(9).toString(); - newInfo.newestVersion.parse(result.at(10).toString()); - newInfo.fileName = result.at(11).toString(); - newInfo.fileCategory = result.at(12).toInt(); - newInfo.repository = result.at(13).toString(); - newInfo.userData = result.at(14).toMap(); - - return newInfo; -} - - -QString MOBase::ModRepositoryFileInfo::toString() const -{ - return QString("[ \"%1\",%2,\"%3\",\"%4\",\"%5\",\"%6\",%7,%8,%9,\"%10\",\"%11\",\"%12\",%13,\"%14\",%15 ]") - .arg(gameName) - .arg(fileID) - .arg(name) - .arg(uri) - .arg(version.canonicalString()) - .arg(description.mid(0).replace("\"", "'")) - .arg(categoryID) - .arg(fileSize) - .arg(modID) - .arg(modName) - .arg(newestVersion.canonicalString()) - .arg(fileName) - .arg(fileCategory) - .arg(repository) - .arg(QString(QtJson::serialize(userData))); -} +#include "modrepositoryfileinfo.h" +#include "json.h" + +MOBase::ModRepositoryFileInfo::ModRepositoryFileInfo( + const ModRepositoryFileInfo& reference) + : QObject(reference.parent()), name(reference.name), uri(reference.uri), + description(reference.description), version(reference.version), + categoryID(reference.categoryID), modName(reference.modName), + gameName(reference.gameName), modID(reference.modID), fileID(reference.fileID), + fileSize(reference.fileSize), fileCategory(reference.fileCategory), + repository(reference.repository), userData(reference.userData) +{} + +MOBase::ModRepositoryFileInfo::ModRepositoryFileInfo(QString gameName, int modID, + int fileID) + : name(), uri(), description(), version(), categoryID(0), modName(), + gameName(gameName), modID(modID), fileID(fileID), fileSize(0), + fileCategory(TYPE_UNKNOWN), repository(), userData() + +{} + +MOBase::ModRepositoryFileInfo +MOBase::ModRepositoryFileInfo::createFromJson(const QString& data) +{ + QVariantList result = QtJson::parse(data).toList(); + + while (result.length() < 15) { + result.append(QVariant()); + } + + ModRepositoryFileInfo newInfo; + + newInfo.gameName = result.at(0).toString(); + newInfo.fileID = result.at(1).toInt(); + newInfo.name = result.at(2).toString(); + newInfo.uri = result.at(3).toString(); + newInfo.version.parse(result.at(4).toString()); + newInfo.description = result.at(5).toString(); + newInfo.categoryID = result.at(6).toInt(); + newInfo.fileSize = result.at(7).toUInt(); + newInfo.modID = result.at(8).toInt(); + newInfo.modName = result.at(9).toString(); + newInfo.newestVersion.parse(result.at(10).toString()); + newInfo.fileName = result.at(11).toString(); + newInfo.fileCategory = result.at(12).toInt(); + newInfo.repository = result.at(13).toString(); + newInfo.userData = result.at(14).toMap(); + + return newInfo; +} + +QString MOBase::ModRepositoryFileInfo::toString() const +{ + return QString("[ " + "\"%1\",%2,\"%3\",\"%4\",\"%5\",\"%6\",%7,%8,%9,\"%10\",\"%11\",\"%" + "12\",%13,\"%14\",%15 ]") + .arg(gameName) + .arg(fileID) + .arg(name) + .arg(uri) + .arg(version.canonicalString()) + .arg(description.mid(0).replace("\"", "'")) + .arg(categoryID) + .arg(fileSize) + .arg(modID) + .arg(modName) + .arg(newestVersion.canonicalString()) + .arg(fileName) + .arg(fileCategory) + .arg(repository) + .arg(QString(QtJson::serialize(userData))); +} diff --git a/src/modrepositoryfileinfo.h b/src/modrepositoryfileinfo.h index b6c3bed2..27d47a02 100644 --- a/src/modrepositoryfileinfo.h +++ b/src/modrepositoryfileinfo.h @@ -2,49 +2,51 @@ #define MODREPOSITORYFILEINFO_H #include "versioninfo.h" -#include #include +#include #include -namespace MOBase { - enum EFileCategory { - TYPE_UNKNOWN = 0, - TYPE_MAIN, - TYPE_UPDATE, - TYPE_OPTION - }; - - class QDLLEXPORT ModRepositoryFileInfo : public QObject { - Q_OBJECT - - public: - - ModRepositoryFileInfo(const ModRepositoryFileInfo &reference); - ModRepositoryFileInfo(QString gameName = "", int modID = 0, int fileID = 0); - QString toString() const; - - static ModRepositoryFileInfo createFromJson(const QString &data); - QString name; - QString uri; - QString description; - VersionInfo version; - VersionInfo newestVersion; - int categoryID; - QString modName; - QString gameName; - QString nexusKey; - int modID; - int fileID; - int nexusExpires; - int nexusDownloadUser; - size_t fileSize; - QString fileName; - int fileCategory; - QDateTime fileTime; - QString repository; - - QVariantMap userData; - }; -} - -#endif // MODREPOSITORYFILEINFO_H +namespace MOBase +{ +enum EFileCategory +{ + TYPE_UNKNOWN = 0, + TYPE_MAIN, + TYPE_UPDATE, + TYPE_OPTION +}; + +class QDLLEXPORT ModRepositoryFileInfo : public QObject +{ + Q_OBJECT + +public: + ModRepositoryFileInfo(const ModRepositoryFileInfo& reference); + ModRepositoryFileInfo(QString gameName = "", int modID = 0, int fileID = 0); + QString toString() const; + + static ModRepositoryFileInfo createFromJson(const QString& data); + QString name; + QString uri; + QString description; + VersionInfo version; + VersionInfo newestVersion; + int categoryID; + QString modName; + QString gameName; + QString nexusKey; + int modID; + int fileID; + int nexusExpires; + int nexusDownloadUser; + size_t fileSize; + QString fileName; + int fileCategory; + QDateTime fileTime; + QString repository; + + QVariantMap userData; +}; +} // namespace MOBase + +#endif // MODREPOSITORYFILEINFO_H diff --git a/src/nxmurl.cpp b/src/nxmurl.cpp index 7ff980fc..0e94c05a 100644 --- a/src/nxmurl.cpp +++ b/src/nxmurl.cpp @@ -19,25 +19,26 @@ along with Mod Organizer. If not, see . #include "nxmurl.h" #include "utility.h" -#include #include +#include #include #include #include -NXMUrl::NXMUrl(const QString &url) +NXMUrl::NXMUrl(const QString& url) { QUrl nxm(url); QUrlQuery query(nxm); - QRegularExpression exp("nxm://[a-z0-9]+/mods/(\\d+)/files/(\\d+)", QRegularExpression::CaseInsensitiveOption); + QRegularExpression exp("nxm://[a-z0-9]+/mods/(\\d+)/files/(\\d+)", + QRegularExpression::CaseInsensitiveOption); auto match = exp.match(url); if (!match.hasMatch()) { throw MOBase::InvalidNXMLinkException(url); } - m_Game = nxm.host(); - m_ModId = match.captured(1).toInt(); - m_FileId = match.captured(2).toInt(); - m_Key = query.queryItemValue("key"); + m_Game = nxm.host(); + m_ModId = match.captured(1).toInt(); + m_FileId = match.captured(2).toInt(); + m_Key = query.queryItemValue("key"); m_Expires = query.queryItemValue("expires").toInt(); - m_UserId = query.queryItemValue("user_id").toInt(); + m_UserId = query.queryItemValue("user_id").toInt(); } diff --git a/src/nxmurl.h b/src/nxmurl.h index d97ba380..bd06d3dc 100644 --- a/src/nxmurl.h +++ b/src/nxmurl.h @@ -20,11 +20,10 @@ along with Mod Organizer. If not, see . #ifndef NXMURL_H #define NXMURL_H +#include "dllimport.h" #include -#include #include -#include "dllimport.h" - +#include /** * @brief represents a nxm:// url @@ -35,13 +34,12 @@ class QDLLEXPORT NXMUrl : public QObject Q_OBJECT public: - /** * @brief constructor * * @param url url following the nxm-protocol **/ - NXMUrl(const QString &url); + NXMUrl(const QString& url); /** * @return name of the game @@ -78,7 +76,6 @@ class QDLLEXPORT NXMUrl : public QObject int userId() const { return m_UserId; } private: - QString m_Game; QString m_Key; int m_ModId; @@ -87,4 +84,4 @@ class QDLLEXPORT NXMUrl : public QObject int m_UserId; }; -#endif // NXMURL_H +#endif // NXMURL_H diff --git a/src/pch.h b/src/pch.h index 94f87283..5ccae8e2 100644 --- a/src/pch.h +++ b/src/pch.h @@ -1,35 +1,37 @@ -#pragma warning(disable: 4251) // neds to have dll-interface -#pragma warning(disable: 4355) // this used in initializer list -#pragma warning(disable: 4371) // layout may have changed -#pragma warning(disable: 4514) // unreferenced inline function removed -#pragma warning(disable: 4571) // catch semantics changed -#pragma warning(disable: 4619) // no warning X -#pragma warning(disable: 4623) // default constructor deleted -#pragma warning(disable: 4625) // copy constructor deleted -#pragma warning(disable: 4626) // copy assignment operator deleted -#pragma warning(disable: 4710) // function not inlined -#pragma warning(disable: 4820) // padding -#pragma warning(disable: 4866) // left-to-right evaluation order -#pragma warning(disable: 4868) // left-to-right evaluation order -#pragma warning(disable: 5026) // move constructor deleted -#pragma warning(disable: 5027) // move assignment operator deleted -#pragma warning(disable: 5045) // spectre mitigation +#pragma warning(disable : 4251) // neds to have dll-interface +#pragma warning(disable : 4355) // this used in initializer list +#pragma warning(disable : 4371) // layout may have changed +#pragma warning(disable : 4514) // unreferenced inline function removed +#pragma warning(disable : 4571) // catch semantics changed +#pragma warning(disable : 4619) // no warning X +#pragma warning(disable : 4623) // default constructor deleted +#pragma warning(disable : 4625) // copy constructor deleted +#pragma warning(disable : 4626) // copy assignment operator deleted +#pragma warning(disable : 4710) // function not inlined +#pragma warning(disable : 4820) // padding +#pragma warning(disable : 4866) // left-to-right evaluation order +#pragma warning(disable : 4868) // left-to-right evaluation order +#pragma warning(disable : 5026) // move constructor deleted +#pragma warning(disable : 5027) // move assignment operator deleted +#pragma warning(disable : 5045) // spectre mitigation #pragma warning(push, 3) -#pragma warning(disable: 4242) // uint -> const quint8 -#pragma warning(disable: 4365) // signed/unsigned mismatch -#pragma warning(disable: 4668) // preprocessor macro used but not defined -#pragma warning(disable: 4774) // bad format string -#pragma warning(disable: 4946) // reinterpret_cast used between related classes -#pragma warning(disable: 4800) // implicit conversion -#pragma warning(disable: 5219) // implicit int -> float conversion -#pragma warning(disable: 5249) // named enumerators with values outside of bit field width +#pragma warning(disable : 4242) // uint -> const quint8 +#pragma warning(disable : 4365) // signed/unsigned mismatch +#pragma warning(disable : 4668) // preprocessor macro used but not defined +#pragma warning(disable : 4774) // bad format string +#pragma warning(disable : 4946) // reinterpret_cast used between related classes +#pragma warning(disable : 4800) // implicit conversion +#pragma warning(disable : 5219) // implicit int -> float conversion +#pragma warning( \ + disable : 5249) // named enumerators with values outside of bit field width #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING 1 // std #include #include +#include #include #include #include @@ -45,7 +47,6 @@ #include #include #include -#include // windows #ifndef NOMINMAX @@ -55,8 +56,8 @@ #define WIN32_MEAN_AND_LEAN #endif #include -#include #include +#include // Qt #include @@ -68,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -81,12 +81,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -103,15 +103,14 @@ #include #include #include +#include #include #include #include -#include #include #include -#include #include -#include +#include #include #include #include @@ -122,11 +121,13 @@ #include #include #include +#include #include #include #include -#include #include +#include +#include #undef _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING #pragma warning(pop) diff --git a/src/pluginrequirements.cpp b/src/pluginrequirements.cpp index d79ad332..05164517 100644 --- a/src/pluginrequirements.cpp +++ b/src/pluginrequirements.cpp @@ -3,17 +3,19 @@ #include #include "imoinfo.h" -#include "iplugingame.h" #include "iplugindiagnose.h" +#include "iplugingame.h" using namespace MOBase; // Plugin and Game dependencies -PluginDependencyRequirement::PluginDependencyRequirement(QStringList const& pluginNames) : - m_PluginNames(pluginNames) { } +PluginDependencyRequirement::PluginDependencyRequirement(QStringList const& pluginNames) + : m_PluginNames(pluginNames) +{} -std::optional PluginDependencyRequirement::check(IOrganizer* o) const +std::optional +PluginDependencyRequirement::check(IOrganizer* o) const { for (auto const& pluginName : m_PluginNames) { if (o->isPluginEnabled(pluginName)) { @@ -26,19 +28,21 @@ std::optional PluginDependencyRequirement::check(IO QString PluginDependencyRequirement::message() const { if (m_PluginNames.size() > 1) { - return QObject::tr( - "One of the following plugins must be enabled: %1.").arg(m_PluginNames.join(", ")); - } - else { - return QObject::tr( - "This plugin can only be enabled if the '%1' plugin is installed and enabled.").arg(m_PluginNames[0]); + return QObject::tr("One of the following plugins must be enabled: %1.") + .arg(m_PluginNames.join(", ")); + } else { + return QObject::tr("This plugin can only be enabled if the '%1' plugin is " + "installed and enabled.") + .arg(m_PluginNames[0]); } } -GameDependencyRequirement::GameDependencyRequirement(QStringList const& gameNames) : - m_GameNames(gameNames) { } +GameDependencyRequirement::GameDependencyRequirement(QStringList const& gameNames) + : m_GameNames(gameNames) +{} -std::optional GameDependencyRequirement::check(IOrganizer* o) const +std::optional +GameDependencyRequirement::check(IOrganizer* o) const { auto* game = o->managedGame(); if (!game) { @@ -56,17 +60,18 @@ std::optional GameDependencyRequirement::check(IOrg QString GameDependencyRequirement::message() const { - return QObject::tr( - "This plugin can only be enabled for the following game(s): %1.", "", - static_cast(m_GameNames.size())).arg(m_GameNames.join(", ")); + return QObject::tr("This plugin can only be enabled for the following game(s): %1.", + "", static_cast(m_GameNames.size())) + .arg(m_GameNames.join(", ")); } // Diagnose requirements -DiagnoseRequirement::DiagnoseRequirement(const IPluginDiagnose *diagnose) : - m_Diagnose(diagnose) { } +DiagnoseRequirement::DiagnoseRequirement(const IPluginDiagnose* diagnose) + : m_Diagnose(diagnose) +{} -std::optional DiagnoseRequirement::check(IOrganizer*) const +std::optional DiagnoseRequirement::check(IOrganizer*) const { auto activeProblems = m_Diagnose->activeProblems(); @@ -84,12 +89,16 @@ std::optional DiagnoseRequirement::check(IOrganize } // Basic requirements -class BasicPluginRequirement : public IPluginRequirement { +class BasicPluginRequirement : public IPluginRequirement +{ public: - BasicPluginRequirement(std::function const& checker, QString const description) : - m_Checker(checker), m_Description(description) { } + BasicPluginRequirement(std::function const& checker, + QString const description) + : m_Checker(checker), m_Description(description) + {} - std::optional check(IOrganizer* o) const { + std::optional check(IOrganizer* o) const + { if (m_Checker(o)) { return {}; } @@ -99,31 +108,31 @@ class BasicPluginRequirement : public IPluginRequirement { private: std::function m_Checker; QString m_Description; - }; // Factory -std::shared_ptr PluginRequirementFactory::pluginDependency( - QStringList const& pluginNames) +std::shared_ptr +PluginRequirementFactory::pluginDependency(QStringList const& pluginNames) { return std::make_shared(pluginNames); } -std::shared_ptr PluginRequirementFactory::gameDependency( - QStringList const& pluginGameNames) +std::shared_ptr +PluginRequirementFactory::gameDependency(QStringList const& pluginGameNames) { return std::make_shared(pluginGameNames); } -std::shared_ptr PluginRequirementFactory::diagnose( - const IPluginDiagnose* diagnose) +std::shared_ptr +PluginRequirementFactory::diagnose(const IPluginDiagnose* diagnose) { return std::make_shared(diagnose); } -std::shared_ptr PluginRequirementFactory::basic( - std::function const& checker, QString const description) +std::shared_ptr +PluginRequirementFactory::basic(std::function const& checker, + QString const description) { return std::make_shared(checker, description); } diff --git a/src/pluginrequirements.h b/src/pluginrequirements.h index 28557b5f..16432766 100644 --- a/src/pluginrequirements.h +++ b/src/pluginrequirements.h @@ -10,7 +10,8 @@ #include "dllimport.h" -namespace MOBase { +namespace MOBase +{ class IOrganizer; class IPluginDiagnose; @@ -18,12 +19,12 @@ class IPluginDiagnose; /** * @brief The interface for plugin requirements. */ -class IPluginRequirement { +class IPluginRequirement +{ public: - - class Problem { + class Problem + { public: - /** * @return a short description for the problem. */ @@ -37,17 +38,17 @@ class IPluginRequirement { /** * */ - Problem(QString shortDescription, QString longDescription = "") : - m_ShortDescription(shortDescription), - m_LongDescription(longDescription.isEmpty() ? shortDescription : longDescription) { } + Problem(QString shortDescription, QString longDescription = "") + : m_ShortDescription(shortDescription), + m_LongDescription(longDescription.isEmpty() ? shortDescription + : longDescription) + {} private: QString m_ShortDescription, m_LongDescription; - }; public: - /** * @brief Check if the requirements is met. * @@ -57,14 +58,15 @@ class IPluginRequirement { */ virtual std::optional check(IOrganizer* organizer) const = 0; - virtual ~IPluginRequirement() { } + virtual ~IPluginRequirement() {} }; /** * @brief Plugin dependency - The requirement is met if one of the * given plugin is active. */ -class PluginDependencyRequirement : public IPluginRequirement { +class PluginDependencyRequirement : public IPluginRequirement +{ friend class PluginRequirementFactory; @@ -87,7 +89,8 @@ class PluginDependencyRequirement : public IPluginRequirement { * @brief Game dependency - The requirement is met if the active game * is one of the specified game. */ -class GameDependencyRequirement : public IPluginRequirement { +class GameDependencyRequirement : public IPluginRequirement +{ friend class PluginRequirementFactory; @@ -114,7 +117,8 @@ class GameDependencyRequirement : public IPluginRequirement { * and the associated message is the one from the diagnose plugin (or the * list of messages if multiple problems were reported). */ -class DiagnoseRequirement : public IPluginRequirement { +class DiagnoseRequirement : public IPluginRequirement +{ friend class PluginRequirementFactory; @@ -127,13 +131,12 @@ class DiagnoseRequirement : public IPluginRequirement { const IPluginDiagnose* m_Diagnose; }; - /** * Factory for plugin requirements. */ -class QDLLEXPORT PluginRequirementFactory { +class QDLLEXPORT PluginRequirementFactory +{ public: - /** * @brief Create a new plugin dependency. The requirement is met if one of the * given plugin is enabled. @@ -142,9 +145,12 @@ class QDLLEXPORT PluginRequirementFactory { * * @param pluginNames Name of the plugin required. */ - static std::shared_ptr pluginDependency(QStringList const& pluginNames); - static std::shared_ptr pluginDependency(QString const& pluginName) { - return pluginDependency(QStringList{ pluginName }); + static std::shared_ptr + pluginDependency(QStringList const& pluginNames); + static std::shared_ptr + pluginDependency(QString const& pluginName) + { + return pluginDependency(QStringList{pluginName}); } /** @@ -155,9 +161,12 @@ class QDLLEXPORT PluginRequirementFactory { * * @note This differ from makePluginDependency only for the message. */ - static std::shared_ptr gameDependency(QStringList const& gameNames); - static std::shared_ptr gameDependency(QString const& gameName) { - return gameDependency(QStringList{ gameName }); + static std::shared_ptr + gameDependency(QStringList const& gameNames); + static std::shared_ptr + gameDependency(QString const& gameName) + { + return gameDependency(QStringList{gameName}); } /** @@ -165,7 +174,8 @@ class QDLLEXPORT PluginRequirementFactory { * * @param diagnose The diagnose plugin. */ - static std::shared_ptr diagnose(const IPluginDiagnose *diagnose); + static std::shared_ptr + diagnose(const IPluginDiagnose* diagnose); /** * @brief Create a generic requirement with the given checker and message. @@ -174,10 +184,10 @@ class QDLLEXPORT PluginRequirementFactory { * return true if the requirement is met). * @param description The description to show user if the requirement is not met. */ - static std::shared_ptr basic(std::function const& checker, QString const description); - + static std::shared_ptr + basic(std::function const& checker, QString const description); }; -} +} // namespace MOBase -#endif \ No newline at end of file +#endif diff --git a/src/pluginsetting.cpp b/src/pluginsetting.cpp index 31dc53df..cce84eb6 100644 --- a/src/pluginsetting.cpp +++ b/src/pluginsetting.cpp @@ -1,23 +1,24 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with Mod Organizer. If not, see . -*/ - -#include "pluginsetting.h" - -namespace MOBase { -} // namespace MOBase +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with Mod Organizer. If not, see . +*/ + +#include "pluginsetting.h" + +namespace MOBase +{ +} // namespace MOBase diff --git a/src/pluginsetting.h b/src/pluginsetting.h index 0852d7ef..6844f4d0 100644 --- a/src/pluginsetting.h +++ b/src/pluginsetting.h @@ -1,50 +1,50 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef PLUGINSETTING_H -#define PLUGINSETTING_H - - -#include -#include -#include - -namespace MOBase { - - -/** - * @brief struct to hold the user-configurable parameters a plugin accepts. The purpose of this - * struct is only to inform the application what settings to offer to the user, it does not hold the actual value - */ -struct PluginSetting -{ - PluginSetting(const QString &key, const QString &description, const QVariant &defaultValue) - : key(key), description(description), defaultValue(defaultValue) {} - - QString key; - QString description; - QVariant defaultValue; - -}; - -} // namespace MOBase - -#endif // PLUGINSETTING_H +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef PLUGINSETTING_H +#define PLUGINSETTING_H + +#include +#include +#include + +namespace MOBase +{ + +/** + * @brief struct to hold the user-configurable parameters a plugin accepts. The purpose + * of this struct is only to inform the application what settings to offer to the user, + * it does not hold the actual value + */ +struct PluginSetting +{ + PluginSetting(const QString& key, const QString& description, + const QVariant& defaultValue) + : key(key), description(description), defaultValue(defaultValue) + {} + + QString key; + QString description; + QVariant defaultValue; +}; + +} // namespace MOBase + +#endif // PLUGINSETTING_H diff --git a/src/questionboxmemory.cpp b/src/questionboxmemory.cpp index e02f6347..16f3436b 100644 --- a/src/questionboxmemory.cpp +++ b/src/questionboxmemory.cpp @@ -1,208 +1,200 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "questionboxmemory.h" -#include "ui_questionboxmemory.h" -#include "log.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace MOBase -{ - -static QMutex g_mutex; -static QuestionBoxMemory::GetButton g_get; -static QuestionBoxMemory::SetWindowButton g_setWindow; -static QuestionBoxMemory::SetFileButton g_setFile; - - -QuestionBoxMemory::QuestionBoxMemory( - QWidget *parent, const QString &title, const QString &text, QString const *filename, - const QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton) - : QDialog(parent) - , ui(new Ui::QuestionBoxMemory) - , m_Button(QDialogButtonBox::Cancel) -{ - ui->setupUi(this); - - setWindowFlag(Qt::WindowType::WindowContextHelpButtonHint, false); - setWindowTitle(title); - - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); - ui->iconLabel->setPixmap(icon.pixmap(128)); - ui->messageLabel->setText(text); - - if (filename == nullptr) { - //delete the 2nd check box - QCheckBox *box = ui->rememberForCheckBox; - box->parentWidget()->layout()->removeWidget(box); - delete box; - } else { - ui->rememberForCheckBox->setText( - ui->rememberForCheckBox->text().arg(*filename)); - } - - ui->buttonBox->setStandardButtons(buttons); - - if (defaultButton != QDialogButtonBox::NoButton) { - ui->buttonBox->button(defaultButton)->setDefault(true); - } - - connect( - ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), - this, SLOT(buttonClicked(QAbstractButton*))); -} - -QuestionBoxMemory::~QuestionBoxMemory() = default; - -void QuestionBoxMemory::setCallbacks( - GetButton get, SetWindowButton setWindow, SetFileButton setFile) -{ - QMutexLocker locker(&g_mutex); - - g_get = get; - g_setWindow = setWindow; - g_setFile = setFile; -} - -void QuestionBoxMemory::buttonClicked(QAbstractButton *button) -{ - m_Button = ui->buttonBox->standardButton(button); -} - -QDialogButtonBox::StandardButton QuestionBoxMemory::query( - QWidget *parent, const QString &windowName, - const QString &title, const QString &text, QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) -{ - return queryImpl(parent, windowName, nullptr, title, text, buttons, defaultButton); -} - -QDialogButtonBox::StandardButton QuestionBoxMemory::query( - QWidget *parent, const QString &windowName, const QString &fileName, - const QString &title, const QString &text, QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) -{ - return queryImpl(parent, windowName, &fileName, title, text, buttons, defaultButton); -} - -QDialogButtonBox::StandardButton QuestionBoxMemory::queryImpl( - QWidget *parent, const QString &windowName, const QString *fileName, - const QString &title, const QString &text, QDialogButtonBox::StandardButtons buttons, - QDialogButtonBox::StandardButton defaultButton) -{ - QMutexLocker locker(&g_mutex); - - const auto button = getMemory(windowName, (fileName ? *fileName : "")); - if (button != NoButton) { - log::debug( - "{}: not asking because user always wants response {}", - windowName + (fileName ? QString("/") + *fileName : ""), - buttonToString(button)); - - return button; - } - - QuestionBoxMemory dialog(parent, title, text, fileName, buttons, defaultButton); - dialog.exec(); - - if (dialog.m_Button != QDialogButtonBox::Cancel) { - if (dialog.ui->rememberCheckBox->isChecked()) { - setWindowMemory(windowName, dialog.m_Button); - } - - if (fileName != nullptr && dialog.ui->rememberForCheckBox->isChecked()) { - setFileMemory(windowName, *fileName, dialog.m_Button); - } - } - - return dialog.m_Button; -} - -void QuestionBoxMemory::setWindowMemory(const QString& windowName, Button b) -{ - log::debug( - "remembering choice {} for window {}", - buttonToString(b), windowName); - - g_setWindow(windowName, b); -} - -void QuestionBoxMemory::setFileMemory( - const QString& windowName, const QString& filename, Button b) -{ - log::debug( - "remembering choice {} for file {}", - buttonToString(b), windowName + "/" + filename); - - g_setFile(windowName, filename, b); -} - -QuestionBoxMemory::Button QuestionBoxMemory::getMemory( - const QString& windowName, const QString& filename) -{ - return g_get(windowName, filename); -} - -QString QuestionBoxMemory::buttonToString(Button b) -{ - using BB = QDialogButtonBox; - - static const std::map map = { - {BB::NoButton, "none"}, - {BB::Ok, "ok"}, - {BB::Save, "save"}, - {BB::SaveAll, "saveall"}, - {BB::Open, "open"}, - {BB::Yes, "yes"}, - {BB::YesToAll, "yestoall"}, - {BB::No, "no"}, - {BB::NoToAll, "notoall"}, - {BB::Abort, "abort"}, - {BB::Retry, "retry"}, - {BB::Ignore, "ignore"}, - {BB::Close, "close"}, - {BB::Cancel, "cancel"}, - {BB::Discard, "discard"}, - {BB::Help, "help"}, - {BB::Apply, "apply"}, - {BB::Reset, "reset"}, - {BB::RestoreDefaults, "restoredefaults"} - }; - - auto itor = map.find(b); - - if (itor == map.end()) { - return QString("0x%1") - .arg(static_cast(b), 0, 16); - } else { - return QString("'%1' (0x%2)") - .arg(itor->second) - .arg(static_cast(b), 0, 16); - } -} - -} // namespace +/* +Mod Organizer shared UI functionality + +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "questionboxmemory.h" +#include "log.h" +#include "ui_questionboxmemory.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace MOBase +{ + +static QMutex g_mutex; +static QuestionBoxMemory::GetButton g_get; +static QuestionBoxMemory::SetWindowButton g_setWindow; +static QuestionBoxMemory::SetFileButton g_setFile; + +QuestionBoxMemory::QuestionBoxMemory(QWidget* parent, const QString& title, + const QString& text, QString const* filename, + const QDialogButtonBox::StandardButtons buttons, + QDialogButtonBox::StandardButton defaultButton) + : QDialog(parent), ui(new Ui::QuestionBoxMemory), m_Button(QDialogButtonBox::Cancel) +{ + ui->setupUi(this); + + setWindowFlag(Qt::WindowType::WindowContextHelpButtonHint, false); + setWindowTitle(title); + + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); + ui->iconLabel->setPixmap(icon.pixmap(128)); + ui->messageLabel->setText(text); + + if (filename == nullptr) { + // delete the 2nd check box + QCheckBox* box = ui->rememberForCheckBox; + box->parentWidget()->layout()->removeWidget(box); + delete box; + } else { + ui->rememberForCheckBox->setText(ui->rememberForCheckBox->text().arg(*filename)); + } + + ui->buttonBox->setStandardButtons(buttons); + + if (defaultButton != QDialogButtonBox::NoButton) { + ui->buttonBox->button(defaultButton)->setDefault(true); + } + + connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, + SLOT(buttonClicked(QAbstractButton*))); +} + +QuestionBoxMemory::~QuestionBoxMemory() = default; + +void QuestionBoxMemory::setCallbacks(GetButton get, SetWindowButton setWindow, + SetFileButton setFile) +{ + QMutexLocker locker(&g_mutex); + + g_get = get; + g_setWindow = setWindow; + g_setFile = setFile; +} + +void QuestionBoxMemory::buttonClicked(QAbstractButton* button) +{ + m_Button = ui->buttonBox->standardButton(button); +} + +QDialogButtonBox::StandardButton +QuestionBoxMemory::query(QWidget* parent, const QString& windowName, + const QString& title, const QString& text, + QDialogButtonBox::StandardButtons buttons, + QDialogButtonBox::StandardButton defaultButton) +{ + return queryImpl(parent, windowName, nullptr, title, text, buttons, defaultButton); +} + +QDialogButtonBox::StandardButton +QuestionBoxMemory::query(QWidget* parent, const QString& windowName, + const QString& fileName, const QString& title, + const QString& text, QDialogButtonBox::StandardButtons buttons, + QDialogButtonBox::StandardButton defaultButton) +{ + return queryImpl(parent, windowName, &fileName, title, text, buttons, defaultButton); +} + +QDialogButtonBox::StandardButton +QuestionBoxMemory::queryImpl(QWidget* parent, const QString& windowName, + const QString* fileName, const QString& title, + const QString& text, + QDialogButtonBox::StandardButtons buttons, + QDialogButtonBox::StandardButton defaultButton) +{ + QMutexLocker locker(&g_mutex); + + const auto button = getMemory(windowName, (fileName ? *fileName : "")); + if (button != NoButton) { + log::debug("{}: not asking because user always wants response {}", + windowName + (fileName ? QString("/") + *fileName : ""), + buttonToString(button)); + + return button; + } + + QuestionBoxMemory dialog(parent, title, text, fileName, buttons, defaultButton); + dialog.exec(); + + if (dialog.m_Button != QDialogButtonBox::Cancel) { + if (dialog.ui->rememberCheckBox->isChecked()) { + setWindowMemory(windowName, dialog.m_Button); + } + + if (fileName != nullptr && dialog.ui->rememberForCheckBox->isChecked()) { + setFileMemory(windowName, *fileName, dialog.m_Button); + } + } + + return dialog.m_Button; +} + +void QuestionBoxMemory::setWindowMemory(const QString& windowName, Button b) +{ + log::debug("remembering choice {} for window {}", buttonToString(b), windowName); + + g_setWindow(windowName, b); +} + +void QuestionBoxMemory::setFileMemory(const QString& windowName, + const QString& filename, Button b) +{ + log::debug("remembering choice {} for file {}", buttonToString(b), + windowName + "/" + filename); + + g_setFile(windowName, filename, b); +} + +QuestionBoxMemory::Button QuestionBoxMemory::getMemory(const QString& windowName, + const QString& filename) +{ + return g_get(windowName, filename); +} + +QString QuestionBoxMemory::buttonToString(Button b) +{ + using BB = QDialogButtonBox; + + static const std::map map = { + {BB::NoButton, "none"}, + {BB::Ok, "ok"}, + {BB::Save, "save"}, + {BB::SaveAll, "saveall"}, + {BB::Open, "open"}, + {BB::Yes, "yes"}, + {BB::YesToAll, "yestoall"}, + {BB::No, "no"}, + {BB::NoToAll, "notoall"}, + {BB::Abort, "abort"}, + {BB::Retry, "retry"}, + {BB::Ignore, "ignore"}, + {BB::Close, "close"}, + {BB::Cancel, "cancel"}, + {BB::Discard, "discard"}, + {BB::Help, "help"}, + {BB::Apply, "apply"}, + {BB::Reset, "reset"}, + {BB::RestoreDefaults, "restoredefaults"}}; + + auto itor = map.find(b); + + if (itor == map.end()) { + return QString("0x%1").arg(static_cast(b), 0, 16); + } else { + return QString("'%1' (0x%2)").arg(itor->second).arg(static_cast(b), 0, 16); + } +} + +} // namespace MOBase diff --git a/src/questionboxmemory.h b/src/questionboxmemory.h index 7298b714..c5224eab 100644 --- a/src/questionboxmemory.h +++ b/src/questionboxmemory.h @@ -1,107 +1,112 @@ -/* -Mod Organizer shared UI functionality - -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef QUESTIONBOXMEMORY_H -#define QUESTIONBOXMEMORY_H - -#include "dllimport.h" - -#include -#include -#include -#include -#include - -class QAbstractButton; -class QMutex; -class QSettings; -class QWidget; - -namespace Ui { class QuestionBoxMemory; } - -namespace MOBase -{ - -class QDLLEXPORT QuestionBoxMemory : public QDialog -{ - Q_OBJECT - -public: - using Button = QDialogButtonBox::StandardButton; - static const auto NoButton = QDialogButtonBox::NoButton; - - using GetButton = std::function