master de8784c90c9c cached
77 files
725.1 KB
217.8k tokens
293 symbols
1 requests
Download .txt
Showing preview only (759K chars total). Download the full file or copy to clipboard to get everything.
Repository: KoenZomers/KeePassOneDriveSync
Branch: master
Commit: de8784c90c9c
Files: 77
Total size: 725.1 KB

Directory structure:
gitextract_t4ju8rln/

├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── feature_request.md
│   │   └── question.md
│   ├── PULL_REQUEST_TEMPLATE/
│   │   └── PULL_REQUEST_TEMPLATE.md
│   └── auto_assign.yml
├── .gitignore
├── KeeOneDriveSync.plgx
├── KoenZomers.KeePass.OneDriveSync/
│   ├── Configuration.cs
│   ├── Enums/
│   │   ├── CloudStorageType.cs
│   │   └── OneDriveRefreshTokenStorage.cs
│   ├── Forms/
│   │   ├── AboutForm.Designer.cs
│   │   ├── AboutForm.cs
│   │   ├── AboutForm.resx
│   │   ├── OneDriveAboutForm.Designer.cs
│   │   ├── OneDriveAboutForm.cs
│   │   ├── OneDriveAboutForm.resx
│   │   ├── OneDriveAskToStartSyncingDialog.Designer.cs
│   │   ├── OneDriveAskToStartSyncingDialog.cs
│   │   ├── OneDriveAskToStartSyncingDialog.resx
│   │   ├── OneDriveAuthenticateForm.Designer.cs
│   │   ├── OneDriveAuthenticateForm.cs
│   │   ├── OneDriveAuthenticateForm.resx
│   │   ├── OneDriveCloudTypeForm.Designer.cs
│   │   ├── OneDriveCloudTypeForm.cs
│   │   ├── OneDriveCloudTypeForm.resx
│   │   ├── OneDriveConfigDetailsForm.Designer.cs
│   │   ├── OneDriveConfigDetailsForm.cs
│   │   ├── OneDriveConfigDetailsForm.resx
│   │   ├── OneDriveConfigForm.Designer.cs
│   │   ├── OneDriveConfigForm.cs
│   │   ├── OneDriveConfigForm.resx
│   │   ├── OneDriveFilePickerDialog.Designer.cs
│   │   ├── OneDriveFilePickerDialog.cs
│   │   ├── OneDriveFilePickerDialog.resx
│   │   ├── OneDriveGraphDeviceLoginForm.Designer.cs
│   │   ├── OneDriveGraphDeviceLoginForm.cs
│   │   ├── OneDriveGraphDeviceLoginForm.resx
│   │   ├── OneDriveGraphDeviceLoginForm1.Designer.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.Designer.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.resx
│   │   ├── OneDriveRemoteLocationDialog.resx
│   │   ├── OneDriveRequestInputDialog.Designer.cs
│   │   ├── OneDriveRequestInputDialog.cs
│   │   ├── OneDriveRequestInputDialog.resx
│   │   ├── SharePointCredentialsForm.Designer.cs
│   │   ├── SharePointCredentialsForm.cs
│   │   ├── SharePointCredentialsForm.resx
│   │   ├── SharePointDocumentLibraryPickerDialog.Designer.cs
│   │   ├── SharePointDocumentLibraryPickerDialog.cs
│   │   └── SharePointDocumentLibraryPickerDialog.resx
│   ├── KeePass.exe.config
│   ├── KeePassDatabase.cs
│   ├── KoenZomers.KeePass.OneDriveSync.csproj
│   ├── KoenZomersKeePassOneDriveSyncExt.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── Providers/
│   │   ├── MicrosoftGraph/
│   │   │   ├── MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs
│   │   │   ├── MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs
│   │   │   └── MicrosoftGraphDeviceCodeResponse.cs
│   │   ├── OneDriveProvider.cs
│   │   └── SharePointProvider.cs
│   ├── Resources/
│   │   ├── MSGraph.pdn
│   │   └── SharePoint.pdn
│   ├── Resources.Designer.cs
│   ├── Resources.resx
│   ├── TokenHelper.cs
│   ├── Utilities.cs
│   ├── app.config
│   └── packages.config
├── KoenZomers.KeePass.OneDriveSync.sln
├── LICENSE.md
├── NuGet.config
├── README.md
├── create-plgx.cmd
└── version.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs     diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following 
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.csproj    merge=binary
#*.vbproj    merge=binary
#*.vcxproj   merge=binary
#*.vcproj    merge=binary
#*.dbproj    merge=binary
#*.fsproj    merge=binary
#*.lsproj    merge=binary
#*.wixproj   merge=binary
#*.modelproj merge=binary
#*.sqlproj   merge=binary
#*.wwaproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
# 
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the 
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: If you believe something is not working well
title: "[BUG] Brief description"
labels: need to test
assignees: KoenZomers

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Versions (please complete the following information):**
- KeePass [e.g. 2.45]:
- KeePass OneDriveSync Plugin [e.g. 2.1.1.2]:

**Authentication method**
- [ ] Microsoft Graph (any browser)
- [ ] Microsoft Graph (built in browser)
- [ ] OneDrive
- [ ] OneDrive for Business
- [ ] SharePoint 2013/2016/2019

**KeePass database synced with**
- [ ] OneDrive for Business
- [ ] OneDrive Personal


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Author
    url: koen@zomers.eu
    about: If you want to share feedback which you rather don't want to be public, share it via e-mail


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for the plugin
title: "[FEATURE REQUEST] Brief description"
labels: need to test
assignees: KoenZomers

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: If you have a question regarding this project
title: "[QUESTION] Brief description"
labels: need to test
assignees: KoenZomers

---

**Describe your question**
A clear and concise description of what your question is about.

**Screenshots**
If applicable, add screenshots to help explain your question.

**Versions (please complete the following information):**
- KeePass [e.g. 2.45]:
- KeePass OneDriveSync Plugin [e.g. 2.1.1.2]:

**Authentication method**
- [ ] Microsoft Graph (any browser)
- [ ] Microsoft Graph (built in browser)
- [ ] OneDrive
- [ ] OneDrive for Business
- [ ] SharePoint 2013/2016/2019

**KeePass database synced with**
- [ ] OneDrive for Business
- [ ] OneDrive Personal


================================================
FILE: .github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md
================================================
## Type ##
- [ ] Bug Fix
- [ ] New Feature
- [ ] Sample

## Related Issues? ##
Fixes #X, partially fixes #Y, mentioned in #Z, etc.

## What is in this Pull Request ? ##
Please describe the changes you are proposing through this PR


================================================
FILE: .github/auto_assign.yml
================================================
# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: false

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
  - koenzomers

# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 0

# A list of assignees, overrides reviewers if set
# assignees:
#   - assigneeA

# A number of assignees to add to the pull request
# Set to 0 to add all of the assignees.
# Uses numberOfReviewers if unset.
# numberOfAssignees: 2

# A list of keywords to be skipped the process that add reviewers if pull requests include it
# skipKeywords:
#   - wip


================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Bb]in/
[Oo]bj/

# Roslyn cache directories
*.ide/

# Visual Studio 2015/2017 cache/options directory
.vs/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

#NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding addin-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
## TODO: Comment the next line if you want to checkin your
## web deploy settings but do note that will include unencrypted
## passwords
#*.pubxml

# NuGet Packages Directory
packages/*
## TODO: If the tool you use requires repositories.config
## uncomment the next line
#!packages/repositories.config

# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/

# Windows Azure Build Output
csx/
*.build.csdef

# Windows Store app package directory
AppPackages/

KoenZomers.KeePass.OneDriveSync/Packages/

# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
/.vs/config
/.vs/KoenZomers.KeePass.OneDriveSync/v15/Server/sqlite3
/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/db.lock
/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/storage.ide-wal
/.vs/KoenZomers.KeePass.OneDriveSync/v15/sqlite3/storage.ide-shm


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Configuration.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Windows.Forms;
using KoenZomersKeePassOneDriveSync;
using Newtonsoft.Json;

namespace KoenZomers.KeePass.OneDriveSync
{
    /// <summary>
    /// Plugin configuration class. Contains functions to serialize/deserialize to/from JSON.
    /// </summary>
    [DataContract]
    public class Configuration : ICloneable
    {
        #region Constants

        /// <summary>
        /// Name under which to store these settings in the KeePass configuration store
        /// </summary>
        private const string ConfigurationKey = "KeeOneDrive";

        #endregion

        #region Non serializable Properties

        /// <summary>
        /// Dictionary with configuration settings for all password databases. Key is the local database path, value is the configuration belonging to it.
        /// </summary>
        private static IDictionary<string, Configuration> PasswordDatabases = new Dictionary<string, Configuration>();

        /// <summary>
        /// Boolean indicating if the syncing of this database is allowed
        /// </summary>
        public bool SyncingEnabled = true;

        /// <summary>
        /// The KeePass database to which these settings belong
        /// </summary>
        public KeePassLib.PwDatabase KeePassDatabase { get; set; }

        /// <summary>
        /// Boolean indicating if this database is currently synchronizing
        /// </summary>
        public bool IsCurrentlySyncing { get; set; }

        #endregion

        #region Serializable Properties

        /// <summary>
        /// Gets or sets refresh token that can be used to get an Access Token for OneDrive access. Will be set to ClientId;ClientSecret in the case of a SharePoint configuration.
        /// </summary>
        [DataMember]
        public string RefreshToken { get; set; }

        /// <summary>
        /// Gets or sets the location where the refresh token will be stored
        /// </summary>
        [DataMember]
        public Enums.OneDriveRefreshTokenStorage? RefreshTokenStorage { get; set; } 

        /// <summary>
        /// Gets or sets the name of the OneDrive the KeePass database is synchronized with. Will be set to the SharePoint site title in the scenario of a SharePoint configuration.
        /// </summary>
        [DataMember]
        public string OneDriveName { get; set; }

        /// <summary>
        /// Gets or sets database file path on OneDrive relative to the user. Will be set to the site URL in the case of a SharePoint configuration.
        /// </summary>
        [DataMember]
        public string RemoteDatabasePath { get; set; }

        /// <summary>
        /// Gets or sets the unique identifier of the folder on OneDrive in which the file is stored. Will be set to the Document Library server relative URL in the case of a SharePoint configuration.
        /// </summary>
        [DataMember]
        public string RemoteFolderId { get; set; }

        /// <summary>
        /// Gets or sets the unique identifier of the drive on OneDrive in which the file is stored. If NULL then the drive of the current user will be used.
        /// </summary>
        [DataMember]
        public string RemoteDriveId { get; set; }

        /// <summary>
        /// Gets or sets the unique identifier of the file on OneDrive
        /// </summary>
        [DataMember]
        public string RemoteItemId { get; set; }

        /// <summary>
        /// Gets or sets the filename under which the database is stored on OneDrive
        /// </summary>
        [DataMember]
        public string RemoteFileName { get; set; }

        /// <summary>
        /// Gets or sets a boolean to indicate if the database should be synced with OneDrive
        /// </summary>
        [DataMember]
        public bool DoNotSync { get; set; }

        /// <summary>
        /// The SHA1 hash of the local KeePass database
        /// </summary>
        [DataMember]
        public string LocalFileHash { get; set; }

        /// <summary>
        /// The ETag of the KeePass database on OneDrive
        /// </summary>
        [DataMember]
        public string ETag { get; set; }

        /// <summary>
        /// Date and time at which the database last synced with OneDrive
        /// </summary>
        [DataMember]
        public DateTime? LastSyncedAt { get; set; }

        /// <summary>
        /// Date and time at which the database has last been compared with its equivallent on OneDrive
        /// </summary>
        [DataMember]
        public DateTime? LastCheckedAt { get; set; }

        /// <summary>
        /// Type of cloud storage used for storing the database
        /// </summary>
        [DataMember]
        public Enums.CloudStorageType? CloudStorageType { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Gets the KeePass database configuration for KeePassOneDriveSync for the KeePass database of which the local path is provided
        /// </summary>
        /// <param name="localPasswordDatabasePath">Full path to where the KeePass database resides locally</param>
        /// <returns>KeePassOneDriveSync settings for the provided database. If no configuration exists yet for the database, it will provide a new empty configuration set.</returns>
        public static Configuration GetPasswordDatabaseConfiguration(string localPasswordDatabasePath)
        {
            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);

            if (!PasswordDatabases.ContainsKey(localPasswordDatabasePath))
            {
                PasswordDatabases.Add(new KeyValuePair<string, Configuration>(localPasswordDatabasePath, new Configuration()));
            }
            return PasswordDatabases[localPasswordDatabasePath];
        }

        /// <summary>
        /// Sets the KeePass database configuration for KeePassOneDriveSync for the KeePass database of which the local path is provided to the configuration that is provided
        /// </summary>
        /// <param name="localPasswordDatabasePath">Full path to where the KeePass database resides locally</param>
        /// <param name="configuration">Configuration that should be set for the KeePass database. If configuration already existed for the same database, it will be overwritten. If it didn't exist yet, it will be added.</param>
        public static void SetPasswordDatabaseConfiguration(string localPasswordDatabasePath, Configuration configuration)
        {
            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);
            PasswordDatabases[localPasswordDatabasePath] = configuration;
        }

        /// <summary>
        /// Loads the configuration stored in KeePass
        /// </summary>
        public static void Load()
        {
            // Retrieve the stored configuration from KeePass
            var value = KoenZomersKeePassOneDriveSyncExt.Host.CustomConfig.GetString(ConfigurationKey, null);

            if (string.IsNullOrEmpty(value))
            {
                return;
            }

            try
            {
                // Convert the retrieved JSON to a typed entity
                PasswordDatabases = JsonConvert.DeserializeObject<Dictionary<string, Configuration>>(value);
            }
            catch (JsonSerializationException)
            {                
                MessageBox.Show("Unable to parse the plugin configuration for the KeePass OneDriveSync plugin. If this happens again, please let me know. Sorry for the inconvinience. Koen Zomers <koen@zomers.eu>", "KeePass OneDriveSync Plugin", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

                // Reset the configuration so at least it works again next time, all be it that all configuration will be lost
                PasswordDatabases = new Dictionary<string, Configuration>();
                Save();
            }

            // Get all database configurations which have their OneDrive Refresh Token stored in the Windows Credential Manager and retrieve them
            var windowsCredentialManagerDatabaseConfigs = PasswordDatabases.Where(pwdDb => pwdDb.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager);
            foreach (var windowsCredentialManagerDatabaseConfig in windowsCredentialManagerDatabaseConfigs)
            {
                windowsCredentialManagerDatabaseConfig.Value.RefreshToken = Utilities.GetRefreshTokenFromWindowsCredentialManager(windowsCredentialManagerDatabaseConfig.Key);
            }

            // Decrypt all database configurations which have their OneDrive Refresh Token stored encrypted in the config file
            var encryptedDatabaseConfigs = PasswordDatabases.Where(pwdDb => pwdDb.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.DiskEncrypted);
            foreach (var encryptedDatabaseConfig in encryptedDatabaseConfigs)
            {
                encryptedDatabaseConfig.Value.RefreshToken = string.IsNullOrWhiteSpace(encryptedDatabaseConfig.Value.RefreshToken) ? null : Utilities.Unprotect(encryptedDatabaseConfig.Value.RefreshToken);
            }
        }

        /// <summary>
        /// Saves the current configuration
        /// </summary>
        public static void Save()
        {
            // Create a new dictionary with the information to store in KeePass.config.xml
            var passwordDatabasesForStoring = new Dictionary<string, Configuration>();

            // Loop through the entries to store
            foreach (var passwordDatabase in PasswordDatabases)
            {
                switch (passwordDatabase.Value.RefreshTokenStorage)
                {
                    case Enums.OneDriveRefreshTokenStorage.Disk:
                    case Enums.OneDriveRefreshTokenStorage.DiskEncrypted:
                        // Enforce encryption of tokens previously stored in plain text
                        passwordDatabase.Value.RefreshTokenStorage = Enums.OneDriveRefreshTokenStorage.DiskEncrypted;

                        // Refresh token will be stored encrypted on disk, we create a copy of the configuration and encrypt the refresh token
                        var diskConfiguration = (Configuration)passwordDatabase.Value.Clone();
                        diskConfiguration.RefreshToken = string.IsNullOrWhiteSpace(diskConfiguration.RefreshToken) ? null : Utilities.Protect(diskConfiguration.RefreshToken);
                        passwordDatabasesForStoring.Add(passwordDatabase.Key, diskConfiguration);
                        break;

                    case Enums.OneDriveRefreshTokenStorage.KeePassDatabase:
                    case Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager:
                        // Refresh token will not be stored on disk, we create a copy of the configuration and remove the refresh token from it so it will not be stored on disk
                        var tempConfiguration = (Configuration) passwordDatabase.Value.Clone();
                        tempConfiguration.RefreshToken = null;
                        passwordDatabasesForStoring.Add(passwordDatabase.Key, tempConfiguration);

                        if (passwordDatabase.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.KeePassDatabase && passwordDatabase.Value.KeePassDatabase != null && !string.IsNullOrEmpty(passwordDatabase.Value.RefreshToken))
                        {
                            Utilities.SaveRefreshTokenInKeePassDatabase(passwordDatabase.Value.KeePassDatabase, passwordDatabase.Value.RefreshToken);
                        }
                        if (passwordDatabase.Value.RefreshTokenStorage == Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager)
                        {
                            Utilities.SaveRefreshTokenInWindowsCredentialManager(passwordDatabase.Key, passwordDatabase.Value.RefreshToken);
                        }
                        break;
                    default:
                        // Hit when user selected the do not sync database option. In that case just store the config on disk as it doesn't contain any tokens.
                        passwordDatabasesForStoring.Add(passwordDatabase.Key, passwordDatabase.Value);
                        break;
                }
            }

            // Serialize the configuration to JSON
            var json = JsonConvert.SerializeObject(passwordDatabasesForStoring);

            // Store the configuration in KeePass.config.xml
            KoenZomersKeePassOneDriveSyncExt.Host.CustomConfig.SetString(ConfigurationKey, json);
        }

        /// <summary>
        /// Returns a copy of the current instance
        /// </summary>
        public object Clone()
        {
            return MemberwiseClone();
        }

        /// <summary>
        /// Deletes the complete configuration of the KeePass database on the provided local path
        /// </summary>
        /// <param name="localPasswordDatabasePath">Full local path to a KeePass database of which to delete the configuration</param>
        public static void DeleteConfig(string localPasswordDatabasePath)
        {
            localPasswordDatabasePath = NormalizePath(localPasswordDatabasePath);

            // Verify if we have configuration available of a KeePass database stored on the provided full local path
            if (!PasswordDatabases.ContainsKey(localPasswordDatabasePath)) return;
            
            // Retrieve the configuration we have available about the KeePass database
            var config = PasswordDatabases[localPasswordDatabasePath];
            
            // Take cleanup actions based on where the OneDrive Refresh Token is stored
            switch (config.RefreshTokenStorage)
            {
                case Enums.OneDriveRefreshTokenStorage.Disk:
                case Enums.OneDriveRefreshTokenStorage.DiskEncrypted:
                    // No action required as it will be removed as part of removing the complete configuration
                    break;

                case Enums.OneDriveRefreshTokenStorage.KeePassDatabase:
                    // There's no way to remove it from the KeePass database without having the database open, so we'll have to leave it there
                    break;

                case Enums.OneDriveRefreshTokenStorage.WindowsCredentialManager:
                    Utilities.DeleteRefreshTokenFromWindowsCredentialManager(localPasswordDatabasePath);
                    break;
            }

            // Remove the configuration we have available
            PasswordDatabases.Remove(localPasswordDatabasePath);

            // Initiate a save to write the results
            Save();
        }

        /// <summary>
        /// Get the full PasswordDatabases object list, used by the configuration form
        /// </summary>
        /// <returns></returns>
        internal static IDictionary<string, Configuration> GetAllConfigurations()
        {
            return PasswordDatabases;
        }

        /// <summary>
        /// Boolean to indicate if some process is still running that we need to wait for before we shut down KeePass
        /// </summary>
        internal static bool IsSomethingStillRunning
        {
            get
            {
                return PasswordDatabases.Any(db => db.Value.IsCurrentlySyncing);
            }
        }

        /// <summary>
        /// Normalize database path - if located under the KeePass folder (portable install) then use a relative path, otherwise use the original (absolute)
        /// </summary>
        /// <param name="localPasswordDatabasePath">Full path to a KeePass database</param>
        /// <returns>If the path resides under the folder where KeePass runs from, it will return a relative path, otherwise the full path will be returned</returns>
        private static string NormalizePath(string localPasswordDatabasePath)
        {
            if (localPasswordDatabasePath.StartsWith(AppDomain.CurrentDomain.BaseDirectory))
            {
                localPasswordDatabasePath = localPasswordDatabasePath.Remove(0, AppDomain.CurrentDomain.BaseDirectory.Length);
            }

            return localPasswordDatabasePath;
        }

        #endregion
    }
}



================================================
FILE: KoenZomers.KeePass.OneDriveSync/Enums/CloudStorageType.cs
================================================
namespace KoenZomers.KeePass.OneDriveSync.Enums
{
    /// <summary>
    /// Defines the types of cloud storage that can be used
    /// </summary>
    public enum CloudStorageType : short
    {
        /// <summary>
        /// Consumer OneDrive
        /// </summary>
        OneDriveConsumer = 0,

        /// <summary>
        /// Microsoft Graph API
        /// </summary>
        MicrosoftGraph = 2,

        /// <summary>
        /// Microsoft SharePoint
        /// </summary>
        SharePoint = 3,

        /// <summary>
        /// Microsoft Graph API Device Login
        /// </summary>
        MicrosoftGraphDeviceLogin = 4,

        /// <summary>
        /// Do not sync
        /// </summary>
        None = 99
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Enums/OneDriveRefreshTokenStorage.cs
================================================
namespace KoenZomers.KeePass.OneDriveSync.Enums
{
    /// <summary>
    /// Defines the possible storage locations for the OneDrive Refresh Token
    /// </summary>
    public enum OneDriveRefreshTokenStorage : short
    {
        /// <summary>
        /// Saves the RefreshToken plain text in KeePass.config.xml located in %APPDATA%\KeePass 
        /// </summary>
        Disk = 0,

        /// <summary>
        /// Saves the RefreshToken encrypted in the Windows Credential Manager
        /// </summary>
        WindowsCredentialManager = 1,

        /// <summary>
        /// Saves the RefreshToken in the encrypted KeePass database
        /// </summary>
        KeePassDatabase = 2,

        /// <summary>
        /// Saves the RefreshToken encrypted with DPAPI in KeePass.config.xml located in %APPDATA%\KeePass 
        /// </summary>
        DiskEncrypted = 3,
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class AboutForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.NameLabel = new System.Windows.Forms.Label();
            this.CloseButton = new System.Windows.Forms.Button();
            this.HeaderLabel = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // ExplanationLabel
            // 
            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ExplanationLabel.Location = new System.Drawing.Point(23, 73);
            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
            this.ExplanationLabel.Name = "ExplanationLabel";
            this.ExplanationLabel.Size = new System.Drawing.Size(608, 72);
            this.ExplanationLabel.TabIndex = 11;
            this.ExplanationLabel.Text = "This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.";
            // 
            // NameLabel
            // 
            this.NameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.NameLabel.Location = new System.Drawing.Point(23, 158);
            this.NameLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
            this.NameLabel.Name = "NameLabel";
            this.NameLabel.Size = new System.Drawing.Size(608, 27);
            this.NameLabel.TabIndex = 10;
            this.NameLabel.Text = "Koen Zomers <mail@koenzomers.nl>";
            this.NameLabel.UseMnemonic = false;
            // 
            // CloseButton
            // 
            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.CloseButton.Location = new System.Drawing.Point(455, 190);
            this.CloseButton.Margin = new System.Windows.Forms.Padding(5);
            this.CloseButton.Name = "CloseButton";
            this.CloseButton.Size = new System.Drawing.Size(176, 50);
            this.CloseButton.TabIndex = 9;
            this.CloseButton.Text = "&Close";
            this.CloseButton.UseVisualStyleBackColor = true;
            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // HeaderLabel
            // 
            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.HeaderLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.HeaderLabel.Location = new System.Drawing.Point(21, 16);
            this.HeaderLabel.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0);
            this.HeaderLabel.Name = "HeaderLabel";
            this.HeaderLabel.Size = new System.Drawing.Size(610, 34);
            this.HeaderLabel.TabIndex = 8;
            this.HeaderLabel.Text = "KeePass OneDriveSync";
            this.HeaderLabel.UseMnemonic = false;
            // 
            // AboutForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(645, 254);
            this.Controls.Add(this.ExplanationLabel);
            this.Controls.Add(this.NameLabel);
            this.Controls.Add(this.CloseButton);
            this.Controls.Add(this.HeaderLabel);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(410, 280);
            this.Name = "AboutForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "About KeePass OneDriveSync";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Label ExplanationLabel;
        private System.Windows.Forms.Label NameLabel;
        private System.Windows.Forms.Button CloseButton;
        private System.Windows.Forms.Label HeaderLabel;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.cs
================================================
using System.Reflection;
using System.Windows.Forms;

namespace KoenZomersKeePassOneDriveSync
{
    public partial class AboutForm : Form
    {
        public AboutForm()
        {
            InitializeComponent();

            var assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;

            HeaderLabel.Text = string.Format("KeePass OneDriveSync v{0}.{1}.{2}", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build);
        }

        private void CloseButton_Click(object sender, System.EventArgs e)
        {
            Close();
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class OneDriveAboutForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.HeaderLabel = new System.Windows.Forms.Label();
            this.CloseButton = new System.Windows.Forms.Button();
            this.NameLabel = new System.Windows.Forms.Label();
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.WebsiteLinkLabel = new System.Windows.Forms.LinkLabel();
            this.SuspendLayout();
            // 
            // HeaderLabel
            // 
            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.HeaderLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.HeaderLabel.Location = new System.Drawing.Point(18, 14);
            this.HeaderLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.HeaderLabel.Name = "HeaderLabel";
            this.HeaderLabel.Size = new System.Drawing.Size(561, 35);
            this.HeaderLabel.TabIndex = 2;
            this.HeaderLabel.Text = "KeePass OneDriveSync";
            this.HeaderLabel.UseMnemonic = false;
            // 
            // CloseButton
            // 
            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.CloseButton.Location = new System.Drawing.Point(431, 194);
            this.CloseButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
            this.CloseButton.Name = "CloseButton";
            this.CloseButton.Size = new System.Drawing.Size(148, 51);
            this.CloseButton.TabIndex = 5;
            this.CloseButton.Text = "&Close";
            this.CloseButton.UseVisualStyleBackColor = true;
            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // NameLabel
            // 
            this.NameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.NameLabel.Location = new System.Drawing.Point(20, 194);
            this.NameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.NameLabel.Name = "NameLabel";
            this.NameLabel.Size = new System.Drawing.Size(405, 28);
            this.NameLabel.TabIndex = 6;
            this.NameLabel.Text = "Koen Zomers (koen@zomers.eu)";
            this.NameLabel.UseMnemonic = false;
            // 
            // ExplanationLabel
            // 
            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ExplanationLabel.Location = new System.Drawing.Point(19, 71);
            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.ExplanationLabel.MinimumSize = new System.Drawing.Size(558, 118);
            this.ExplanationLabel.Name = "ExplanationLabel";
            this.ExplanationLabel.Size = new System.Drawing.Size(558, 118);
            this.ExplanationLabel.TabIndex = 7;
            this.ExplanationLabel.Text = "This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.";
            // 
            // WebsiteLinkLabel
            // 
            this.WebsiteLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.WebsiteLinkLabel.AutoSize = true;
            this.WebsiteLinkLabel.Location = new System.Drawing.Point(19, 222);
            this.WebsiteLinkLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.WebsiteLinkLabel.Name = "WebsiteLinkLabel";
            this.WebsiteLinkLabel.Size = new System.Drawing.Size(398, 20);
            this.WebsiteLinkLabel.TabIndex = 9;
            this.WebsiteLinkLabel.TabStop = true;
            this.WebsiteLinkLabel.Text = "https://github.com/KoenZomers/KeePassOneDriveSync";
            this.WebsiteLinkLabel.Click += new System.EventHandler(this.WebsiteLinkLabel_Click);
            // 
            // OneDriveAboutForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(597, 262);
            this.Controls.Add(this.CloseButton);
            this.Controls.Add(this.WebsiteLinkLabel);
            this.Controls.Add(this.ExplanationLabel);
            this.Controls.Add(this.NameLabel);
            this.Controls.Add(this.HeaderLabel);
            this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(619, 250);
            this.Name = "OneDriveAboutForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "About KeePass OneDriveSync";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label HeaderLabel;
        private System.Windows.Forms.Button CloseButton;
        private System.Windows.Forms.Label NameLabel;
        private System.Windows.Forms.Label ExplanationLabel;
        private System.Windows.Forms.LinkLabel WebsiteLinkLabel;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.cs
================================================
using System;
using System.Reflection;
using System.Windows.Forms;

namespace KoenZomersKeePassOneDriveSync
{
    /// <summary>
    /// About Form
    /// </summary>
    public partial class OneDriveAboutForm : Form
    {
        public OneDriveAboutForm()
        {
            InitializeComponent();

            var assemblyVersion = Assembly.GetCallingAssembly().GetName().Version;

            HeaderLabel.Text = string.Format("KeePass OneDriveSync v{0}.{1}.{2}.{3}", assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build, assemblyVersion.Revision);
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {

        }

        private void WebsiteLinkLabel_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(WebsiteLinkLabel.Text);
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="ExplanationLabel.Text" xml:space="preserve">
    <value>This KeePass plugin allows synchronizing your KeePass databases with one or multiple OneDrive accounts. It is inspired by KeeSkyDrive by Oleksandr Senyuk. It is free to use and open source. Please leave these credits in place if you decide to use my source code. Feel free to contact me in case of questions or suggestions.</value>
  </data>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
 {
     partial class OneDriveAskToStartSyncingDialog
     {
         /// <summary>
         /// Required designer variable.
         /// </summary>
         private System.ComponentModel.IContainer components = null;

         /// <summary>
         /// Clean up any resources being used.
         /// </summary>
         /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
         protected override void Dispose(bool disposing)
         {
             if (disposing && (components != null))
             {
                 components.Dispose();
             }
             base.Dispose(disposing);
         }

         #region Windows Form Designer generated code

         /// <summary>
         /// Required method for Designer support - do not modify
         /// the contents of this method with the code editor.
         /// </summary>
         private void InitializeComponent()
         {
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.YesRadio = new System.Windows.Forms.RadioButton();
            this.NotNowRadio = new System.Windows.Forms.RadioButton();
            this.NoNeverAskAgainRadio = new System.Windows.Forms.RadioButton();
            this.OKButton = new System.Windows.Forms.Button();
            this.CancelButton = new System.Windows.Forms.Button();
            this.OneDriveDatabasePath = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // ExplanationLabel
            // 
            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ExplanationLabel.Location = new System.Drawing.Point(9, 7);
            this.ExplanationLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
            this.ExplanationLabel.Name = "ExplanationLabel";
            this.ExplanationLabel.Size = new System.Drawing.Size(375, 35);
            this.ExplanationLabel.TabIndex = 0;
            this.ExplanationLabel.Text = "The following KeePass database is not being synced with OneDrive. Would you like " +
    "to set up a synchronization connection now?";
            // 
            // YesRadio
            // 
            this.YesRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.YesRadio.AutoSize = true;
            this.YesRadio.Checked = true;
            this.YesRadio.Location = new System.Drawing.Point(11, 75);
            this.YesRadio.Margin = new System.Windows.Forms.Padding(2);
            this.YesRadio.Name = "YesRadio";
            this.YesRadio.Size = new System.Drawing.Size(43, 17);
            this.YesRadio.TabIndex = 1;
            this.YesRadio.TabStop = true;
            this.YesRadio.Text = "Yes";
            this.YesRadio.UseVisualStyleBackColor = true;
            // 
            // NotNowRadio
            // 
            this.NotNowRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.NotNowRadio.AutoSize = true;
            this.NotNowRadio.Location = new System.Drawing.Point(11, 97);
            this.NotNowRadio.Margin = new System.Windows.Forms.Padding(2);
            this.NotNowRadio.Name = "NotNowRadio";
            this.NotNowRadio.Size = new System.Drawing.Size(65, 17);
            this.NotNowRadio.TabIndex = 2;
            this.NotNowRadio.Text = "Not now";
            this.NotNowRadio.UseVisualStyleBackColor = true;
            // 
            // NoNeverAskAgainRadio
            // 
            this.NoNeverAskAgainRadio.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.NoNeverAskAgainRadio.AutoSize = true;
            this.NoNeverAskAgainRadio.Location = new System.Drawing.Point(11, 118);
            this.NoNeverAskAgainRadio.Margin = new System.Windows.Forms.Padding(2);
            this.NoNeverAskAgainRadio.Name = "NoNeverAskAgainRadio";
            this.NoNeverAskAgainRadio.Size = new System.Drawing.Size(220, 17);
            this.NoNeverAskAgainRadio.TabIndex = 3;
            this.NoNeverAskAgainRadio.Text = "No and never ask again for this database";
            this.NoNeverAskAgainRadio.UseVisualStyleBackColor = true;
            // 
            // OKButton
            // 
            this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.OKButton.Location = new System.Drawing.Point(127, 154);
            this.OKButton.Margin = new System.Windows.Forms.Padding(2);
            this.OKButton.Name = "OKButton";
            this.OKButton.Size = new System.Drawing.Size(74, 41);
            this.OKButton.TabIndex = 5;
            this.OKButton.Text = "&OK";
            this.OKButton.UseVisualStyleBackColor = true;
            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
            // 
            // CancelButton
            // 
            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.CancelButton.Location = new System.Drawing.Point(206, 154);
            this.CancelButton.Margin = new System.Windows.Forms.Padding(2);
            this.CancelButton.Name = "CancelButton";
            this.CancelButton.Size = new System.Drawing.Size(74, 41);
            this.CancelButton.TabIndex = 6;
            this.CancelButton.Text = "&Cancel";
            this.CancelButton.UseVisualStyleBackColor = true;
            // 
            // OneDriveDatabasePath
            // 
            this.OneDriveDatabasePath.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.OneDriveDatabasePath.BackColor = System.Drawing.SystemColors.Control;
            this.OneDriveDatabasePath.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.OneDriveDatabasePath.Location = new System.Drawing.Point(12, 45);
            this.OneDriveDatabasePath.Name = "OneDriveDatabasePath";
            this.OneDriveDatabasePath.ReadOnly = true;
            this.OneDriveDatabasePath.Size = new System.Drawing.Size(369, 13);
            this.OneDriveDatabasePath.TabIndex = 7;
            this.OneDriveDatabasePath.Text = "?";
            // 
            // OneDriveAskToStartSyncingDialog
            // 
            this.AcceptButton = this.OKButton;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(393, 205);
            this.Controls.Add(this.OneDriveDatabasePath);
            this.Controls.Add(this.CancelButton);
            this.Controls.Add(this.OKButton);
            this.Controls.Add(this.NoNeverAskAgainRadio);
            this.Controls.Add(this.NotNowRadio);
            this.Controls.Add(this.YesRadio);
            this.Controls.Add(this.ExplanationLabel);
            this.Margin = new System.Windows.Forms.Padding(2);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(409, 244);
            this.Name = "OneDriveAskToStartSyncingDialog";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Start syncing with OneDrive";
            this.ResumeLayout(false);
            this.PerformLayout();

         }

         #endregion

         private System.Windows.Forms.Label ExplanationLabel;
         private System.Windows.Forms.Button OKButton;
         private System.Windows.Forms.Button CancelButton;
         private System.Windows.Forms.RadioButton YesRadio;
         private System.Windows.Forms.RadioButton NotNowRadio;
         private System.Windows.Forms.RadioButton NoNeverAskAgainRadio;
        private System.Windows.Forms.TextBox OneDriveDatabasePath;
    }
 }

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.cs
================================================
using System;
using System.Windows.Forms;
using KoenZomers.KeePass.OneDriveSync;

namespace KoenZomersKeePassOneDriveSync
{
    public partial class OneDriveAskToStartSyncingDialog : Form
    {
        /// <summary>
        /// Configuration of the database for which this question is being asked for
        /// </summary>
        private readonly Configuration _configuration;

        public OneDriveAskToStartSyncingDialog(Configuration configuration)
        {
            InitializeComponent();

            _configuration = configuration;

            OneDriveDatabasePath.Text = configuration.KeePassDatabase.IOConnectionInfo.Path;
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            if (NotNowRadio.Checked)
            {
                DialogResult = DialogResult.Cancel;
            }
            if (YesRadio.Checked)
            {
                DialogResult = DialogResult.OK;
            }
            if (NoNeverAskAgainRadio.Checked)
            {
                _configuration.DoNotSync = NoNeverAskAgainRadio.Checked;
                Configuration.Save();
                DialogResult = DialogResult.OK;
            }

            Close();
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class OneDriveAuthenticateForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.WebBrowser = new System.Windows.Forms.WebBrowser();
            this.SuspendLayout();
            // 
            // WebBrowser
            // 
            this.WebBrowser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.WebBrowser.Location = new System.Drawing.Point(-2, 0);
            this.WebBrowser.MinimumSize = new System.Drawing.Size(22, 25);
            this.WebBrowser.Name = "WebBrowser";
            this.WebBrowser.ScriptErrorsSuppressed = true;
            this.WebBrowser.Size = new System.Drawing.Size(664, 828);
            this.WebBrowser.TabIndex = 0;
            this.WebBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.WebBrowser_Navigated);
            // 
            // OneDriveAuthenticateForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(664, 826);
            this.Controls.Add(this.WebBrowser);
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(438, 390);
            this.Name = "OneDriveAuthenticateForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Authenticate to OneDrive";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.WebBrowser WebBrowser;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.cs
================================================
using System.Windows.Forms;
using KoenZomers.OneDrive.Api;

namespace KoenZomersKeePassOneDriveSync
{
    public partial class OneDriveAuthenticateForm : Form
    {
        /// <summary>
        /// OneDrive API instance
        /// </summary>
        public OneDriveApi OneDriveApi { get; private set; }

        public OneDriveAuthenticateForm(OneDriveApi oneDriveApi)
        {
            InitializeComponent();

            OneDriveApi = oneDriveApi;
            Utilities.ApplyProxySettings(OneDriveApi);

            SignOut();
        }

        /// <summary>
        /// Sign the current user out of OneDrive
        /// </summary>
        public void SignOut()
        {
            // First sign the current user out to make sure he/she needs to authenticate again
            var signoutUri = OneDriveApi.GetSignOutUri();
            WebBrowser.Navigate(signoutUri);
        }

        private async void WebBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            // Check if the current URL contains the authorization token
            var authorizationCode = OneDriveApi.GetAuthorizationTokenFromUrl(e.Url.ToString());

            // Verify if an authorization token was successfully extracted
            if (!string.IsNullOrEmpty(authorizationCode))
            {
                // Get an access token based on the authorization token that we now have
                await OneDriveApi.GetAccessToken();
                if (OneDriveApi.AccessToken != null)
                {
                    DialogResult = DialogResult.OK;
                    Close();
                    return;
                }
            }

            // If we're on this page, but we didn't get an authorization token, it means that we just signed out, proceed with signing in again
            if (e.Url.ToString().StartsWith(OneDriveApi.SignoutUri))
            {
                var authenticateUri = OneDriveApi.GetAuthenticationUri();
                WebBrowser.Navigate(authenticateUri);
            }
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class OneDriveCloudTypeForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.CancelButton = new System.Windows.Forms.Button();
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.CloudPlatformTabs = new System.Windows.Forms.TabControl();
            this.OneDriveTab = new System.Windows.Forms.TabPage();
            this.GraphDeviceLoginPictureButton = new System.Windows.Forms.Button();
            this.GraphPictureButton = new System.Windows.Forms.Button();
            this.SharePointTab = new System.Windows.Forms.TabPage();
            this.SharePointPictureButton = new System.Windows.Forms.Button();
            this.CloudPlatformTabs.SuspendLayout();
            this.OneDriveTab.SuspendLayout();
            this.SharePointTab.SuspendLayout();
            this.SuspendLayout();
            // 
            // CancelButton
            // 
            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.CancelButton.Location = new System.Drawing.Point(200, 432);
            this.CancelButton.Name = "CancelButton";
            this.CancelButton.Size = new System.Drawing.Size(168, 43);
            this.CancelButton.TabIndex = 1;
            this.CancelButton.Text = "Cancel";
            this.CancelButton.UseVisualStyleBackColor = true;
            this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click);
            // 
            // ExplanationLabel
            // 
            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ExplanationLabel.Location = new System.Drawing.Point(22, 9);
            this.ExplanationLabel.Name = "ExplanationLabel";
            this.ExplanationLabel.Size = new System.Drawing.Size(531, 37);
            this.ExplanationLabel.TabIndex = 0;
            this.ExplanationLabel.Text = "Choose the cloud service you wish to store the KeePass database on:";
            // 
            // CloudPlatformTabs
            // 
            this.CloudPlatformTabs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.CloudPlatformTabs.Controls.Add(this.OneDriveTab);
            this.CloudPlatformTabs.Controls.Add(this.SharePointTab);
            this.CloudPlatformTabs.Location = new System.Drawing.Point(26, 48);
            this.CloudPlatformTabs.Name = "CloudPlatformTabs";
            this.CloudPlatformTabs.SelectedIndex = 0;
            this.CloudPlatformTabs.Size = new System.Drawing.Size(514, 378);
            this.CloudPlatformTabs.TabIndex = 0;
            // 
            // OneDriveTab
            // 
            this.OneDriveTab.Controls.Add(this.GraphDeviceLoginPictureButton);
            this.OneDriveTab.Controls.Add(this.GraphPictureButton);
            this.OneDriveTab.Location = new System.Drawing.Point(4, 29);
            this.OneDriveTab.Name = "OneDriveTab";
            this.OneDriveTab.Size = new System.Drawing.Size(506, 345);
            this.OneDriveTab.TabIndex = 0;
            this.OneDriveTab.Text = "OneDrive";
            this.OneDriveTab.UseVisualStyleBackColor = true;
            // 
            // GraphDeviceLoginPictureButton
            // 
            this.GraphDeviceLoginPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.GraphDeviceLoginPictureButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.GraphDeviceLoginPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.GraphDeviceLoginPictureButton.Location = new System.Drawing.Point(10, 15);
            this.GraphDeviceLoginPictureButton.Name = "GraphDeviceLoginPictureButton";
            this.GraphDeviceLoginPictureButton.Size = new System.Drawing.Size(483, 151);
            this.GraphDeviceLoginPictureButton.TabIndex = 0;
            this.GraphDeviceLoginPictureButton.Text = "&Any browser (recommended)";
            this.GraphDeviceLoginPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
            this.GraphDeviceLoginPictureButton.UseVisualStyleBackColor = false;
            this.GraphDeviceLoginPictureButton.Click += new System.EventHandler(this.GraphDeviceLoginPictureButton_Click);
            // 
            // GraphPictureButton
            // 
            this.GraphPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.GraphPictureButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.GraphPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.GraphPictureButton.Location = new System.Drawing.Point(10, 175);
            this.GraphPictureButton.Name = "GraphPictureButton";
            this.GraphPictureButton.Size = new System.Drawing.Size(483, 151);
            this.GraphPictureButton.TabIndex = 1;
            this.GraphPictureButton.Text = "&Built-in browser";
            this.GraphPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
            this.GraphPictureButton.UseVisualStyleBackColor = false;
            this.GraphPictureButton.Click += new System.EventHandler(this.GraphPictureButton_Click);
            // 
            // SharePointTab
            // 
            this.SharePointTab.Controls.Add(this.SharePointPictureButton);
            this.SharePointTab.Location = new System.Drawing.Point(4, 29);
            this.SharePointTab.Name = "SharePointTab";
            this.SharePointTab.Size = new System.Drawing.Size(506, 345);
            this.SharePointTab.TabIndex = 1;
            this.SharePointTab.Text = "SharePoint";
            this.SharePointTab.UseVisualStyleBackColor = true;
            // 
            // SharePointPictureButton
            // 
            this.SharePointPictureButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.SharePointPictureButton.BackColor = System.Drawing.Color.White;
            this.SharePointPictureButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.SharePointPictureButton.ForeColor = System.Drawing.SystemColors.ControlText;
            this.SharePointPictureButton.Location = new System.Drawing.Point(12, 17);
            this.SharePointPictureButton.Name = "SharePointPictureButton";
            this.SharePointPictureButton.Size = new System.Drawing.Size(483, 129);
            this.SharePointPictureButton.TabIndex = 8;
            this.SharePointPictureButton.Text = "SharePoint 2013, 2016, 2019 & Online";
            this.SharePointPictureButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
            this.SharePointPictureButton.UseMnemonic = false;
            this.SharePointPictureButton.UseVisualStyleBackColor = false;
            this.SharePointPictureButton.Click += new System.EventHandler(this.SharePointPictureButton_Click);
            // 
            // OneDriveCloudTypeForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(564, 489);
            this.Controls.Add(this.CloudPlatformTabs);
            this.Controls.Add(this.ExplanationLabel);
            this.Controls.Add(this.CancelButton);
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "OneDriveCloudTypeForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Choose Cloud Platform";
            this.CloudPlatformTabs.ResumeLayout(false);
            this.OneDriveTab.ResumeLayout(false);
            this.SharePointTab.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button CancelButton;
        private System.Windows.Forms.Label ExplanationLabel;
        private System.Windows.Forms.TabControl CloudPlatformTabs;
        private System.Windows.Forms.TabPage OneDriveTab;
        private System.Windows.Forms.Button GraphPictureButton;
        private System.Windows.Forms.TabPage SharePointTab;
        private System.Windows.Forms.Button SharePointPictureButton;
        private System.Windows.Forms.Button GraphDeviceLoginPictureButton;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.cs
================================================
using System;
using System.Windows.Forms;
using KoenZomers.KeePass.OneDriveSync.Enums;

namespace KoenZomersKeePassOneDriveSync
{
    public partial class OneDriveCloudTypeForm : Form
    {
        /// <summary>
        /// The cloud storage provider that was chosen in this dialog
        /// </summary>
        public CloudStorageType ChosenCloudStorageType { get; private set; }

        /// <summary>
        /// Gets or sets the explanation text in the dialog
        /// </summary>
        public string ExplanationText
        {
            get { return ExplanationLabel.Text; }
            set { ExplanationLabel.Text = value; }
        }

        public OneDriveCloudTypeForm()
        {
            InitializeComponent();

            GraphPictureButton.BackgroundImage = Resources.OneDriveBothClouds;
            GraphDeviceLoginPictureButton.BackgroundImage = Resources.OneDriveBothClouds;
            SharePointPictureButton.BackgroundImage = Resources.SharePoint;
        }

        private void OneDriveConsumerPicture_Click(object sender, EventArgs e)
        {
            ChosenCloudStorageType = CloudStorageType.OneDriveConsumer;
            DialogResult = DialogResult.OK;

            Close();
        }

        private void OneDriveConsumerPictureButton_Click(object sender, EventArgs e)
        {
            ChosenCloudStorageType = CloudStorageType.OneDriveConsumer;
            DialogResult = DialogResult.OK;

            Close();
        }

        private void GraphPictureButton_Click(object sender, EventArgs e)
        {
            ChosenCloudStorageType = CloudStorageType.MicrosoftGraph;
            DialogResult = DialogResult.OK;

            Close();
        }

        private void SharePointPictureButton_Click(object sender, EventArgs e)
        {
            ChosenCloudStorageType = CloudStorageType.SharePoint;
            DialogResult = DialogResult.OK;

            Close();
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {

        }

        private void GraphDeviceLoginPictureButton_Click(object sender, EventArgs e)
        {
            ChosenCloudStorageType = CloudStorageType.MicrosoftGraphDeviceLogin;
            DialogResult = DialogResult.OK;

            Close();
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class OneDriveConfigDetailsForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.LocationNameLabel = new System.Windows.Forms.Label();
            this.LocalKeePassPathLabel = new System.Windows.Forms.Label();
            this.RemoteKeePassPathLabel = new System.Windows.Forms.Label();
            this.OneDriveRefreshTokenLabel = new System.Windows.Forms.Label();
            this.RemoteKeePassPathTextbox = new System.Windows.Forms.TextBox();
            this.OneDriveRefreshTokenTextbox = new System.Windows.Forms.TextBox();
            this.OneDriveNameTextbox = new System.Windows.Forms.TextBox();
            this.CloseButton = new System.Windows.Forms.Button();
            this.DeleteButton = new System.Windows.Forms.Button();
            this.LastSyncedLabel = new System.Windows.Forms.Label();
            this.LastSyncedTextbox = new System.Windows.Forms.TextBox();
            this.LocalKeePassFileHashLabel = new System.Windows.Forms.Label();
            this.LocalKeePassFileHashTextbox = new System.Windows.Forms.TextBox();
            this.ForceSyncButton = new System.Windows.Forms.Button();
            this.LastVerifiedLabel = new System.Windows.Forms.Label();
            this.LastVerifiedTextbox = new System.Windows.Forms.TextBox();
            this.StatusLabel = new System.Windows.Forms.Label();
            this.RefreshTokenStorageTextBox = new System.Windows.Forms.TextBox();
            this.RefreshTokenStorageLabel = new System.Windows.Forms.Label();
            this.CloudStorageTypeTextBox = new System.Windows.Forms.TextBox();
            this.CloudStorageTypeLabel = new System.Windows.Forms.Label();
            this.OneDriveEtagTextBox = new System.Windows.Forms.TextBox();
            this.OneDriveEtagLabel = new System.Windows.Forms.Label();
            this.LocalDatabasePathLinkLabel = new System.Windows.Forms.LinkLabel();
            this.ItemIdTextBox = new System.Windows.Forms.TextBox();
            this.ItemIdLabel = new System.Windows.Forms.Label();
            this.FolderIdTextBox = new System.Windows.Forms.TextBox();
            this.FolderIdLabel = new System.Windows.Forms.Label();
            this.DriveIdTextBox = new System.Windows.Forms.TextBox();
            this.DriveIdLabel = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // LocationNameLabel
            // 
            this.LocationNameLabel.Location = new System.Drawing.Point(16, 11);
            this.LocationNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.LocationNameLabel.Name = "LocationNameLabel";
            this.LocationNameLabel.Size = new System.Drawing.Size(236, 20);
            this.LocationNameLabel.TabIndex = 0;
            this.LocationNameLabel.Text = "Location Name:";
            this.LocationNameLabel.UseMnemonic = false;
            // 
            // LocalKeePassPathLabel
            // 
            this.LocalKeePassPathLabel.Location = new System.Drawing.Point(16, 58);
            this.LocalKeePassPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.LocalKeePassPathLabel.Name = "LocalKeePassPathLabel";
            this.LocalKeePassPathLabel.Size = new System.Drawing.Size(236, 20);
            this.LocalKeePassPathLabel.TabIndex = 2;
            this.LocalKeePassPathLabel.Text = "Local KeePass path:";
            this.LocalKeePassPathLabel.UseMnemonic = false;
            // 
            // RemoteKeePassPathLabel
            // 
            this.RemoteKeePassPathLabel.Location = new System.Drawing.Point(16, 83);
            this.RemoteKeePassPathLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.RemoteKeePassPathLabel.Name = "RemoteKeePassPathLabel";
            this.RemoteKeePassPathLabel.Size = new System.Drawing.Size(236, 20);
            this.RemoteKeePassPathLabel.TabIndex = 4;
            this.RemoteKeePassPathLabel.Text = "Remote KeePass path:";
            this.RemoteKeePassPathLabel.UseMnemonic = false;
            // 
            // OneDriveRefreshTokenLabel
            // 
            this.OneDriveRefreshTokenLabel.Location = new System.Drawing.Point(16, 109);
            this.OneDriveRefreshTokenLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.OneDriveRefreshTokenLabel.Name = "OneDriveRefreshTokenLabel";
            this.OneDriveRefreshTokenLabel.Size = new System.Drawing.Size(236, 20);
            this.OneDriveRefreshTokenLabel.TabIndex = 6;
            this.OneDriveRefreshTokenLabel.Text = "API Refresh Token:";
            this.OneDriveRefreshTokenLabel.UseMnemonic = false;
            // 
            // RemoteKeePassPathTextbox
            // 
            this.RemoteKeePassPathTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.RemoteKeePassPathTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.RemoteKeePassPathTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.RemoteKeePassPathTextbox.Location = new System.Drawing.Point(260, 83);
            this.RemoteKeePassPathTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.RemoteKeePassPathTextbox.Name = "RemoteKeePassPathTextbox";
            this.RemoteKeePassPathTextbox.ReadOnly = true;
            this.RemoteKeePassPathTextbox.Size = new System.Drawing.Size(444, 15);
            this.RemoteKeePassPathTextbox.TabIndex = 4;
            this.RemoteKeePassPathTextbox.Text = "?";
            // 
            // OneDriveRefreshTokenTextbox
            // 
            this.OneDriveRefreshTokenTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.OneDriveRefreshTokenTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.OneDriveRefreshTokenTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.OneDriveRefreshTokenTextbox.Location = new System.Drawing.Point(260, 109);
            this.OneDriveRefreshTokenTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.OneDriveRefreshTokenTextbox.Name = "OneDriveRefreshTokenTextbox";
            this.OneDriveRefreshTokenTextbox.ReadOnly = true;
            this.OneDriveRefreshTokenTextbox.Size = new System.Drawing.Size(444, 15);
            this.OneDriveRefreshTokenTextbox.TabIndex = 5;
            this.OneDriveRefreshTokenTextbox.Text = "?";
            // 
            // OneDriveNameTextbox
            // 
            this.OneDriveNameTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.OneDriveNameTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.OneDriveNameTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.OneDriveNameTextbox.Location = new System.Drawing.Point(260, 11);
            this.OneDriveNameTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.OneDriveNameTextbox.Name = "OneDriveNameTextbox";
            this.OneDriveNameTextbox.ReadOnly = true;
            this.OneDriveNameTextbox.Size = new System.Drawing.Size(444, 15);
            this.OneDriveNameTextbox.TabIndex = 2;
            this.OneDriveNameTextbox.Text = "?";
            // 
            // CloseButton
            // 
            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.CloseButton.Location = new System.Drawing.Point(572, 333);
            this.CloseButton.Margin = new System.Windows.Forms.Padding(4);
            this.CloseButton.Name = "CloseButton";
            this.CloseButton.Size = new System.Drawing.Size(132, 41);
            this.CloseButton.TabIndex = 1;
            this.CloseButton.Text = "&Close";
            this.CloseButton.UseVisualStyleBackColor = true;
            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // DeleteButton
            // 
            this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.DeleteButton.Location = new System.Drawing.Point(20, 333);
            this.DeleteButton.Margin = new System.Windows.Forms.Padding(4);
            this.DeleteButton.Name = "DeleteButton";
            this.DeleteButton.Size = new System.Drawing.Size(132, 41);
            this.DeleteButton.TabIndex = 13;
            this.DeleteButton.Text = "&Delete";
            this.DeleteButton.UseVisualStyleBackColor = true;
            this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click);
            // 
            // LastSyncedLabel
            // 
            this.LastSyncedLabel.Location = new System.Drawing.Point(16, 161);
            this.LastSyncedLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.LastSyncedLabel.Name = "LastSyncedLabel";
            this.LastSyncedLabel.Size = new System.Drawing.Size(236, 20);
            this.LastSyncedLabel.TabIndex = 14;
            this.LastSyncedLabel.Text = "Last synced with {0}:";
            this.LastSyncedLabel.UseMnemonic = false;
            // 
            // LastSyncedTextbox
            // 
            this.LastSyncedTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.LastSyncedTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.LastSyncedTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.LastSyncedTextbox.Location = new System.Drawing.Point(260, 161);
            this.LastSyncedTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.LastSyncedTextbox.Name = "LastSyncedTextbox";
            this.LastSyncedTextbox.ReadOnly = true;
            this.LastSyncedTextbox.Size = new System.Drawing.Size(444, 15);
            this.LastSyncedTextbox.TabIndex = 15;
            this.LastSyncedTextbox.Text = "?";
            // 
            // LocalKeePassFileHashLabel
            // 
            this.LocalKeePassFileHashLabel.Location = new System.Drawing.Point(16, 212);
            this.LocalKeePassFileHashLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.LocalKeePassFileHashLabel.Name = "LocalKeePassFileHashLabel";
            this.LocalKeePassFileHashLabel.Size = new System.Drawing.Size(236, 20);
            this.LocalKeePassFileHashLabel.TabIndex = 16;
            this.LocalKeePassFileHashLabel.Text = "Local KeePass SHA1 hash:";
            this.LocalKeePassFileHashLabel.UseMnemonic = false;
            // 
            // LocalKeePassFileHashTextbox
            // 
            this.LocalKeePassFileHashTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.LocalKeePassFileHashTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.LocalKeePassFileHashTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.LocalKeePassFileHashTextbox.Location = new System.Drawing.Point(260, 212);
            this.LocalKeePassFileHashTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.LocalKeePassFileHashTextbox.Name = "LocalKeePassFileHashTextbox";
            this.LocalKeePassFileHashTextbox.ReadOnly = true;
            this.LocalKeePassFileHashTextbox.Size = new System.Drawing.Size(444, 15);
            this.LocalKeePassFileHashTextbox.TabIndex = 17;
            this.LocalKeePassFileHashTextbox.Text = "?";
            // 
            // ForceSyncButton
            // 
            this.ForceSyncButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.ForceSyncButton.Location = new System.Drawing.Point(432, 333);
            this.ForceSyncButton.Margin = new System.Windows.Forms.Padding(4);
            this.ForceSyncButton.Name = "ForceSyncButton";
            this.ForceSyncButton.Size = new System.Drawing.Size(132, 41);
            this.ForceSyncButton.TabIndex = 18;
            this.ForceSyncButton.Text = "&Sync Now";
            this.ForceSyncButton.UseVisualStyleBackColor = true;
            this.ForceSyncButton.Click += new System.EventHandler(this.ForceSyncButton_Click);
            // 
            // LastVerifiedLabel
            // 
            this.LastVerifiedLabel.Location = new System.Drawing.Point(16, 186);
            this.LastVerifiedLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.LastVerifiedLabel.Name = "LastVerifiedLabel";
            this.LastVerifiedLabel.Size = new System.Drawing.Size(236, 20);
            this.LastVerifiedLabel.TabIndex = 19;
            this.LastVerifiedLabel.Text = "Last verified with {0}:";
            this.LastVerifiedLabel.UseMnemonic = false;
            // 
            // LastVerifiedTextbox
            // 
            this.LastVerifiedTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.LastVerifiedTextbox.BackColor = System.Drawing.SystemColors.Control;
            this.LastVerifiedTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.LastVerifiedTextbox.Location = new System.Drawing.Point(260, 186);
            this.LastVerifiedTextbox.Margin = new System.Windows.Forms.Padding(4);
            this.LastVerifiedTextbox.Name = "LastVerifiedTextbox";
            this.LastVerifiedTextbox.ReadOnly = true;
            this.LastVerifiedTextbox.Size = new System.Drawing.Size(444, 15);
            this.LastVerifiedTextbox.TabIndex = 20;
            this.LastVerifiedTextbox.Text = "?";
            // 
            // StatusLabel
            // 
            this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.StatusLabel.Location = new System.Drawing.Point(160, 333);
            this.StatusLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.StatusLabel.Name = "StatusLabel";
            this.StatusLabel.Size = new System.Drawing.Size(264, 44);
            this.StatusLabel.TabIndex = 21;
            this.StatusLabel.Text = "Ready";
            this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.StatusLabel.UseMnemonic = false;
            // 
            // RefreshTokenStorageTextBox
            // 
            this.RefreshTokenStorageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.RefreshTokenStorageTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.RefreshTokenStorageTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.RefreshTokenStorageTextBox.Location = new System.Drawing.Point(260, 135);
            this.RefreshTokenStorageTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.RefreshTokenStorageTextBox.Name = "RefreshTokenStorageTextBox";
            this.RefreshTokenStorageTextBox.ReadOnly = true;
            this.RefreshTokenStorageTextBox.Size = new System.Drawing.Size(444, 15);
            this.RefreshTokenStorageTextBox.TabIndex = 22;
            this.RefreshTokenStorageTextBox.Text = "?";
            // 
            // RefreshTokenStorageLabel
            // 
            this.RefreshTokenStorageLabel.Location = new System.Drawing.Point(16, 135);
            this.RefreshTokenStorageLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.RefreshTokenStorageLabel.Name = "RefreshTokenStorageLabel";
            this.RefreshTokenStorageLabel.Size = new System.Drawing.Size(236, 20);
            this.RefreshTokenStorageLabel.TabIndex = 23;
            this.RefreshTokenStorageLabel.Text = "Refresh Token Storage:";
            this.RefreshTokenStorageLabel.UseMnemonic = false;
            // 
            // CloudStorageTypeTextBox
            // 
            this.CloudStorageTypeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.CloudStorageTypeTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.CloudStorageTypeTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.CloudStorageTypeTextBox.Location = new System.Drawing.Point(260, 34);
            this.CloudStorageTypeTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.CloudStorageTypeTextBox.Name = "CloudStorageTypeTextBox";
            this.CloudStorageTypeTextBox.ReadOnly = true;
            this.CloudStorageTypeTextBox.Size = new System.Drawing.Size(444, 15);
            this.CloudStorageTypeTextBox.TabIndex = 25;
            this.CloudStorageTypeTextBox.Text = "?";
            // 
            // CloudStorageTypeLabel
            // 
            this.CloudStorageTypeLabel.Location = new System.Drawing.Point(16, 34);
            this.CloudStorageTypeLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.CloudStorageTypeLabel.Name = "CloudStorageTypeLabel";
            this.CloudStorageTypeLabel.Size = new System.Drawing.Size(236, 20);
            this.CloudStorageTypeLabel.TabIndex = 24;
            this.CloudStorageTypeLabel.Text = "Cloud storage type:";
            this.CloudStorageTypeLabel.UseMnemonic = false;
            // 
            // OneDriveEtagTextBox
            // 
            this.OneDriveEtagTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.OneDriveEtagTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.OneDriveEtagTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.OneDriveEtagTextBox.Location = new System.Drawing.Point(260, 238);
            this.OneDriveEtagTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.OneDriveEtagTextBox.Name = "OneDriveEtagTextBox";
            this.OneDriveEtagTextBox.ReadOnly = true;
            this.OneDriveEtagTextBox.Size = new System.Drawing.Size(444, 15);
            this.OneDriveEtagTextBox.TabIndex = 27;
            this.OneDriveEtagTextBox.Text = "?";
            // 
            // OneDriveEtagLabel
            // 
            this.OneDriveEtagLabel.Location = new System.Drawing.Point(16, 238);
            this.OneDriveEtagLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.OneDriveEtagLabel.Name = "OneDriveEtagLabel";
            this.OneDriveEtagLabel.Size = new System.Drawing.Size(236, 20);
            this.OneDriveEtagLabel.TabIndex = 26;
            this.OneDriveEtagLabel.Text = "ETag:";
            this.OneDriveEtagLabel.UseMnemonic = false;
            // 
            // LocalDatabasePathLinkLabel
            // 
            this.LocalDatabasePathLinkLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.LocalDatabasePathLinkLabel.Location = new System.Drawing.Point(257, 58);
            this.LocalDatabasePathLinkLabel.Name = "LocalDatabasePathLinkLabel";
            this.LocalDatabasePathLinkLabel.Size = new System.Drawing.Size(447, 20);
            this.LocalDatabasePathLinkLabel.TabIndex = 28;
            this.LocalDatabasePathLinkLabel.TabStop = true;
            this.LocalDatabasePathLinkLabel.Text = "?";
            this.LocalDatabasePathLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LocalDatabasePathLinkLabel_LinkClicked);
            // 
            // ItemIdTextBox
            // 
            this.ItemIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ItemIdTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.ItemIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.ItemIdTextBox.Location = new System.Drawing.Point(260, 261);
            this.ItemIdTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.ItemIdTextBox.Name = "ItemIdTextBox";
            this.ItemIdTextBox.ReadOnly = true;
            this.ItemIdTextBox.Size = new System.Drawing.Size(444, 15);
            this.ItemIdTextBox.TabIndex = 30;
            this.ItemIdTextBox.Text = "?";
            this.ItemIdTextBox.TextChanged += new System.EventHandler(this.ItemIdTextBox_TextChanged);
            // 
            // ItemIdLabel
            // 
            this.ItemIdLabel.Location = new System.Drawing.Point(17, 261);
            this.ItemIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.ItemIdLabel.Name = "ItemIdLabel";
            this.ItemIdLabel.Size = new System.Drawing.Size(236, 20);
            this.ItemIdLabel.TabIndex = 29;
            this.ItemIdLabel.Text = "Item Id:";
            this.ItemIdLabel.UseMnemonic = false;
            this.ItemIdLabel.Click += new System.EventHandler(this.ItemIdLabel_Click);
            // 
            // FolderIdTextBox
            // 
            this.FolderIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.FolderIdTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.FolderIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.FolderIdTextBox.Location = new System.Drawing.Point(259, 284);
            this.FolderIdTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.FolderIdTextBox.Name = "FolderIdTextBox";
            this.FolderIdTextBox.ReadOnly = true;
            this.FolderIdTextBox.Size = new System.Drawing.Size(444, 15);
            this.FolderIdTextBox.TabIndex = 32;
            this.FolderIdTextBox.Text = "?";
            // 
            // FolderIdLabel
            // 
            this.FolderIdLabel.Location = new System.Drawing.Point(16, 284);
            this.FolderIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.FolderIdLabel.Name = "FolderIdLabel";
            this.FolderIdLabel.Size = new System.Drawing.Size(236, 20);
            this.FolderIdLabel.TabIndex = 31;
            this.FolderIdLabel.Text = "Folder Id:";
            this.FolderIdLabel.UseMnemonic = false;
            // 
            // DriveIdTextBox
            // 
            this.DriveIdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.DriveIdTextBox.BackColor = System.Drawing.SystemColors.Control;
            this.DriveIdTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.DriveIdTextBox.Location = new System.Drawing.Point(259, 307);
            this.DriveIdTextBox.Margin = new System.Windows.Forms.Padding(4);
            this.DriveIdTextBox.Name = "DriveIdTextBox";
            this.DriveIdTextBox.ReadOnly = true;
            this.DriveIdTextBox.Size = new System.Drawing.Size(444, 15);
            this.DriveIdTextBox.TabIndex = 34;
            this.DriveIdTextBox.Text = "?";
            // 
            // DriveIdLabel
            // 
            this.DriveIdLabel.Location = new System.Drawing.Point(16, 307);
            this.DriveIdLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
            this.DriveIdLabel.Name = "DriveIdLabel";
            this.DriveIdLabel.Size = new System.Drawing.Size(236, 20);
            this.DriveIdLabel.TabIndex = 33;
            this.DriveIdLabel.Text = "Drive Id:";
            this.DriveIdLabel.UseMnemonic = false;
            // 
            // OneDriveConfigDetailsForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.CancelButton = this.CloseButton;
            this.ClientSize = new System.Drawing.Size(720, 388);
            this.Controls.Add(this.StatusLabel);
            this.Controls.Add(this.ForceSyncButton);
            this.Controls.Add(this.DeleteButton);
            this.Controls.Add(this.CloseButton);
            this.Controls.Add(this.DriveIdTextBox);
            this.Controls.Add(this.DriveIdLabel);
            this.Controls.Add(this.FolderIdTextBox);
            this.Controls.Add(this.FolderIdLabel);
            this.Controls.Add(this.ItemIdTextBox);
            this.Controls.Add(this.ItemIdLabel);
            this.Controls.Add(this.LocalDatabasePathLinkLabel);
            this.Controls.Add(this.OneDriveEtagTextBox);
            this.Controls.Add(this.OneDriveEtagLabel);
            this.Controls.Add(this.CloudStorageTypeTextBox);
            this.Controls.Add(this.CloudStorageTypeLabel);
            this.Controls.Add(this.RefreshTokenStorageTextBox);
            this.Controls.Add(this.RefreshTokenStorageLabel);
            this.Controls.Add(this.LastVerifiedTextbox);
            this.Controls.Add(this.LastVerifiedLabel);
            this.Controls.Add(this.LocalKeePassFileHashTextbox);
            this.Controls.Add(this.LocalKeePassFileHashLabel);
            this.Controls.Add(this.LastSyncedTextbox);
            this.Controls.Add(this.LastSyncedLabel);
            this.Controls.Add(this.OneDriveNameTextbox);
            this.Controls.Add(this.OneDriveRefreshTokenTextbox);
            this.Controls.Add(this.RemoteKeePassPathTextbox);
            this.Controls.Add(this.OneDriveRefreshTokenLabel);
            this.Controls.Add(this.RemoteKeePassPathLabel);
            this.Controls.Add(this.LocalKeePassPathLabel);
            this.Controls.Add(this.LocationNameLabel);
            this.KeyPreview = true;
            this.Margin = new System.Windows.Forms.Padding(4);
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(680, 278);
            this.Name = "OneDriveConfigDetailsForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "OneDriveSync Configuration";
            this.Load += new System.EventHandler(this.OneDriveConfigDetailsForm_Load);
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.OneDriveConfigDetailsForm_KeyUp);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label LocationNameLabel;
        private System.Windows.Forms.Label LocalKeePassPathLabel;
        private System.Windows.Forms.Label RemoteKeePassPathLabel;
        private System.Windows.Forms.Label OneDriveRefreshTokenLabel;
        private System.Windows.Forms.TextBox RemoteKeePassPathTextbox;
        private System.Windows.Forms.TextBox OneDriveRefreshTokenTextbox;
        private System.Windows.Forms.TextBox OneDriveNameTextbox;
        private System.Windows.Forms.Button CloseButton;
        private System.Windows.Forms.Button DeleteButton;
        private System.Windows.Forms.Label LastSyncedLabel;
        private System.Windows.Forms.TextBox LastSyncedTextbox;
        private System.Windows.Forms.Label LocalKeePassFileHashLabel;
        private System.Windows.Forms.TextBox LocalKeePassFileHashTextbox;
        private System.Windows.Forms.Button ForceSyncButton;
        private System.Windows.Forms.Label LastVerifiedLabel;
        private System.Windows.Forms.TextBox LastVerifiedTextbox;
        private System.Windows.Forms.Label StatusLabel;
        private System.Windows.Forms.TextBox RefreshTokenStorageTextBox;
        private System.Windows.Forms.Label RefreshTokenStorageLabel;
        private System.Windows.Forms.TextBox CloudStorageTypeTextBox;
        private System.Windows.Forms.Label CloudStorageTypeLabel;
        private System.Windows.Forms.TextBox OneDriveEtagTextBox;
        private System.Windows.Forms.Label OneDriveEtagLabel;
        private System.Windows.Forms.LinkLabel LocalDatabasePathLinkLabel;
        private System.Windows.Forms.TextBox ItemIdTextBox;
        private System.Windows.Forms.Label ItemIdLabel;
        private System.Windows.Forms.TextBox FolderIdTextBox;
        private System.Windows.Forms.Label FolderIdLabel;
        private System.Windows.Forms.TextBox DriveIdTextBox;
        private System.Windows.Forms.Label DriveIdLabel;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using KoenZomers.KeePass.OneDriveSync;
using KoenZomers.KeePass.OneDriveSync.Enums;

namespace KoenZomersKeePassOneDriveSync
{
    /// <summary>
    /// Detail screen for a OneDriveSync configuration
    /// </summary>
    public partial class OneDriveConfigDetailsForm : Form
    {
        private KeyValuePair<string, Configuration> _configuration;

        /// <summary>
        /// Opens the configuration details screen for the provided configuration
        /// </summary>
        /// <param name="configuration"></param>
        public OneDriveConfigDetailsForm(KeyValuePair<string, Configuration> configuration)
        {
            InitializeComponent();

            _configuration = configuration;
        }

        private void OneDriveConfigDetailsForm_Load(object sender, EventArgs e)
        {
            ShowConfiguration();
        }

        private void ShowConfiguration()
        {
            LocationNameLabel.Text = _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? "SharePoint site:" : "OneDrive name:";
            LastSyncedLabel.Text = string.Format(LastSyncedLabel.Text, _configuration.Value.CloudStorageType);
            LastVerifiedLabel.Text = string.Format(LastVerifiedLabel.Text, _configuration.Value.CloudStorageType);
            OneDriveNameTextbox.Text = _configuration.Value.DoNotSync ? "Not enabled for sync" : _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? _configuration.Value.RemoteDatabasePath + (string.IsNullOrEmpty(_configuration.Value.OneDriveName) ? "" : " (" + _configuration.Value.OneDriveName + ")") : _configuration.Value.OneDriveName;
            CloudStorageTypeTextBox.Text = _configuration.Value.CloudStorageType.GetValueOrDefault(CloudStorageType.OneDriveConsumer).ToString();
            LocalDatabasePathLinkLabel.Text = _configuration.Key;
            LocalDatabasePathLinkLabel.LinkColor = System.IO.File.Exists(_configuration.Key) ? System.Drawing.Color.Blue : System.Drawing.Color.Red;
            RemoteKeePassPathTextbox.Text = _configuration.Value.CloudStorageType == CloudStorageType.SharePoint ? _configuration.Value.RemoteFolderId + "/" + _configuration.Value.RemoteFileName : _configuration.Value.RemoteDatabasePath;
            OneDriveRefreshTokenTextbox.Text = _configuration.Value.RefreshToken;
            RefreshTokenStorageTextBox.Text = _configuration.Value.RefreshTokenStorage.ToString();
            LastSyncedTextbox.Text = _configuration.Value.LastSyncedAt.HasValue ? _configuration.Value.LastSyncedAt.Value.ToString("dddd d MMMM yyyy HH:mm:ss") : "Never synced yet";
            LastVerifiedTextbox.Text = _configuration.Value.LastCheckedAt.HasValue ? _configuration.Value.LastCheckedAt.Value.ToString("dddd d MMMM yyyy HH:mm:ss") : "Never verified yet";
            LocalKeePassFileHashTextbox.Text = _configuration.Value.LocalFileHash;
            OneDriveEtagTextBox.Text = _configuration.Value.ETag;
            ForceSyncButton.Enabled = !_configuration.Value.DoNotSync;
            ItemIdTextBox.Text = _configuration.Value.RemoteItemId;
            FolderIdTextBox.Text = _configuration.Value.RemoteFolderId;
            DriveIdTextBox.Text = _configuration.Value.RemoteDriveId;
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void DeleteButton_Click(object sender, EventArgs e)
        {
            var answer = MessageBox.Show("Are you sure that you wish to delete the OneDrive configuration for the selected KeePass databases? This will NOT delete the actual KeePass database file, just its configuration for the KeeOneDriveSync plugin.", "Confirm removal", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
            if (answer != DialogResult.Yes) return;

            Configuration.DeleteConfig(_configuration.Key);

            Close();
        }

        private async void ForceSyncButton_Click(object sender, EventArgs e)
        {
            if(_configuration.Value.KeePassDatabase == null)
            {
                UpdateStatus("Database must be open before it can synchronize");
                return;
            }

            UpdateStatus("Synchronizing");
            await KeePassDatabase.SyncDatabase(_configuration.Key, UpdateStatus, true, null);
            ShowConfiguration();
        }

        private void UpdateStatus(string message)
        {
            StatusLabel.Text = message;
        }

        private void OneDriveConfigDetailsForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                ShowConfiguration();
            }
        }

        private void LocalDatabasePathLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if(System.IO.File.Exists(LocalDatabasePathLinkLabel.Text))
            {
                // File still exists locally, open explorer and have it highlight the file
                System.Diagnostics.Process.Start("explorer.exe", "/select, \"" + LocalDatabasePathLinkLabel.Text + "\"");
                return;
            }

            // Check if the parent directory still exists 
            var fileInfo = new System.IO.FileInfo(LocalDatabasePathLinkLabel.Text);
            if (System.IO.Directory.Exists(fileInfo.Directory.FullName))
            {
                // Parent directory still exists, open explorer in that folder
                System.Diagnostics.Process.Start("explorer.exe", "\"" + fileInfo.Directory.FullName + "\"");
                return;
            }

            // Both the file and the parent folder no longer exist, nothing we can do
        }

        private void ItemIdLabel_Click(object sender, EventArgs e)
        {

        }

        private void ItemIdTextBox_TextChanged(object sender, EventArgs e)
        {

        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync
{
    partial class OneDriveConfigForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.HeaderLabel = new System.Windows.Forms.Label();
            this.ConfigurationListView = new System.Windows.Forms.ListView();
            this.PathColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.StorageNameColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.StorageProviderColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.LastSyncedColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
            this.ConfigurationListViewContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.ConfigurationListViewContextItemViewDetails = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemRenameStorage = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSyncNow = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemOpenFileLocation = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemDelete = new System.Windows.Forms.ToolStripMenuItem();
            this.CloseButton = new System.Windows.Forms.Button();
            this.StatusLabel = new System.Windows.Forms.Label();
            this.AboutButton = new System.Windows.Forms.Button();
            this.ConfigurationListViewContextItemOpenDatabase = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
            this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
            this.ConfigurationListViewContextItemRefresh = new System.Windows.Forms.ToolStripMenuItem();
            this.selectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectAll = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotAvailableLocally = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotSynced = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotSynced24Hours = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotSyncedWeek = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextItemSelectNotSyncedMonth = new System.Windows.Forms.ToolStripMenuItem();
            this.ConfigurationListViewContextMenu.SuspendLayout();
            this.SuspendLayout();
            // 
            // ExplanationLabel
            // 
            this.ExplanationLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ExplanationLabel.Location = new System.Drawing.Point(13, 36);
            this.ExplanationLabel.Name = "ExplanationLabel";
            this.ExplanationLabel.Size = new System.Drawing.Size(433, 31);
            this.ExplanationLabel.TabIndex = 0;
            this.ExplanationLabel.Text = "Here you\'ll see all KeePass databases that are configured for use with OneDriveSy" +
    "nc.";
            this.ExplanationLabel.UseMnemonic = false;
            // 
            // HeaderLabel
            // 
            this.HeaderLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.HeaderLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.HeaderLabel.Location = new System.Drawing.Point(12, 9);
            this.HeaderLabel.Name = "HeaderLabel";
            this.HeaderLabel.Size = new System.Drawing.Size(434, 23);
            this.HeaderLabel.TabIndex = 1;
            this.HeaderLabel.Text = "KeePass OneDriveSync";
            this.HeaderLabel.UseMnemonic = false;
            // 
            // ConfigurationListView
            // 
            this.ConfigurationListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ConfigurationListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.PathColumn,
            this.StorageNameColumn,
            this.StorageProviderColumn,
            this.LastSyncedColumn});
            this.ConfigurationListView.ContextMenuStrip = this.ConfigurationListViewContextMenu;
            this.ConfigurationListView.FullRowSelect = true;
            this.ConfigurationListView.GridLines = true;
            this.ConfigurationListView.HideSelection = false;
            this.ConfigurationListView.Location = new System.Drawing.Point(15, 55);
            this.ConfigurationListView.Name = "ConfigurationListView";
            this.ConfigurationListView.Size = new System.Drawing.Size(430, 219);
            this.ConfigurationListView.TabIndex = 3;
            this.ConfigurationListView.UseCompatibleStateImageBehavior = false;
            this.ConfigurationListView.View = System.Windows.Forms.View.Details;
            this.ConfigurationListView.DoubleClick += new System.EventHandler(this.ConfigurationListView_DoubleClick);
            this.ConfigurationListView.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ConfigurationListView_KeyUp);
            // 
            // PathColumn
            // 
            this.PathColumn.Text = "Local Path";
            this.PathColumn.Width = 275;
            // 
            // StorageNameColumn
            // 
            this.StorageNameColumn.Text = "Storage Name";
            this.StorageNameColumn.Width = 150;
            // 
            // StorageProviderColumn
            // 
            this.StorageProviderColumn.Text = "Storage Provider";
            this.StorageProviderColumn.Width = 175;
            // 
            // LastSyncedColumn
            // 
            this.LastSyncedColumn.Text = "Last Synced";
            this.LastSyncedColumn.Width = 175;
            // 
            // ConfigurationListViewContextMenu
            // 
            this.ConfigurationListViewContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
            this.ConfigurationListViewContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.ConfigurationListViewContextItemViewDetails,
            this.ConfigurationListViewContextItemRenameStorage,
            this.ConfigurationListViewContextItemDelete,
            this.toolStripMenuItem2,
            this.ConfigurationListViewContextItemSyncNow,
            this.toolStripMenuItem1,
            this.selectToolStripMenuItem,
            this.ConfigurationListViewContextItemRefresh,
            this.toolStripMenuItem3,
            this.ConfigurationListViewContextItemOpenFileLocation,
            this.ConfigurationListViewContextItemOpenDatabase});
            this.ConfigurationListViewContextMenu.Name = "ConfigurationListViewContextMenu";
            this.ConfigurationListViewContextMenu.Size = new System.Drawing.Size(218, 198);
            this.ConfigurationListViewContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ConfigurationListViewContextMenu_Opening);
            // 
            // ConfigurationListViewContextItemViewDetails
            // 
            this.ConfigurationListViewContextItemViewDetails.Name = "ConfigurationListViewContextItemViewDetails";
            this.ConfigurationListViewContextItemViewDetails.ShortcutKeys = System.Windows.Forms.Keys.F1;
            this.ConfigurationListViewContextItemViewDetails.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemViewDetails.Text = "&View details";
            this.ConfigurationListViewContextItemViewDetails.Click += new System.EventHandler(this.ConfigurationListViewContextItemViewDetails_Click);
            // 
            // ConfigurationListViewContextItemRenameStorage
            // 
            this.ConfigurationListViewContextItemRenameStorage.Name = "ConfigurationListViewContextItemRenameStorage";
            this.ConfigurationListViewContextItemRenameStorage.ShortcutKeys = System.Windows.Forms.Keys.F2;
            this.ConfigurationListViewContextItemRenameStorage.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemRenameStorage.Text = "&Rename storage";
            this.ConfigurationListViewContextItemRenameStorage.Click += new System.EventHandler(this.ConfigurationListViewContextItemRenameStorage_Click);
            // 
            // ConfigurationListViewContextItemSyncNow
            // 
            this.ConfigurationListViewContextItemSyncNow.Name = "ConfigurationListViewContextItemSyncNow";
            this.ConfigurationListViewContextItemSyncNow.ShortcutKeys = System.Windows.Forms.Keys.F4;
            this.ConfigurationListViewContextItemSyncNow.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemSyncNow.Text = "&Sync Now";
            this.ConfigurationListViewContextItemSyncNow.Click += new System.EventHandler(this.ConfigurationListViewContextItemSyncNow_Click);
            // 
            // ConfigurationListViewContextItemOpenFileLocation
            // 
            this.ConfigurationListViewContextItemOpenFileLocation.Name = "ConfigurationListViewContextItemOpenFileLocation";
            this.ConfigurationListViewContextItemOpenFileLocation.ShortcutKeys = System.Windows.Forms.Keys.F7;
            this.ConfigurationListViewContextItemOpenFileLocation.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemOpenFileLocation.Text = "Open file &location";
            this.ConfigurationListViewContextItemOpenFileLocation.Click += new System.EventHandler(this.ConfigurationListViewContextItemOpenFileLocation_Click);
            // 
            // ConfigurationListViewContextItemDelete
            // 
            this.ConfigurationListViewContextItemDelete.Name = "ConfigurationListViewContextItemDelete";
            this.ConfigurationListViewContextItemDelete.ShortcutKeys = System.Windows.Forms.Keys.Delete;
            this.ConfigurationListViewContextItemDelete.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemDelete.Text = "&Delete configuration";
            this.ConfigurationListViewContextItemDelete.Click += new System.EventHandler(this.ConfigurationListViewContextItemDelete_Click);
            // 
            // CloseButton
            // 
            this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.CloseButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.CloseButton.Location = new System.Drawing.Point(347, 280);
            this.CloseButton.Name = "CloseButton";
            this.CloseButton.Size = new System.Drawing.Size(99, 33);
            this.CloseButton.TabIndex = 4;
            this.CloseButton.Text = "&Close";
            this.CloseButton.UseVisualStyleBackColor = true;
            this.CloseButton.Click += new System.EventHandler(this.CloseButton_Click);
            // 
            // StatusLabel
            // 
            this.StatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.StatusLabel.Location = new System.Drawing.Point(13, 280);
            this.StatusLabel.Name = "StatusLabel";
            this.StatusLabel.Size = new System.Drawing.Size(223, 33);
            this.StatusLabel.TabIndex = 5;
            this.StatusLabel.Text = "-";
            this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.StatusLabel.UseMnemonic = false;
            // 
            // AboutButton
            // 
            this.AboutButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.AboutButton.Location = new System.Drawing.Point(242, 280);
            this.AboutButton.Name = "AboutButton";
            this.AboutButton.Size = new System.Drawing.Size(99, 33);
            this.AboutButton.TabIndex = 6;
            this.AboutButton.Text = "&About";
            this.AboutButton.UseVisualStyleBackColor = true;
            this.AboutButton.Click += new System.EventHandler(this.AboutButton_Click);
            // 
            // ConfigurationListViewContextItemOpenDatabase
            // 
            this.ConfigurationListViewContextItemOpenDatabase.Name = "ConfigurationListViewContextItemOpenDatabase";
            this.ConfigurationListViewContextItemOpenDatabase.ShortcutKeys = System.Windows.Forms.Keys.F8;
            this.ConfigurationListViewContextItemOpenDatabase.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemOpenDatabase.Text = "Open &KeePass database";
            this.ConfigurationListViewContextItemOpenDatabase.Click += new System.EventHandler(this.ConfigurationListViewContextItemOpenDatabase_Click);
            // 
            // toolStripMenuItem1
            // 
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new System.Drawing.Size(214, 6);
            // 
            // toolStripMenuItem2
            // 
            this.toolStripMenuItem2.Name = "toolStripMenuItem2";
            this.toolStripMenuItem2.Size = new System.Drawing.Size(214, 6);
            // 
            // toolStripMenuItem3
            // 
            this.toolStripMenuItem3.Name = "toolStripMenuItem3";
            this.toolStripMenuItem3.Size = new System.Drawing.Size(214, 6);
            // 
            // ConfigurationListViewContextItemRefresh
            // 
            this.ConfigurationListViewContextItemRefresh.Name = "ConfigurationListViewContextItemRefresh";
            this.ConfigurationListViewContextItemRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5;
            this.ConfigurationListViewContextItemRefresh.Size = new System.Drawing.Size(217, 22);
            this.ConfigurationListViewContextItemRefresh.Text = "Refresh &list";
            this.ConfigurationListViewContextItemRefresh.Click += new System.EventHandler(this.ConfigurationListViewContextItemRefresh_Click);
            // 
            // selectToolStripMenuItem
            // 
            this.selectToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.ConfigurationListViewContextItemSelectAll,
            this.ConfigurationListViewContextItemSelectNotAvailableLocally,
            this.ConfigurationListViewContextItemSelectNotSynced});
            this.selectToolStripMenuItem.Name = "selectToolStripMenuItem";
            this.selectToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
            this.selectToolStripMenuItem.Text = "S&elect";
            // 
            // ConfigurationListViewContextItemSelectAll
            // 
            this.ConfigurationListViewContextItemSelectAll.Name = "ConfigurationListViewContextItemSelectAll";
            this.ConfigurationListViewContextItemSelectAll.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
            this.ConfigurationListViewContextItemSelectAll.Size = new System.Drawing.Size(254, 22);
            this.ConfigurationListViewContextItemSelectAll.Text = "&All";
            this.ConfigurationListViewContextItemSelectAll.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectAll_Click);
            // 
            // ConfigurationListViewContextItemSelectNotAvailableLocally
            // 
            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Name = "ConfigurationListViewContextItemSelectNotAvailableLocally";
            this.ConfigurationListViewContextItemSelectNotAvailableLocally.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) 
            | System.Windows.Forms.Keys.A)));
            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Size = new System.Drawing.Size(254, 22);
            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Text = "&Not available locally";
            this.ConfigurationListViewContextItemSelectNotAvailableLocally.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotAvailableLocally_Click);
            // 
            // ConfigurationListViewContextItemSelectNotSynced
            // 
            this.ConfigurationListViewContextItemSelectNotSynced.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.ConfigurationListViewContextItemSelectNotSynced24Hours,
            this.ConfigurationListViewContextItemSelectNotSyncedWeek,
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks,
            this.ConfigurationListViewContextItemSelectNotSyncedMonth});
            this.ConfigurationListViewContextItemSelectNotSynced.Name = "ConfigurationListViewContextItemSelectNotSynced";
            this.ConfigurationListViewContextItemSelectNotSynced.Size = new System.Drawing.Size(254, 22);
            this.ConfigurationListViewContextItemSelectNotSynced.Text = "Not synced in the &past...";
            // 
            // ConfigurationListViewContextItemSelectNotSynced24Hours
            // 
            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Name = "ConfigurationListViewContextItemSelectNotSynced24Hours";
            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Size = new System.Drawing.Size(180, 22);
            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Text = "24 &hours";
            this.ConfigurationListViewContextItemSelectNotSynced24Hours.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSynced24Hours_Click);
            // 
            // ConfigurationListViewContextItemSelectNotSyncedWeek
            // 
            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Name = "ConfigurationListViewContextItemSelectNotSyncedWeek";
            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Size = new System.Drawing.Size(180, 22);
            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Text = "&Week";
            this.ConfigurationListViewContextItemSelectNotSyncedWeek.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSyncedWeek_Click);
            // 
            // ConfigurationListViewContextItemSelectNotSynced2Weeks
            // 
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Name = "ConfigurationListViewContextItemSelectNotSynced2Weeks";
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Size = new System.Drawing.Size(180, 22);
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Text = "&2 Weeks";
            this.ConfigurationListViewContextItemSelectNotSynced2Weeks.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSynced2Weeks_Click);
            // 
            // ConfigurationListViewContextItemSelectNotSyncedMonth
            // 
            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Name = "ConfigurationListViewContextItemSelectNotSyncedMonth";
            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Size = new System.Drawing.Size(180, 22);
            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Text = "&Month";
            this.ConfigurationListViewContextItemSelectNotSyncedMonth.Click += new System.EventHandler(this.ConfigurationListViewContextItemSelectNotSyncedMonth_Click);
            // 
            // OneDriveConfigForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.CancelButton = this.CloseButton;
            this.ClientSize = new System.Drawing.Size(458, 325);
            this.Controls.Add(this.AboutButton);
            this.Controls.Add(this.StatusLabel);
            this.Controls.Add(this.CloseButton);
            this.Controls.Add(this.ConfigurationListView);
            this.Controls.Add(this.HeaderLabel);
            this.Controls.Add(this.ExplanationLabel);
            this.MinimizeBox = false;
            this.MinimumSize = new System.Drawing.Size(386, 217);
            this.Name = "OneDriveConfigForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "OneDrive Sync Configuration";
            this.Load += new System.EventHandler(this.OneDriveConfigForm_Load);
            this.ConfigurationListViewContextMenu.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Label ExplanationLabel;
        private System.Windows.Forms.Label HeaderLabel;
        private System.Windows.Forms.ListView ConfigurationListView;
        private System.Windows.Forms.Button CloseButton;
        private System.Windows.Forms.ColumnHeader PathColumn;
        private System.Windows.Forms.ColumnHeader StorageNameColumn;
        private System.Windows.Forms.ContextMenuStrip ConfigurationListViewContextMenu;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemDelete;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemViewDetails;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSyncNow;
        private System.Windows.Forms.Label StatusLabel;
        private System.Windows.Forms.Button AboutButton;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemOpenFileLocation;
        private System.Windows.Forms.CheckBox UseSystemProxyCheckBox;
        private System.Windows.Forms.ColumnHeader StorageProviderColumn;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemRenameStorage;
        private System.Windows.Forms.ColumnHeader LastSyncedColumn;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemOpenDatabase;
        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemRefresh;
        private System.Windows.Forms.ToolStripMenuItem selectToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectAll;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotAvailableLocally;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced24Hours;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSyncedWeek;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSynced2Weeks;
        private System.Windows.Forms.ToolStripMenuItem ConfigurationListViewContextItemSelectNotSyncedMonth;
    }
}

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using KeePassLib.Serialization;
using KoenZomers.KeePass.OneDriveSync;
using KoenZomers.KeePass.OneDriveSync.Enums;

namespace KoenZomersKeePassOneDriveSync
{
    public partial class OneDriveConfigForm : Form
    {
        /// <summary>
        /// Timer that resets any other status back to the default after a few seconds
        /// </summary>
        private readonly Timer _resetStatusTimer;

        /// <summary>
        /// The default status to show
        /// </summary>
        private string _defaultStatus;

        public OneDriveConfigForm()
        {
            InitializeComponent();

            _resetStatusTimer = new Timer {Enabled = false, Interval = 10000 };
            _resetStatusTimer.Tick += (sender, args) => { _resetStatusTimer.Enabled = false; UpdateStatus(_defaultStatus); };
        }

        private void OneDriveConfigForm_Load(object sender, EventArgs e)
        {
            LoadConfigurations();
        }

        /// <summary>
        /// Loads the configurations in the listview
        /// </summary>
        private void LoadConfigurations()
        {
            UpdateStatus("Loading configuration");

            // Clear the existing items
            ConfigurationListView.Items.Clear();

            var configurations = Configuration.GetAllConfigurations();

            foreach (var configuration in configurations)
            {
                var configurationItem = new ListViewItem
                {
                    Text = configuration.Key,
                    Tag = configuration
                };
                var doesDatabaseExistLocally = File.Exists(configuration.Key);
                var isRemoteDatabase = Regex.IsMatch(configuration.Key, @".+:[\\/]{2}.+", RegexOptions.IgnoreCase);
                configurationItem.BackColor = doesDatabaseExistLocally ? ConfigurationListView.BackColor : isRemoteDatabase ? Color.Orange : Color.Red;
                configurationItem.ToolTipText = doesDatabaseExistLocally ? "Database has been found" : isRemoteDatabase ? "Database is a remote database which is not supported" : "Database has not been found"; 
                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = "OneDrive", Text = configuration.Value.DoNotSync ? "Not synced" : configuration.Value.OneDriveName });
                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = "CloudStorage", Text = configuration.Value.CloudStorageType.HasValue ? configuration.Value.CloudStorageType.Value.ToString() : configuration.Value.DoNotSync ? "Not in cloud" : CloudStorageType.OneDriveConsumer.ToString() });
                configurationItem.SubItems.Add(new ListViewItem.ListViewSubItem { Name = "LastSynced", Text = configuration.Value.LastCheckedAt.HasValue ? configuration.Value.LastCheckedAt.Value.ToString("ddd d MMMM yyyy HH:mm:ss") : "Never", Tag = configuration.Value.LastCheckedAt.HasValue ? (DateTime?) configuration.Value.LastCheckedAt.Value : null });
                ConfigurationListView.Items.Add(configurationItem);
            }

            _defaultStatus = string.Format("{0} configuration{1} found", ConfigurationListView.Items.Count, ConfigurationListView.Items.Count != 1 ? "s" : "");
            UpdateStatus(_defaultStatus);
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            
        }

        private void ConfigurationListViewContextItemDelete_Click(object sender, EventArgs e)
        {
            DeleteItem();
        }

        private void ConfigurationListViewContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ConfigurationListViewContextItemDelete.Enabled = ConfigurationListView.SelectedItems.Count > 0;
            ConfigurationListViewContextItemViewDetails.Enabled = ConfigurationListView.SelectedItems.Count == 1;
            ConfigurationListViewContextItemOpenFileLocation.Enabled = ConfigurationListView.SelectedItems.Count > 0;
            ConfigurationListViewContextItemSyncNow.Enabled = ConfigurationListView.SelectedItems.Count > 0;
            ConfigurationListViewContextItemRenameStorage.Enabled = ConfigurationListView.SelectedItems.Count > 0;
            ConfigurationListViewContextItemOpenDatabase.Enabled = ConfigurationListView.SelectedItems.Count > 0;
        }

        private void ConfigurationListView_DoubleClick(object sender, EventArgs e)
        {
            ViewDetails();
        }

        private void ConfigurationListViewContextItemViewDetails_Click(object sender, EventArgs e)
        {
            ViewDetails();
        }

        private void DeleteItem()
        {
            if (ConfigurationListView.SelectedItems.Count == 0) return;

            var answer = MessageBox.Show("Are you sure that you wish to delete the OneDrive configuration for the selected KeePass databases? This will NOT delete the actual KeePass database file, just its configuration for the KeeOneDriveSync plugin.", "Confirm removal", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);
            if (answer != DialogResult.Yes) return;

            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)
            {
                Configuration.DeleteConfig(((KeyValuePair<string, Configuration>)selectedItem.Tag).Key);
            }

            LoadConfigurations();
        }

        private void ViewDetails()
        {
            if (ConfigurationListView.SelectedItems.Count != 1) return;

            var oneDriveConfigDetailsForm = new OneDriveConfigDetailsForm((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag);
            oneDriveConfigDetailsForm.ShowDialog();

            LoadConfigurations();
        }

        private void RenameEntry()
        {
            if (ConfigurationListView.SelectedItems.Count == 0) return;

            var selectedDatabaseText = ConfigurationListView.SelectedItems.Count == 1 ? ((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag).Value.OneDriveName : string.Format("the selected {0} databases", ConfigurationListView.SelectedItems.Count);

            var renameItemDialog = new Forms.OneDriveRequestInputDialog
            {
                FormTitle = string.Format("Enter new storage name name for {0}", selectedDatabaseText),
                InputValue = ConfigurationListView.SelectedItems.Count == 1 ? ((KeyValuePair<string, Configuration>)ConfigurationListView.SelectedItems[0].Tag).Value.OneDriveName : string.Empty
            };
            renameItemDialog.ShowDialog(this);
            if (renameItemDialog.DialogResult != DialogResult.OK) return;

            // Loop through all selected items to update their names
            foreach (ListViewItem configurationItem in ConfigurationListView.SelectedItems)
            {
                var configuration = (KeyValuePair<string, Configuration>)configurationItem.Tag;
                
                // Update the name in the configuration
                configuration.Value.OneDriveName = renameItemDialog.InputValue;

                // Update the name in the configuration list shown on the screen
                configurationItem.SubItems[1].Text = renameItemDialog.InputValue;
            }
            Configuration.Save();

            UpdateStatus("Storage Name has been changed");
        }

        private async Task SyncNow()
        {
            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)
            {
                // Only allow syncing if the database is not marked with the DoNotSync flag
                var configuration = (KeyValuePair<string, Configuration>)selectedItem.Tag;
                if (configuration.Value.DoNotSync)
                {
                    return;
                }
                
                // Ensure the database to be synced is currently open
                if(configuration.Value.KeePassDatabase == null)
                {
                    UpdateStatus(string.Format("Database {0} must be open before it can sync", configuration.Key));
                    continue;
                }

                UpdateStatus(string.Format("Synchronizing database {0}", configuration.Value.KeePassDatabase.Name));
                await KeePassDatabase.SyncDatabase(selectedItem.Text, UpdateStatus, true, configuration.Value);

                // Update the Last Synced column
                selectedItem.SubItems[3].Text = configuration.Value.LastCheckedAt.HasValue ? configuration.Value.LastCheckedAt.Value.ToString("ddd d MMMM yyyy HH:mm:ss") : "Never";
                selectedItem.SubItems[3].Tag = configuration.Value.LastCheckedAt.HasValue ? (DateTime?) configuration.Value.LastCheckedAt.Value : null;
            }
        }

        private async void ConfigurationListViewContextItemSyncNow_Click(object sender, EventArgs e)
        {
            await SyncNow();
        }

        private void UpdateStatus(string message)
        {
            StatusLabel.Text = message;

            // If the status message is not the default message, enable the timer to reset the status back to the default after a few seconds
            if (_defaultStatus != null && message != _defaultStatus)
            {
                _resetStatusTimer.Enabled = true;
            }
        }

        private void AboutButton_Click(object sender, EventArgs e)
        {
            var oneDriveAboutForm = new OneDriveAboutForm();
            oneDriveAboutForm.ShowDialog();
        }

        private void ConfigurationListView_KeyUp(object sender, KeyEventArgs e)
        {

        }

        private void ConfigurationListViewContextItemOpenFileLocation_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)
            {
                // Get the full local path of the selected KeePass database configuration
                var databaseFileLocation = ((KeyValuePair<string, Configuration>)selectedItem.Tag).Key;

                // Open File Explorer and make it directly jump to the KeePass database if it exists, if not, just open the explorer to the folder
                Process.Start("explorer.exe", File.Exists(databaseFileLocation) ? string.Concat("/select, ", databaseFileLocation) : Directory.GetParent(databaseFileLocation).FullName);
            }
        }

        private void ConfigurationListViewContextItemRenameStorage_Click(object sender, EventArgs e)
        {
            RenameEntry();
        }

        private void ConfigurationListViewContextItemOpenDatabase_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem selectedItem in ConfigurationListView.SelectedItems)
            {
                // Get the full local path of the selected KeePass database configuration
                var databaseFileLocation = ((KeyValuePair<string, Configuration>)selectedItem.Tag).Key;

                // Open the KeePass database
                var databaseFile = IOConnectionInfo.FromPath(databaseFileLocation);
                KoenZomersKeePassOneDriveSyncExt.Host.MainWindow.OpenDatabase(databaseFile, null, false);
            }
        }

        private void ConfigurationListViewContextItemRefresh_Click(object sender, EventArgs e)
        {
            LoadConfigurations();
        }

        private void ConfigurationListViewContextItemSelectAll_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                item.Selected = true;
            }
        }

        private void ConfigurationListViewContextItemSelectNotAvailableLocally_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                item.Selected = item.BackColor == Color.Red;
            }
        }

        private void ConfigurationListViewContextItemSelectNotSynced24Hours_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                var lastChecked = item.SubItems[3].Tag as DateTime?;
                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddHours(24) < DateTime.Now;
            }
        }

        private void ConfigurationListViewContextItemSelectNotSyncedWeek_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                var lastChecked = item.SubItems[3].Tag as DateTime?;
                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddDays(7) < DateTime.Now;
            }
        }

        private void ConfigurationListViewContextItemSelectNotSynced2Weeks_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                var lastChecked = item.SubItems[3].Tag as DateTime?;
                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddDays(14) < DateTime.Now;
            }
        }

        private void ConfigurationListViewContextItemSelectNotSyncedMonth_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in ConfigurationListView.Items)
            {
                var lastChecked = item.SubItems[3].Tag as DateTime?;
                item.Selected = !lastChecked.HasValue || lastChecked.Value.AddMonths(1) < DateTime.Now;
            }
        }
    }
}


================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.resx
================================================
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="ConfigurationListViewContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
</root>

================================================
FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.Designer.cs
================================================
namespace KoenZomersKeePassOneDriveSync.Forms
{
    partial class OneDriveFilePickerDialog
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OneDriveFilePickerDialog));
            this.MyFilesContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.GoToRootToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.goupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
            this.newFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.IconsList = new System.Windows.Forms.ImageList(this.components);
            this.CancelButton = new System.Windows.Forms.Button();
            this.OKButton = new System.Windows.Forms.Button();
            this.UpButton = new System.Windows.Forms.Button();
            this.ExplanationLabel = new System.Windows.Forms.Label();
            this.FileNameTextBox = new System.Windows.Forms.TextBox();
            this.FileNameLabel = new System.Windows.Forms.Label();
            this.FilesTabControl = new System.Windows.Forms.TabControl();
            this.MyFilesTabPage = new System.Windows.Forms.TabPage();
            this.CloudLocationPath = new System.Windows.Forms.TextBox();
            this.CloudLocationPicker = new System.Windows.Forms.ListView();
            this.SharedWithMeTabPage = new System.Windows.Forms.TabPage();
            this.SharedWithMeUpButton = new System.Windows.Forms.Button();
            this.SharedWithMePath = new System.Windows.Forms.TextBox();
            this.SharedWithMePicker = new System.Windows.Forms.ListView();
            this.SharedWithMeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.RefreshSharedWithMeFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.GoToSharedWithMeRootTtoolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.GoUpSharedWithMeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.SharedWithMeNotAvailableLabel = new System.Windows.Forms.Label();
            this.MyFilesContextMenu.SuspendLayout();
            this.FilesTabControl.SuspendLayout();
            this.MyFilesTabPage.SuspendLayout();
            this.SharedWithMeTabPage.SuspendLayout();
            this.SharedWithMeContextMenu.SuspendLayout();
            this.SuspendLayout();
            // 
            // MyFilesContextMenu
            // 
            this.MyFilesContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
            this.MyFilesContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.refreshToolStripMenuItem,
            this.GoToRootToolStripMenuItem,
            this.goupToolStripMenuItem,
            this.toolStripMenuItem1,
            this.newFolderToolStripMenuItem,
            this.renameToolStripMenuItem,
            this.deleteToolStripMenuItem});
            this.MyFilesContextMenu.Name = "ListViewContextMenu";
            this.MyFilesContextMenu.Size = new System.Drawing.Size(239, 202);
            this.MyFilesContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ListViewContextMenu_Opening);
            // 
            // refreshToolStripMenuItem
            // 
            this.refreshToolStripMenuItem.Name = "refreshToolStripMenuItem";
            this.refreshToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;
            this.refreshToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.refreshToolStripMenuItem.Text = "&Refresh";
            this.refreshToolStripMenuItem.Click += new System.EventHandler(this.RefreshToolStripMenuItem_Click);
            // 
            // GoToRootToolStripMenuItem
            // 
            this.GoToRootToolStripMenuItem.Name = "GoToRootToolStripMenuItem";
            this.GoToRootToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.H)));
            this.GoToRootToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.GoToRootToolStripMenuItem.Text = "&Go to root";
            this.GoToRootToolStripMenuItem.Click += new System.EventHandler(this.GoToRootToolStripMenuItem_Click);
            // 
            // goupToolStripMenuItem
            // 
            this.goupToolStripMenuItem.Enabled = false;
            this.goupToolStripMenuItem.Name = "goupToolStripMenuItem";
            this.goupToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.U)));
            this.goupToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.goupToolStripMenuItem.Text = "Go &up";
            this.goupToolStripMenuItem.Click += new System.EventHandler(this.GroupToolStripMenuItem_Click);
            // 
            // toolStripMenuItem1
            // 
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new System.Drawing.Size(235, 6);
            // 
            // newFolderToolStripMenuItem
            // 
            this.newFolderToolStripMenuItem.Name = "newFolderToolStripMenuItem";
            this.newFolderToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
            this.newFolderToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.newFolderToolStripMenuItem.Text = "&New Folder";
            this.newFolderToolStripMenuItem.Click += new System.EventHandler(this.NewFolderToolStripMenuItem_Click);
            // 
            // renameToolStripMenuItem
            // 
            this.renameToolStripMenuItem.Name = "renameToolStripMenuItem";
            this.renameToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
            this.renameToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.renameToolStripMenuItem.Text = "R&ename";
            this.renameToolStripMenuItem.Click += new System.EventHandler(this.RenameToolStripMenuItem_Click);
            // 
            // deleteToolStripMenuItem
            // 
            this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
            this.deleteToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(238, 32);
            this.deleteToolStripMenuItem.Text = "&Delete";
            this.deleteToolStripMenuItem.Click += new System.EventHandler(this.DeleteToolStripMenuItem_Click);
            // 
            // IconsList
            // 
            this.IconsList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("IconsList.ImageStream")));
            this.IconsList.TransparentColor = System.Drawing.Color.Transparent;
            this.IconsList.Images.SetKeyName(0, "File");
            this.IconsList.Images.SetKeyName(1, "Folder");
            this.IconsList.Images.SetKeyName(2, "RemoteFolder");
            // 
            // CancelButton
            // 
            this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.CancelButton.Location = new System.Drawing.Point(663, 614);
            this.CancelButton.Name = "CancelButton";
            this.CancelButton.Size = new System.Drawing.Size(108, 49);
            this.CancelButton.TabIndex = 3;
            this.CancelButton.Text = "&Cancel";
            this.CancelButton
Download .txt
gitextract_t4ju8rln/

├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── feature_request.md
│   │   └── question.md
│   ├── PULL_REQUEST_TEMPLATE/
│   │   └── PULL_REQUEST_TEMPLATE.md
│   └── auto_assign.yml
├── .gitignore
├── KeeOneDriveSync.plgx
├── KoenZomers.KeePass.OneDriveSync/
│   ├── Configuration.cs
│   ├── Enums/
│   │   ├── CloudStorageType.cs
│   │   └── OneDriveRefreshTokenStorage.cs
│   ├── Forms/
│   │   ├── AboutForm.Designer.cs
│   │   ├── AboutForm.cs
│   │   ├── AboutForm.resx
│   │   ├── OneDriveAboutForm.Designer.cs
│   │   ├── OneDriveAboutForm.cs
│   │   ├── OneDriveAboutForm.resx
│   │   ├── OneDriveAskToStartSyncingDialog.Designer.cs
│   │   ├── OneDriveAskToStartSyncingDialog.cs
│   │   ├── OneDriveAskToStartSyncingDialog.resx
│   │   ├── OneDriveAuthenticateForm.Designer.cs
│   │   ├── OneDriveAuthenticateForm.cs
│   │   ├── OneDriveAuthenticateForm.resx
│   │   ├── OneDriveCloudTypeForm.Designer.cs
│   │   ├── OneDriveCloudTypeForm.cs
│   │   ├── OneDriveCloudTypeForm.resx
│   │   ├── OneDriveConfigDetailsForm.Designer.cs
│   │   ├── OneDriveConfigDetailsForm.cs
│   │   ├── OneDriveConfigDetailsForm.resx
│   │   ├── OneDriveConfigForm.Designer.cs
│   │   ├── OneDriveConfigForm.cs
│   │   ├── OneDriveConfigForm.resx
│   │   ├── OneDriveFilePickerDialog.Designer.cs
│   │   ├── OneDriveFilePickerDialog.cs
│   │   ├── OneDriveFilePickerDialog.resx
│   │   ├── OneDriveGraphDeviceLoginForm.Designer.cs
│   │   ├── OneDriveGraphDeviceLoginForm.cs
│   │   ├── OneDriveGraphDeviceLoginForm.resx
│   │   ├── OneDriveGraphDeviceLoginForm1.Designer.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.Designer.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.cs
│   │   ├── OneDriveRefreshTokenStorageDialog.resx
│   │   ├── OneDriveRemoteLocationDialog.resx
│   │   ├── OneDriveRequestInputDialog.Designer.cs
│   │   ├── OneDriveRequestInputDialog.cs
│   │   ├── OneDriveRequestInputDialog.resx
│   │   ├── SharePointCredentialsForm.Designer.cs
│   │   ├── SharePointCredentialsForm.cs
│   │   ├── SharePointCredentialsForm.resx
│   │   ├── SharePointDocumentLibraryPickerDialog.Designer.cs
│   │   ├── SharePointDocumentLibraryPickerDialog.cs
│   │   └── SharePointDocumentLibraryPickerDialog.resx
│   ├── KeePass.exe.config
│   ├── KeePassDatabase.cs
│   ├── KoenZomers.KeePass.OneDriveSync.csproj
│   ├── KoenZomersKeePassOneDriveSyncExt.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── Providers/
│   │   ├── MicrosoftGraph/
│   │   │   ├── MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs
│   │   │   ├── MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs
│   │   │   └── MicrosoftGraphDeviceCodeResponse.cs
│   │   ├── OneDriveProvider.cs
│   │   └── SharePointProvider.cs
│   ├── Resources/
│   │   ├── MSGraph.pdn
│   │   └── SharePoint.pdn
│   ├── Resources.Designer.cs
│   ├── Resources.resx
│   ├── TokenHelper.cs
│   ├── Utilities.cs
│   ├── app.config
│   └── packages.config
├── KoenZomers.KeePass.OneDriveSync.sln
├── LICENSE.md
├── NuGet.config
├── README.md
├── create-plgx.cmd
└── version.txt
Download .txt
SYMBOL INDEX (293 symbols across 40 files)

FILE: KoenZomers.KeePass.OneDriveSync/Configuration.cs
  class Configuration (line 14) | [DataContract]
    method GetPasswordDatabaseConfiguration (line 145) | public static Configuration GetPasswordDatabaseConfiguration(string lo...
    method SetPasswordDatabaseConfiguration (line 161) | public static void SetPasswordDatabaseConfiguration(string localPasswo...
    method Load (line 170) | public static void Load()
    method Save (line 212) | public static void Save()
    method Clone (line 266) | public object Clone()
    method DeleteConfig (line 275) | public static void DeleteConfig(string localPasswordDatabasePath)
    method GetAllConfigurations (line 313) | internal static IDictionary<string, Configuration> GetAllConfigurations()
    method NormalizePath (line 334) | private static string NormalizePath(string localPasswordDatabasePath)

FILE: KoenZomers.KeePass.OneDriveSync/Enums/CloudStorageType.cs
  type CloudStorageType (line 6) | public enum CloudStorageType : short

FILE: KoenZomers.KeePass.OneDriveSync/Enums/OneDriveRefreshTokenStorage.cs
  type OneDriveRefreshTokenStorage (line 6) | public enum OneDriveRefreshTokenStorage : short

FILE: KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.Designer.cs
  class AboutForm (line 3) | partial class AboutForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.cs
  class AboutForm (line 6) | public partial class AboutForm : Form
    method AboutForm (line 8) | public AboutForm()
    method CloseButton_Click (line 17) | private void CloseButton_Click(object sender, System.EventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.Designer.cs
  class OneDriveAboutForm (line 3) | partial class OneDriveAboutForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.cs
  class OneDriveAboutForm (line 10) | public partial class OneDriveAboutForm : Form
    method OneDriveAboutForm (line 12) | public OneDriveAboutForm()
    method CloseButton_Click (line 21) | private void CloseButton_Click(object sender, EventArgs e)
    method WebsiteLinkLabel_Click (line 26) | private void WebsiteLinkLabel_Click(object sender, EventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.Designer.cs
  class OneDriveAskToStartSyncingDialog (line 3) | partial class OneDriveAskToStartSyncingDialog
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.cs
  class OneDriveAskToStartSyncingDialog (line 7) | public partial class OneDriveAskToStartSyncingDialog : Form
    method OneDriveAskToStartSyncingDialog (line 14) | public OneDriveAskToStartSyncingDialog(Configuration configuration)
    method OKButton_Click (line 23) | private void OKButton_Click(object sender, EventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.Designer.cs
  class OneDriveAuthenticateForm (line 3) | partial class OneDriveAuthenticateForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.cs
  class OneDriveAuthenticateForm (line 6) | public partial class OneDriveAuthenticateForm : Form
    method OneDriveAuthenticateForm (line 13) | public OneDriveAuthenticateForm(OneDriveApi oneDriveApi)
    method SignOut (line 26) | public void SignOut()
    method WebBrowser_Navigated (line 33) | private async void WebBrowser_Navigated(object sender, WebBrowserNavig...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.Designer.cs
  class OneDriveCloudTypeForm (line 3) | partial class OneDriveCloudTypeForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.cs
  class OneDriveCloudTypeForm (line 7) | public partial class OneDriveCloudTypeForm : Form
    method OneDriveCloudTypeForm (line 23) | public OneDriveCloudTypeForm()
    method OneDriveConsumerPicture_Click (line 32) | private void OneDriveConsumerPicture_Click(object sender, EventArgs e)
    method OneDriveConsumerPictureButton_Click (line 40) | private void OneDriveConsumerPictureButton_Click(object sender, EventA...
    method GraphPictureButton_Click (line 48) | private void GraphPictureButton_Click(object sender, EventArgs e)
    method SharePointPictureButton_Click (line 56) | private void SharePointPictureButton_Click(object sender, EventArgs e)
    method CancelButton_Click (line 64) | private void CancelButton_Click(object sender, EventArgs e)
    method GraphDeviceLoginPictureButton_Click (line 69) | private void GraphDeviceLoginPictureButton_Click(object sender, EventA...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.Designer.cs
  class OneDriveConfigDetailsForm (line 3) | partial class OneDriveConfigDetailsForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.cs
  class OneDriveConfigDetailsForm (line 12) | public partial class OneDriveConfigDetailsForm : Form
    method OneDriveConfigDetailsForm (line 20) | public OneDriveConfigDetailsForm(KeyValuePair<string, Configuration> c...
    method OneDriveConfigDetailsForm_Load (line 27) | private void OneDriveConfigDetailsForm_Load(object sender, EventArgs e)
    method ShowConfiguration (line 32) | private void ShowConfiguration()
    method CloseButton_Click (line 54) | private void CloseButton_Click(object sender, EventArgs e)
    method DeleteButton_Click (line 59) | private void DeleteButton_Click(object sender, EventArgs e)
    method ForceSyncButton_Click (line 69) | private async void ForceSyncButton_Click(object sender, EventArgs e)
    method UpdateStatus (line 82) | private void UpdateStatus(string message)
    method OneDriveConfigDetailsForm_KeyUp (line 87) | private void OneDriveConfigDetailsForm_KeyUp(object sender, KeyEventAr...
    method LocalDatabasePathLinkLabel_LinkClicked (line 95) | private void LocalDatabasePathLinkLabel_LinkClicked(object sender, Lin...
    method ItemIdLabel_Click (line 116) | private void ItemIdLabel_Click(object sender, EventArgs e)
    method ItemIdTextBox_TextChanged (line 121) | private void ItemIdTextBox_TextChanged(object sender, EventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.Designer.cs
  class OneDriveConfigForm (line 3) | partial class OneDriveConfigForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.cs
  class OneDriveConfigForm (line 15) | public partial class OneDriveConfigForm : Form
    method OneDriveConfigForm (line 27) | public OneDriveConfigForm()
    method OneDriveConfigForm_Load (line 35) | private void OneDriveConfigForm_Load(object sender, EventArgs e)
    method LoadConfigurations (line 43) | private void LoadConfigurations()
    method CloseButton_Click (line 73) | private void CloseButton_Click(object sender, EventArgs e)
    method ConfigurationListViewContextItemDelete_Click (line 78) | private void ConfigurationListViewContextItemDelete_Click(object sende...
    method ConfigurationListViewContextMenu_Opening (line 83) | private void ConfigurationListViewContextMenu_Opening(object sender, S...
    method ConfigurationListView_DoubleClick (line 93) | private void ConfigurationListView_DoubleClick(object sender, EventArg...
    method ConfigurationListViewContextItemViewDetails_Click (line 98) | private void ConfigurationListViewContextItemViewDetails_Click(object ...
    method DeleteItem (line 103) | private void DeleteItem()
    method ViewDetails (line 118) | private void ViewDetails()
    method RenameEntry (line 128) | private void RenameEntry()
    method SyncNow (line 158) | private async Task SyncNow()
    method ConfigurationListViewContextItemSyncNow_Click (line 185) | private async void ConfigurationListViewContextItemSyncNow_Click(objec...
    method UpdateStatus (line 190) | private void UpdateStatus(string message)
    method AboutButton_Click (line 201) | private void AboutButton_Click(object sender, EventArgs e)
    method ConfigurationListView_KeyUp (line 207) | private void ConfigurationListView_KeyUp(object sender, KeyEventArgs e)
    method ConfigurationListViewContextItemOpenFileLocation_Click (line 212) | private void ConfigurationListViewContextItemOpenFileLocation_Click(ob...
    method ConfigurationListViewContextItemRenameStorage_Click (line 224) | private void ConfigurationListViewContextItemRenameStorage_Click(objec...
    method ConfigurationListViewContextItemOpenDatabase_Click (line 229) | private void ConfigurationListViewContextItemOpenDatabase_Click(object...
    method ConfigurationListViewContextItemRefresh_Click (line 242) | private void ConfigurationListViewContextItemRefresh_Click(object send...
    method ConfigurationListViewContextItemSelectAll_Click (line 247) | private void ConfigurationListViewContextItemSelectAll_Click(object se...
    method ConfigurationListViewContextItemSelectNotAvailableLocally_Click (line 255) | private void ConfigurationListViewContextItemSelectNotAvailableLocally...
    method ConfigurationListViewContextItemSelectNotSynced24Hours_Click (line 263) | private void ConfigurationListViewContextItemSelectNotSynced24Hours_Cl...
    method ConfigurationListViewContextItemSelectNotSyncedWeek_Click (line 272) | private void ConfigurationListViewContextItemSelectNotSyncedWeek_Click...
    method ConfigurationListViewContextItemSelectNotSynced2Weeks_Click (line 281) | private void ConfigurationListViewContextItemSelectNotSynced2Weeks_Cli...
    method ConfigurationListViewContextItemSelectNotSyncedMonth_Click (line 290) | private void ConfigurationListViewContextItemSelectNotSyncedMonth_Clic...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.Designer.cs
  class OneDriveFilePickerDialog (line 3) | partial class OneDriveFilePickerDialog
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.cs
  class OneDriveFilePickerDialog (line 10) | public partial class OneDriveFilePickerDialog : Form
    method OneDriveFilePickerDialog (line 62) | public OneDriveFilePickerDialog(OneDriveApi oneDriveApi)
    method LoadFolderItems (line 79) | public async Task LoadFolderItems(string parentItemId = null)
    method LoadSharedWithMeItems (line 143) | public async Task LoadSharedWithMeItems(OneDriveItem parentItem = null)
    method CloudLocationPicker_DoubleClick (line 277) | private async void CloudLocationPicker_DoubleClick(object sender, Even...
    method UpButton_Click (line 291) | private async void UpButton_Click(object sender, EventArgs e)
    method RefreshToolStripMenuItem_Click (line 297) | private async void RefreshToolStripMenuItem_Click(object sender, Event...
    method OneDriveFileSaveAsDialog_KeyUp (line 302) | private void OneDriveFileSaveAsDialog_KeyUp(object sender, KeyEventArg...
    method OKButton_Click (line 310) | private void OKButton_Click(object sender, EventArgs e)
    method CloudLocationPicker_ItemSelectionChanged (line 316) | private void CloudLocationPicker_ItemSelectionChanged(object sender, L...
    method GoToRootToolStripMenuItem_Click (line 327) | private async void GoToRootToolStripMenuItem_Click(object sender, Even...
    method ListViewContextMenu_Opening (line 332) | private void ListViewContextMenu_Opening(object sender, System.Compone...
    method OneDriveFileSaveAsDialog_Load (line 337) | private void OneDriveFileSaveAsDialog_Load(object sender, EventArgs e)
    method NewFolderToolStripMenuItem_Click (line 342) | private async void NewFolderToolStripMenuItem_Click(object sender, Eve...
    method DeleteToolStripMenuItem_Click (line 363) | private async void DeleteToolStripMenuItem_Click(object sender, EventA...
    method FileNameTextBox_TextChanged (line 383) | private void FileNameTextBox_TextChanged(object sender, EventArgs e)
    method RenameToolStripMenuItem_Click (line 388) | private async void RenameToolStripMenuItem_Click(object sender, EventA...
    method GroupToolStripMenuItem_Click (line 421) | private void GroupToolStripMenuItem_Click(object sender, EventArgs e)
    method UpButton_EnabledChanged (line 426) | private void UpButton_EnabledChanged(object sender, EventArgs e)
    method CloudLocationPicker_KeyUp (line 431) | private void CloudLocationPicker_KeyUp(object sender, KeyEventArgs e)
    method FileNameTextBox_KeyUp (line 439) | private void FileNameTextBox_KeyUp(object sender, KeyEventArgs e)
    method FilesTabControl_SelectedIndexChanged (line 447) | private async void FilesTabControl_SelectedIndexChanged(object sender,...
    method RefreshSharedWithMeFilesToolStripMenuItem_Click (line 468) | private async void RefreshSharedWithMeFilesToolStripMenuItem_Click(obj...
    method SharedWithMePicker_DoubleClick (line 473) | private async void SharedWithMePicker_DoubleClick(object sender, Event...
    method SharedWithMePicker_KeyUp (line 487) | private void SharedWithMePicker_KeyUp(object sender, KeyEventArgs e)
    method SharedWithMeUpButton_Click (line 495) | private async void SharedWithMeUpButton_Click(object sender, EventArgs e)
    method GoToSharedWithMeRootTtoolStripMenuItem_Click (line 501) | private async void GoToSharedWithMeRootTtoolStripMenuItem_Click(object...
    method GoUpSharedWithMeToolStripMenuItem_Click (line 506) | private async void GoUpSharedWithMeToolStripMenuItem_Click(object send...
    method SharedWithMeContextMenu_Opening (line 511) | private void SharedWithMeContextMenu_Opening(object sender, System.Com...
    method SharedWithMePicker_ItemSelectionChanged (line 516) | private void SharedWithMePicker_ItemSelectionChanged(object sender, Li...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.Designer.cs
  class OneDriveGraphDeviceLoginForm (line 3) | partial class OneDriveGraphDeviceLoginForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.cs
  class OneDriveGraphDeviceLoginForm (line 14) | public partial class OneDriveGraphDeviceLoginForm : Form
    method OneDriveGraphDeviceLoginForm (line 61) | public OneDriveGraphDeviceLoginForm(OneDriveApi oneDriveApi)
    method OneDriveGraphDeviceLoginForm_FormClosing (line 93) | private void OneDriveGraphDeviceLoginForm_FormClosing(object sender, F...
    method GetMicrosoftGraphDeviceId (line 112) | private void GetMicrosoftGraphDeviceId()
    method TryParseJson (line 185) | public static bool TryParseJson<T>(string json, out T result)
    method HasUserAuthenticated (line 201) | private string HasUserAuthenticated()
    method CreateHttpClient (line 271) | private HttpClient CreateHttpClient()
    method CancelButton_Click (line 295) | private void CancelButton_Click(object sender, EventArgs e)
    method StartSessionTimer_Tick (line 305) | private void StartSessionTimer_Tick(object sender, EventArgs e)
    method AuthenticationCheckTimer_Tick (line 317) | private void AuthenticationCheckTimer_Tick(object sender, EventArgs e)
    method CopyDeviceIdButton_Click (line 353) | private void CopyDeviceIdButton_Click(object sender, EventArgs e)
    method OpenBrowserButton_Click (line 360) | private void OpenBrowserButton_Click(object sender, EventArgs e)
    method DeviceAuthLinkLabel_LinkClicked (line 367) | private void DeviceAuthLinkLabel_LinkClicked(object sender, LinkLabelL...
    method OneDriveGraphDeviceLoginForm_FormClosed (line 374) | private void OneDriveGraphDeviceLoginForm_FormClosed(object sender, Fo...
    method AuthenticationCompleteTimer_Tick (line 382) | private void AuthenticationCompleteTimer_Tick(object sender, EventArgs e)
    method MoreInformationLinkLabel_LinkClicked (line 388) | private void MoreInformationLinkLabel_LinkClicked(object sender, LinkL...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm1.Designer.cs
  class OneDriveGraphDeviceLoginForm (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method OneDriveGraphDeviceLoginForm (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.Designer.cs
  class OneDriveRefreshTokenStorageDialog (line 3) | partial class OneDriveRefreshTokenStorageDialog
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.cs
  class OneDriveRefreshTokenStorageDialog (line 8) | public partial class OneDriveRefreshTokenStorageDialog : Form
    method OneDriveRefreshTokenStorageDialog (line 15) | public OneDriveRefreshTokenStorageDialog(Configuration configuration)
    method HelpMeChooseLinkLabel_LinkClicked (line 22) | private void HelpMeChooseLinkLabel_LinkClicked(object sender, LinkLabe...
    method FinishButton_Click (line 27) | private void FinishButton_Click(object sender, EventArgs e)
    method OneDriveRefreshTokenStorageDialog_FormClosing (line 32) | private void OneDriveRefreshTokenStorageDialog_FormClosing(object send...

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.Designer.cs
  class OneDriveRequestInputDialog (line 3) | partial class OneDriveRequestInputDialog
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.cs
  class OneDriveRequestInputDialog (line 6) | public partial class OneDriveRequestInputDialog : Form
    method OneDriveRequestInputDialog (line 26) | public OneDriveRequestInputDialog()
    method OKButton_Click (line 31) | private void OKButton_Click(object sender, EventArgs e)
    method CancelButton_Click (line 37) | private void CancelButton_Click(object sender, EventArgs e)
    method InputTextBoxTextBox_TextChanged (line 42) | private void InputTextBoxTextBox_TextChanged(object sender, EventArgs e)
    method InputTextBox_KeyPress (line 47) | private void InputTextBox_KeyPress(object sender, KeyPressEventArgs e)
    method InputTextBox_KeyUp (line 52) | private void InputTextBox_KeyUp(object sender, KeyEventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.Designer.cs
  class SharePointCredentialsForm (line 3) | partial class SharePointCredentialsForm
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.cs
  class SharePointCredentialsForm (line 7) | public partial class SharePointCredentialsForm : Form
    method SharePointCredentialsForm (line 32) | public SharePointCredentialsForm()
    method OKButton_Click (line 40) | private void OKButton_Click(object sender, EventArgs e)
    method EnsureAllFieldsEntered (line 53) | private bool EnsureAllFieldsEntered()
    method TestButton_Click (line 67) | private async void TestButton_Click(object sender, EventArgs e)
    method SharePointUrlTextBox_KeyUp (line 109) | private void SharePointUrlTextBox_KeyUp(object sender, KeyEventArgs e)
    method CancelButton_Click (line 126) | private void CancelButton_Click(object sender, EventArgs e)
    method SharePointUrlTextBox_TextChanged (line 131) | private void SharePointUrlTextBox_TextChanged(object sender, EventArgs e)
    method ClientIdTextBox_KeyUp (line 136) | private void ClientIdTextBox_KeyUp(object sender, KeyEventArgs e)
    method ClientSecretTextBox_KeyUp (line 141) | private void ClientSecretTextBox_KeyUp(object sender, KeyEventArgs e)

FILE: KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.Designer.cs
  class SharePointDocumentLibraryPickerDialog (line 3) | partial class SharePointDocumentLibraryPickerDialog
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.cs
  class SharePointDocumentLibraryPickerDialog (line 9) | public partial class SharePointDocumentLibraryPickerDialog : System.Wind...
    method SharePointDocumentLibraryPickerDialog (line 67) | public SharePointDocumentLibraryPickerDialog(HttpClient httpClient)
    method LoadDocumentLibraryItems (line 77) | public async Task LoadDocumentLibraryItems()
    method LoadDocumentLibraryFileAndFolderItems (line 119) | public async Task LoadDocumentLibraryFileAndFolderItems(string serverR...
    method SharePointDocumentLibraryPicker_DoubleClick (line 226) | private async void SharePointDocumentLibraryPicker_DoubleClick(object ...
    method OKButton_Click (line 251) | private void OKButton_Click(object sender, EventArgs e)
    method SharePointDocumentLibraryPicker_SelectedIndexChanged (line 269) | private void SharePointDocumentLibraryPicker_SelectedIndexChanged(obje...
    method showHiddenLibrariesToolStripMenuItem_Click (line 283) | private void showHiddenLibrariesToolStripMenuItem_Click(object sender,...
    method refreshToolStripMenuItem_Click (line 291) | private async void refreshToolStripMenuItem_Click(object sender, Event...
    method UpButton_Click (line 303) | private async void UpButton_Click(object sender, EventArgs e)
    method goToRootToolStripMenuItem_Click (line 316) | private async void goToRootToolStripMenuItem_Click(object sender, Even...
    method goupToolStripMenuItem_Click (line 321) | private void goupToolStripMenuItem_Click(object sender, EventArgs e)
    method FileNameTextBox_KeyUp (line 326) | private void FileNameTextBox_KeyUp(object sender, KeyEventArgs e)
    method newFoldertoolStripMenuItem_Click (line 334) | private async void newFoldertoolStripMenuItem_Click(object sender, Eve...
    method deleteToolStripMenuItem_Click (line 357) | private async void deleteToolStripMenuItem_Click(object sender, EventA...
    method renameToolStripMenuItem_Click (line 394) | private async void renameToolStripMenuItem_Click(object sender, EventA...

FILE: KoenZomers.KeePass.OneDriveSync/KeePassDatabase.cs
  class KeePassDatabase (line 14) | public static class KeePassDatabase
    method OpenDatabaseFromCloudService (line 20) | public static async Task OpenDatabaseFromCloudService(Action<string> u...
    method SyncDatabase (line 87) | public static async Task SyncDatabase(string localKeePassDatabasePath,...
    method AskIfShouldBeSynced (line 191) | private static CloudStorageType? AskIfShouldBeSynced(Configuration dat...
    method MergeDatabases (line 224) | public static bool MergeDatabases(Configuration databaseConfig, string...
    method UpdateStatus (line 248) | public static void UpdateStatus(string message)

FILE: KoenZomers.KeePass.OneDriveSync/KoenZomersKeePassOneDriveSyncExt.cs
  class KoenZomersKeePassOneDriveSyncExt (line 14) | public class KoenZomersKeePassOneDriveSyncExt : Plugin
    method Initialize (line 91) | public override bool Initialize(IPluginHost pluginHost)
    method Terminate (line 148) | public override void Terminate()
    method OnKeePassDatabaseClosing (line 171) | private void OnKeePassDatabaseClosing(object sender, FileClosingEventA...
    method MainWindowOnFileSaved (line 192) | private async void MainWindowOnFileSaved(object sender, FileSavedEvent...
    method MenuOptionsOnClick (line 229) | private static void MenuOptionsOnClick(object sender, EventArgs e)
    method MenuFileOpenFromOneDriveOnClick (line 238) | private async static void MenuFileOpenFromOneDriveOnClick(object sende...
    method MenuFileOneDriveSyncOfflineOnClick (line 246) | private void MenuFileOneDriveSyncOfflineOnClick(object sender, EventAr...
    method OnKeePassDatabaseOpened (line 255) | private async void OnKeePassDatabaseOpened(object sender, FileOpenedEv...
    method OnKeePassDatabaseClosed (line 290) | private static void OnKeePassDatabaseClosed(object sender, FileClosedE...

FILE: KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs
  class MicrosoftGraphDeviceCodeAuthCheckFailedResponse (line 9) | public class MicrosoftGraphDeviceCodeAuthCheckFailedResponse

FILE: KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs
  class MicrosoftGraphDeviceCodeAuthCheckSucceededResponse (line 8) | public class MicrosoftGraphDeviceCodeAuthCheckSucceededResponse

FILE: KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeResponse.cs
  class MicrosoftGraphDeviceCodeResponse (line 9) | public class MicrosoftGraphDeviceCodeResponse

FILE: KoenZomers.KeePass.OneDriveSync/Providers/OneDriveProvider.cs
  class OneDriveProvider (line 11) | internal static class OneDriveProvider
    method SyncUsingOneDriveCloudProvider (line 21) | public static async Task<bool> SyncUsingOneDriveCloudProvider(Configur...
    method OpenFromOneDriveCloudProvider (line 360) | public static async Task<string> OpenFromOneDriveCloudProvider(Configu...

FILE: KoenZomers.KeePass.OneDriveSync/Providers/SharePointProvider.cs
  class SharePointProvider (line 12) | internal static class SharePointProvider
    method SyncUsingSharePointPlatform (line 22) | public static async Task<bool> SyncUsingSharePointPlatform(Configurati...
    method GetEtagOfFile (line 148) | public static async Task<string> GetEtagOfFile(HttpClient httpClient, ...
    method UploadFile (line 183) | public static async Task<string> UploadFile(string localDatabasePath, ...
    method DownloadFile (line 280) | public static async Task<bool> DownloadFile(string localDatabasePath, ...
    method DeleteFile (line 309) | public static async Task<bool> DeleteFile(string serverRelativeFilePat...
    method DeleteFolder (line 361) | public static async Task<bool> DeleteFolder(string serverRelativeFolde...
    method RenameFolder (line 414) | public static async Task<bool> RenameFolder(string newFolderName, stri...
    method RenameFile (line 473) | public static async Task<bool> RenameFile(string newFileName, string s...
    method CreateFolder (line 529) | public static async Task<string> CreateFolder(string folderName, strin...
    method GetFormDigest (line 583) | public static async Task<string> GetFormDigest(HttpClient httpClient)
    method CreateSharePointHttpClient (line 621) | public static HttpClient CreateSharePointHttpClient(Configuration data...
    method CreateSharePointHttpClient (line 638) | public static HttpClient CreateSharePointHttpClient(Uri sharePointUri,...
    method RequestSharePointDetails (line 677) | private static bool RequestSharePointDetails(Configuration databaseCon...
    method TestConnection (line 700) | public static async Task<bool> TestConnection(HttpClient httpClient, C...
    method EnsureSharePointCredentials (line 747) | public static async Task<bool> EnsureSharePointCredentials(Configurati...
    method OpenFromSharePoint (line 811) | public static async Task<string> OpenFromSharePoint(Configuration data...

FILE: KoenZomers.KeePass.OneDriveSync/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: KoenZomers.KeePass.OneDriveSync/TokenHelper.cs
  class TokenHelper (line 27) | public static class TokenHelper
    method GetContextTokenFromRequest (line 51) | public static string GetContextTokenFromRequest(HttpRequest request)
    method GetContextTokenFromRequest (line 62) | public static string GetContextTokenFromRequest(HttpRequestBase request)
    method GetAccessToken (line 86) | public static OAuth2AccessTokenResponse GetAccessToken(SharePointConte...
    method GetAccessToken (line 117) | public static OAuth2AccessTokenResponse GetAccessToken(
    method GetAccessToken (line 191) | public static OAuth2AccessTokenResponse GetAccessToken(
    method GetAppOnlyAccessToken (line 249) | public static OAuth2AccessTokenResponse GetAppOnlyAccessToken(
    method GetAuthorizationUrl (line 321) | public static string GetAuthorizationUrl(string contextUrl, string scope)
    method GetAuthorizationUrl (line 341) | public static string GetAuthorizationUrl(string contextUrl, string sco...
    method GetAppContextTokenRequestUrl (line 358) | public static string GetAppContextTokenRequestUrl(string contextUrl, s...
    method GetS2SAccessTokenWithWindowsIdentity (line 376) | public static string GetS2SAccessTokenWithWindowsIdentity(
    method GetRealmFromTargetUrl (line 392) | public static string GetRealmFromTargetUrl(Uri targetApplicationUri)
    method IsHighTrustApp (line 445) | public static bool IsHighTrustApp()
    method EnsureTrailingSlash (line 455) | public static string EnsureTrailingSlash(string url)
    method GetAcsMetadataEndpointUrl (line 511) | private static string GetAcsMetadataEndpointUrl()
    method GetFormattedPrincipal (line 516) | private static string GetFormattedPrincipal(string principalName, stri...
    method GetAcsPrincipalName (line 526) | private static string GetAcsPrincipalName(string realm)
    method GetAcsGlobalEndpointUrl (line 531) | private static string GetAcsGlobalEndpointUrl()
    method CreateJsonWebSecurityTokenHandler (line 536) | private static JsonWebSecurityTokenHandler CreateJsonWebSecurityTokenH...
    method GetS2SAccessTokenWithClaims (line 566) | private static string GetS2SAccessTokenWithClaims(
    method GetClaimsWithWindowsIdentity (line 583) | private static JsonWebTokenClaim[] GetClaimsWithWindowsIdentity(Window...
    method IssueToken (line 593) | private static string IssueToken(
    class AcsMetadataParser (line 666) | public static class AcsMetadataParser
      method GetAcsSigningCert (line 668) | public static X509Certificate2 GetAcsSigningCert(string realm)
      method GetDelegationServiceUrl (line 685) | public static string GetDelegationServiceUrl(string realm)
      method GetMetadataDocument (line 698) | private static JsonMetadataDocument GetMetadataDocument(string realm)
      method GetStsUrl (line 722) | public static string GetStsUrl(string realm)
      class JsonMetadataDocument (line 736) | private class JsonMetadataDocument
      class JsonEndpoint (line 743) | private class JsonEndpoint
      class JsonKeyValue (line 750) | private class JsonKeyValue
      class JsonKey (line 756) | private class JsonKey
  class SharePointContextToken (line 769) | public class SharePointContextToken : JsonWebSecurityToken
    method Create (line 771) | public static SharePointContextToken Create(JsonWebSecurityToken conte...
    method SharePointContextToken (line 776) | public SharePointContextToken(string issuer, string audience, DateTime...
    method SharePointContextToken (line 781) | public SharePointContextToken(string issuer, string audience, DateTime...
    method SharePointContextToken (line 786) | public SharePointContextToken(string issuer, string audience, DateTime...
    method GetClaimValue (line 847) | private static string GetClaimValue(JsonWebSecurityToken token, string...
  class MultipleSymmetricKeySecurityToken (line 870) | public class MultipleSymmetricKeySecurityToken : SecurityToken
    method MultipleSymmetricKeySecurityToken (line 876) | public MultipleSymmetricKeySecurityToken(IEnumerable<byte[]> keys)
    method MultipleSymmetricKeySecurityToken (line 886) | public MultipleSymmetricKeySecurityToken(string tokenId, IEnumerable<b...
    method MatchesKeyIdentifierClause (line 961) | public override bool MatchesKeyIdentifierClause(SecurityKeyIdentifierC...
    method CreateSymmetricSecurityKeys (line 980) | private List<SecurityKey> CreateSymmetricSecurityKeys(IEnumerable<byte...

FILE: KoenZomers.KeePass.OneDriveSync/Utilities.cs
  class Utilities (line 18) | public static class Utilities
    method GetDatabaseFileHash (line 27) | public static string GetDatabaseFileHash(string localKeePassDatabasePath)
    method GetOneDriveApi (line 48) | public static async Task<OneDriveApi> GetOneDriveApi(Configuration dat...
    method GetProxySettings (line 146) | public static IWebProxy GetProxySettings()
    method GetProxyCredentials (line 173) | public static NetworkCredential GetProxyCredentials()
    method ApplyProxySettings (line 183) | public static void ApplyProxySettings(OneDriveApi oneDriveApi)
    method SaveRefreshTokenInWindowsCredentialManager (line 201) | public static void SaveRefreshTokenInWindowsCredentialManager(string d...
    method GetRefreshTokenFromWindowsCredentialManager (line 230) | public static string GetRefreshTokenFromWindowsCredentialManager(strin...
    method DeleteRefreshTokenFromWindowsCredentialManager (line 245) | public static void DeleteRefreshTokenFromWindowsCredentialManager(stri...
    method SaveRefreshTokenInKeePassDatabase (line 267) | public static void SaveRefreshTokenInKeePassDatabase(PwDatabase keePas...
    method GetRefreshTokenFromKeePassDatabase (line 277) | public static string GetRefreshTokenFromKeePassDatabase(PwDatabase kee...
    method Protect (line 292) | public static string Protect(string refreshToken)
    method Unprotect (line 319) | public static string Unprotect(string encryptedRefreshToken)
Condensed preview — 77 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (768K chars).
[
  {
    "path": ".gitattributes",
    "chars": 2518,
    "preview": "###############################################################################\n# Set default behavior to automatically "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 909,
    "preview": "---\nname: Bug report\nabout: If you believe something is not working well\ntitle: \"[BUG] Brief description\"\nlabels: need t"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 187,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Author\n    url: koen@zomers.eu\n    about: If you want to share feed"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 646,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for the plugin\ntitle: \"[FEATURE REQUEST] Brief description\"\nlabels: nee"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 722,
    "preview": "---\nname: Question\nabout: If you have a question regarding this project\ntitle: \"[QUESTION] Brief description\"\nlabels: ne"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md",
    "chars": 231,
    "preview": "## Type ##\n- [ ] Bug Fix\n- [ ] New Feature\n- [ ] Sample\n\n## Related Issues? ##\nFixes #X, partially fixes #Y, mentioned i"
  },
  {
    "path": ".github/auto_assign.yml",
    "chars": 702,
    "preview": "# Set to true to add reviewers to pull requests\naddReviewers: true\n\n# Set to true to add assignees to pull requests\naddA"
  },
  {
    "path": ".gitignore",
    "chars": 3161,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Configuration.cs",
    "chars": 16381,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.Serialization;\nusing System.Win"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Enums/CloudStorageType.cs",
    "chars": 735,
    "preview": "namespace KoenZomers.KeePass.OneDriveSync.Enums\n{\n    /// <summary>\n    /// Defines the types of cloud storage that can"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Enums/OneDriveRefreshTokenStorage.cs",
    "chars": 880,
    "preview": "namespace KoenZomers.KeePass.OneDriveSync.Enums\n{\n    /// <summary>\n    /// Defines the possible storage locations for "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.Designer.cs",
    "chars": 6034,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class AboutForm\n    {\n        /// <summary>\n        /// Required "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.cs",
    "chars": 588,
    "preview": "using System.Reflection;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partial clas"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/AboutForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.Designer.cs",
    "chars": 7153,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveAboutForm\n    {\n        /// <summary>\n        /// R"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.cs",
    "chars": 839,
    "preview": "using System;\nusing System.Reflection;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    /// <"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAboutForm.resx",
    "chars": 6108,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.Designer.cs",
    "chars": 8653,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n {\n     partial class OneDriveAskToStartSyncingDialog\n     {\n         /// <sum"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.cs",
    "chars": 1227,
    "preview": "using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\n\nnamespace KoenZomersKeePassOneDriveS"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAskToStartSyncingDialog.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.Designer.cs",
    "chars": 2722,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveAuthenticateForm\n    {\n        /// <summary>\n      "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.cs",
    "chars": 2054,
    "preview": "using System.Windows.Forms;\nusing KoenZomers.OneDrive.Api;\n\nnamespace KoenZomersKeePassOneDriveSync\n{\n    public partia"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveAuthenticateForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.Designer.cs",
    "chars": 10322,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveCloudTypeForm\n    {\n        /// <summary>\n        /"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.cs",
    "chars": 2285,
    "preview": "using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\n\nnamespace KoenZomersKeePassOneD"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveCloudTypeForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.Designer.cs",
    "chars": 30769,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveConfigDetailsForm\n    {\n        /// <summary>\n     "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.cs",
    "chars": 5983,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\nusin"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigDetailsForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.Designer.cs",
    "chars": 25468,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveConfigForm\n    {\n        /// <summary>\n        /// "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.cs",
    "chars": 13780,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveConfigForm.resx",
    "chars": 5913,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.Designer.cs",
    "chars": 28021,
    "preview": "namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class OneDriveFilePickerDialog\n    {\n        /// <summary>\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.cs",
    "chars": 24463,
    "preview": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing KoenZomers.OneDrive.Ap"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveFilePickerDialog.resx",
    "chars": 83409,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.Designer.cs",
    "chars": 13272,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveGraphDeviceLoginForm\n    {\n        /// <summary>\n  "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.cs",
    "chars": 17542,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Windows.Forms;\nu"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm.resx",
    "chars": 6982,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveGraphDeviceLoginForm1.Designer.cs",
    "chars": 5059,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.Designer.cs",
    "chars": 7232,
    "preview": "namespace KoenZomersKeePassOneDriveSync\n{\n    partial class OneDriveRefreshTokenStorageDialog\n    {\n        /// <summar"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.cs",
    "chars": 1449,
    "preview": "using System;\nusing System.Windows.Forms;\nusing KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync."
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRefreshTokenStorageDialog.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRemoteLocationDialog.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.Designer.cs",
    "chars": 4829,
    "preview": "namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class OneDriveRequestInputDialog\n    {\n        /// <summary"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.cs",
    "chars": 1456,
    "preview": "using System;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n{\n    public partial class One"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/OneDriveRequestInputDialog.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.Designer.cs",
    "chars": 10920,
    "preview": "namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class SharePointCredentialsForm\n    {\n        /// <summary>"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.cs",
    "chars": 5493,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace KoenZomersKeePassOneDriveSync.Forms\n"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointCredentialsForm.resx",
    "chars": 5696,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.Designer.cs",
    "chars": 17784,
    "preview": "namespace KoenZomersKeePassOneDriveSync.Forms\n{\n    partial class SharePointDocumentLibraryPickerDialog\n    {\n        /"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.cs",
    "chars": 19660,
    "preview": "using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Newtonsoft.Json.Li"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Forms/SharePointDocumentLibraryPickerDialog.resx",
    "chars": 76486,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KeePass.exe.config",
    "chars": 736,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n\t<startup>\n\t\t<supportedRuntime version=\"v4.5\" />\n\t\t<supportedRun"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KeePassDatabase.cs",
    "chars": 12741,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing KeePass.DataExchange;\nusing KeePassLib.Se"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KoenZomers.KeePass.OneDriveSync.csproj",
    "chars": 12184,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.micros"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/KoenZomersKeePassOneDriveSyncExt.cs",
    "chars": 13062,
    "preview": "using System;\nusing System.Windows.Forms;\nusing KeePass.Forms;\nusing KeePass.Plugins;\nusing KoenZomers.KeePass.OneDrive"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Properties/AssemblyInfo.cs",
    "chars": 1436,
    "preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled "
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckFailedResponse.cs",
    "chars": 1876,
    "preview": "using Newtonsoft.Json;\nusing System;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summa"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeAuthCheckSucceededResponse.cs",
    "chars": 1645,
    "preview": "using Newtonsoft.Json;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summary>\n    /// Re"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/MicrosoftGraph/MicrosoftGraphDeviceCodeResponse.cs",
    "chars": 2077,
    "preview": "using Newtonsoft.Json;\nusing System;\n\nnamespace KoenZomersKeePassOneDriveSync.Providers.MicrosoftGraph\n{\n    /// <summa"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/OneDriveProvider.cs",
    "chars": 28522,
    "preview": "using KoenZomers.KeePass.OneDriveSync;\nusing KoenZomers.KeePass.OneDriveSync.Enums;\nusing KoenZomers.OneDrive.Api;\nusin"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Providers/SharePointProvider.cs",
    "chars": 43017,
    "preview": "using KoenZomers.KeePass.OneDriveSync;\nusing Newtonsoft.Json.Linq;\nusing System;\nusing System.Net.Http;\nusing System.Ne"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Resources.Designer.cs",
    "chars": 5822,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code w"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Resources.resx",
    "chars": 7823,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/TokenHelper.cs",
    "chars": 41501,
    "preview": "using Microsoft.IdentityModel;\nusing Microsoft.IdentityModel.SecurityTokenService;\nusing Microsoft.IdentityModel.S2S.Pro"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/Utilities.cs",
    "chars": 15456,
    "preview": "using System;\nusing System.IO;\nusing System.Net;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Th"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/app.config",
    "chars": 420,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-co"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync/packages.config",
    "chars": 418,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"KoenZomers.OneDrive.Api\" version=\"2.3.0.3\" targetFrame"
  },
  {
    "path": "KoenZomers.KeePass.OneDriveSync.sln",
    "chars": 3883,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.0.3190"
  },
  {
    "path": "LICENSE.md",
    "chars": 11514,
    "preview": "Eclipse Public License - v 1.0\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC\nLICENSE (\"AG"
  },
  {
    "path": "NuGet.config",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <config>\n    <add key=\"repositoryPath\" value=\"./KoenZomers.Kee"
  },
  {
    "path": "README.md",
    "chars": 5399,
    "preview": "# KeePass OneDrive Sync\n\n> Notice: Through the years I have enjoyed building and maintaining this code. I have been surp"
  },
  {
    "path": "create-plgx.cmd",
    "chars": 406,
    "preview": "ECHO Creating KeePass plugin package\nset PLUGIN_NAME=KeeOneDriveSync\nset SourceFolder=KoenZomers.KeePass.OneDriveSync\nrd"
  },
  {
    "path": "version.txt",
    "chars": 43,
    "preview": ":\nKoenZomers.KeePass.OneDriveSync:2.1.2.2\n:"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the KoenZomers/KeePassOneDriveSync GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 77 files (725.1 KB), approximately 217.8k tokens, and a symbol index with 293 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!