mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
[KOE-124] Lots of small fixes for account share setup
This commit is contained in:
parent
ae076fe12f
commit
6d50679269
@ -97,6 +97,7 @@ namespace Acacia
|
|||||||
public const string ZPUSH_CAPABILITY_NOTES = "notes";
|
public const string ZPUSH_CAPABILITY_NOTES = "notes";
|
||||||
public const string ZPUSH_CAPABILITY_OUT_OF_OFFICE = "oof";
|
public const string ZPUSH_CAPABILITY_OUT_OF_OFFICE = "oof";
|
||||||
public const string ZPUSH_CAPABILITY_OUT_OF_OFFICE_TIMES = "ooftime";
|
public const string ZPUSH_CAPABILITY_OUT_OF_OFFICE_TIMES = "ooftime";
|
||||||
|
public const string ZPUSH_CAPABILITY_IMPERSONATE = "impersonate";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -118,5 +119,6 @@ namespace Acacia
|
|||||||
public const string PLUGIN_REGISTRY_LOGLEVEL = "LogLevel";
|
public const string PLUGIN_REGISTRY_LOGLEVEL = "LogLevel";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,15 @@ namespace Acacia.Features.SharedFolders
|
|||||||
set { RegistryUtil.SetConfigValue("SharedFolders", "DefaultFolderNameFormat", value, Microsoft.Win32.RegistryValueKind.String); }
|
set { RegistryUtil.SetConfigValue("SharedFolders", "DefaultFolderNameFormat", value, Microsoft.Win32.RegistryValueKind.String); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AcaciaOption("If enabled, the 'Impersonate' capability is added, allowing whole stores to be opened through " +
|
||||||
|
"user impersonation; if Z-Push supports it.")]
|
||||||
|
public bool AllowImpersonate
|
||||||
|
{
|
||||||
|
get { return GetOption(OPTION_ALLOW_IMPERSONATE); }
|
||||||
|
set { SetOption(OPTION_ALLOW_IMPERSONATE, value); }
|
||||||
|
}
|
||||||
|
private static readonly BoolOption OPTION_ALLOW_IMPERSONATE = new BoolOption("AllowImpersonate", false);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public override void Startup()
|
public override void Startup()
|
||||||
@ -84,6 +93,13 @@ namespace Acacia.Features.SharedFolders
|
|||||||
SetupHierarchyChangeSuppression();
|
SetupHierarchyChangeSuppression();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override public void GetCapabilities(ZPushCapabilities caps)
|
||||||
|
{
|
||||||
|
base.GetCapabilities(caps);
|
||||||
|
if (AllowImpersonate)
|
||||||
|
caps.Add(Constants.ZPUSH_CAPABILITY_IMPERSONATE);
|
||||||
|
}
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|
||||||
private bool CanManageFolder(MenuItem<IFolder> b, IFolder folder)
|
private bool CanManageFolder(MenuItem<IFolder> b, IFolder folder)
|
||||||
|
@ -290,6 +290,8 @@ namespace Acacia.Features.SharedFolders
|
|||||||
// Restart
|
// Restart
|
||||||
IRestarter restarter = ThisAddIn.Instance.Restarter();
|
IRestarter restarter = ThisAddIn.Instance.Restarter();
|
||||||
restarter.CloseWindows = true;
|
restarter.CloseWindows = true;
|
||||||
|
foreach (StoreTreeNode node in state.stores)
|
||||||
|
restarter.OpenShare(_account, node.User);
|
||||||
restarter.Restart();
|
restarter.Restart();
|
||||||
}
|
}
|
||||||
}, true)
|
}, true)
|
||||||
@ -362,7 +364,7 @@ namespace Acacia.Features.SharedFolders
|
|||||||
|
|
||||||
if (select)
|
if (select)
|
||||||
{
|
{
|
||||||
FocusNode(node, false);
|
FocusNode(node, !_folders.SupportsWholeStore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,6 +394,7 @@ namespace Acacia.Features.SharedFolders
|
|||||||
|
|
||||||
private void WholeStoreShareChanged(KTreeNode node)
|
private void WholeStoreShareChanged(KTreeNode node)
|
||||||
{
|
{
|
||||||
|
// TODO: check duplicate email address
|
||||||
StoreTreeNode storeNode = (StoreTreeNode)node;
|
StoreTreeNode storeNode = (StoreTreeNode)node;
|
||||||
_dirtyWholeStores[storeNode.User] = storeNode.IsWholeStoreDirty;
|
_dirtyWholeStores[storeNode.User] = storeNode.IsWholeStoreDirty;
|
||||||
CheckDirty();
|
CheckDirty();
|
||||||
|
@ -43,7 +43,7 @@ namespace Acacia.Features.SharedFolders
|
|||||||
|
|
||||||
public bool SupportsWholeStore
|
public bool SupportsWholeStore
|
||||||
{
|
{
|
||||||
get { return true; } // TODO: use capability
|
get { return _feature.AllowImpersonate; } // TODO: use capability
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureSharedFolders Feature { get { return _feature; } }
|
public FeatureSharedFolders Feature { get { return _feature; } }
|
||||||
|
@ -65,7 +65,7 @@ namespace Acacia.Features.SharedFolders
|
|||||||
|
|
||||||
ChildLoader = new UserFolderLoader(this, folders, user);
|
ChildLoader = new UserFolderLoader(this, folders, user);
|
||||||
ChildLoader.ReloadOnCloseOpen = true;
|
ChildLoader.ReloadOnCloseOpen = true;
|
||||||
HasCheckBox = folders.SupportsWholeStore;
|
HasCheckBox = !string.IsNullOrEmpty(user.EmailAddress) && folders.SupportsWholeStore;
|
||||||
ApplyReadOnly(this, IsReadOnly);
|
ApplyReadOnly(this, IsReadOnly);
|
||||||
|
|
||||||
// TODO: better icons, better way of handling this
|
// TODO: better icons, better way of handling this
|
||||||
|
@ -27,6 +27,8 @@ namespace Acacia.Stubs
|
|||||||
{
|
{
|
||||||
AccountType AccountType { get; }
|
AccountType AccountType { get; }
|
||||||
|
|
||||||
|
string AccountId { get; }
|
||||||
|
|
||||||
IStore Store { get; }
|
IStore Store { get; }
|
||||||
|
|
||||||
void SendReceive();
|
void SendReceive();
|
||||||
|
@ -35,6 +35,7 @@ namespace Acacia.Stubs
|
|||||||
IEnumerable<Feature> Features { get; }
|
IEnumerable<Feature> Features { get; }
|
||||||
IEnumerable<KeyValuePair<string,string>> COMAddIns { get; }
|
IEnumerable<KeyValuePair<string,string>> COMAddIns { get; }
|
||||||
string Version { get; }
|
string Version { get; }
|
||||||
|
string VersionMajor { get; }
|
||||||
ISyncObject GetSyncObject();
|
ISyncObject GetSyncObject();
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
@ -35,11 +35,13 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||||
class AccountWrapper : ComWrapper<NSOutlook.Application>, IAccount, LogContext
|
class AccountWrapper : ComWrapper<NSOutlook.Application>, IAccount, LogContext
|
||||||
{
|
{
|
||||||
|
private readonly string _accountId;
|
||||||
private readonly string _regPath;
|
private readonly string _regPath;
|
||||||
private readonly IStore _store;
|
private readonly IStore _store;
|
||||||
|
|
||||||
internal AccountWrapper(NSOutlook.Application item, string regPath, IStore store) : base(item)
|
internal AccountWrapper(NSOutlook.Application item, string regPath, IStore store) : base(item)
|
||||||
{
|
{
|
||||||
|
this._accountId = System.IO.Path.GetFileName(regPath);
|
||||||
this._regPath = regPath;
|
this._regPath = regPath;
|
||||||
this._store = store;
|
this._store = store;
|
||||||
|
|
||||||
@ -81,10 +83,15 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (DeviceId == null) ? AccountType.Other : AccountType.EAS;
|
return (UserName == null) ? AccountType.Other : AccountType.EAS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string AccountId
|
||||||
|
{
|
||||||
|
get { return _accountId; }
|
||||||
|
}
|
||||||
|
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public IStore Store
|
public IStore Store
|
||||||
{
|
{
|
||||||
|
@ -304,7 +304,10 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
{
|
{
|
||||||
get { return _app.Version; }
|
get { return _app.Version; }
|
||||||
}
|
}
|
||||||
|
public string VersionMajor
|
||||||
|
{
|
||||||
|
get { return _app.Version.Split('.')[0]; }
|
||||||
|
}
|
||||||
|
|
||||||
public FeatureType GetFeature<FeatureType>()
|
public FeatureType GetFeature<FeatureType>()
|
||||||
where FeatureType : Feature
|
where FeatureType : Feature
|
||||||
|
@ -72,29 +72,27 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
commandLine += " /cleankoe " + Util.QuoteCommandLine(path);
|
commandLine += " /cleankoe " + Util.QuoteCommandLine(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_shares.Count > 0)
|
||||||
|
{
|
||||||
foreach (KeyValuePair<ZPushAccount, GABUser> share in _shares)
|
foreach (KeyValuePair<ZPushAccount, GABUser> share in _shares)
|
||||||
{
|
{
|
||||||
using (RegistryKey key = OutlookRegistryUtils.OpenProfileOutlookKey(_addIn.ProfileName, RegistryKeyPermissionCheck.ReadWriteSubTree))
|
// TODO: escaping
|
||||||
{
|
commandLine += " /sharekoe " + Util.QuoteCommandLine(_addIn.ProfileName + ":" +
|
||||||
int accountId = (int)key.GetValue(OutlookConstants.REG_VAL_NEXT_ACCOUNT_ID);
|
_addIn.VersionMajor + ":" +
|
||||||
using (RegistryKey accountKey = key.CreateSubKey(string.Format("{0:X8}", accountId)))
|
share.Key.Account.AccountId + ":" +
|
||||||
{
|
share.Value.UserName + ":" + share.Value.EmailAddress + ":" +
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_ACCOUNTNAME, share.Value.UserName + " through " + share.Key.DisplayName);
|
share.Value.EmailAddress);
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_DISPLAYNAME, "Share for " + share.Value.DisplayName);
|
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_EMAIL, "test" + share.Key.Account.SmtpAddress);
|
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_SERVER, share.Key.Account.ServerURL);
|
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_USERNAME, share.Key.Account.UserName + ".share." + share.Value.UserName);
|
|
||||||
accountKey.SetValue(OutlookConstants.REG_VAL_EAS_PASSWORD, share.Key.Account.EncryptedPassword);
|
|
||||||
//accountKey.SetValue(OutlookConstants.REG_VAL_EAS_DEVICEID, share.Key.Account.DeviceId);
|
|
||||||
accountKey.SetValue("clsid", "{ED475415-B0D6-11D2-8C3B-00104B2A6676}");
|
|
||||||
}
|
|
||||||
key.SetValue(OutlookConstants.REG_VAL_NEXT_ACCOUNT_ID, accountId + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
// Run that
|
// Run that
|
||||||
Process process = new Process();
|
Process process = new Process();
|
||||||
process.StartInfo = new ProcessStartInfo(RestarterPath, Process.GetCurrentProcess().Id + " " + commandLine);
|
process.StartInfo = new ProcessStartInfo(RestarterPath,
|
||||||
|
Process.GetCurrentProcess().Id + " " +
|
||||||
|
arch + " " +
|
||||||
|
commandLine);
|
||||||
process.Start();
|
process.Start();
|
||||||
|
|
||||||
// And close us and any other windows
|
// And close us and any other windows
|
||||||
|
@ -212,7 +212,7 @@ namespace Acacia.UI.Outlook
|
|||||||
|
|
||||||
string title = Properties.Resources.Ribbon_Title;
|
string title = Properties.Resources.Ribbon_Title;
|
||||||
// Convert to upper case for Outlook 2013, to match other ribbons
|
// Convert to upper case for Outlook 2013, to match other ribbons
|
||||||
if (ThisAddIn.Instance.Version.StartsWith("15."))
|
if (ThisAddIn.Instance.VersionMajor.Equals("15"))
|
||||||
{
|
{
|
||||||
title = title.ToUpper();
|
title = title.ToUpper();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,26 @@
|
|||||||
#include "EASAccount.h"
|
#include "EASAccount.h"
|
||||||
|
|
||||||
|
static const wstring R_ACCOUNT_NAME = L"Account Name";
|
||||||
|
static const wstring R_DISPLAY_NAME = L"Display Name";
|
||||||
|
static const wstring R_SERVER_URL = L"EAS Server URL";
|
||||||
|
static const wstring R_USERNAME = L"EAS User";
|
||||||
|
static const wstring R_EMAIL = L"Email";
|
||||||
|
static const wstring R_EMAIL_ORIGINAL = L"KOE Share For";
|
||||||
|
static const wstring R_PASSWORD = L"EAS Password";
|
||||||
|
|
||||||
struct Account
|
struct Account
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wstring profileName;
|
wstring profileName;
|
||||||
|
wstring outlookVersion;
|
||||||
wstring accountName;
|
wstring accountName;
|
||||||
wstring displayName;
|
wstring displayName;
|
||||||
wstring email;
|
wstring email;
|
||||||
|
wstring emailOriginal;
|
||||||
wstring server;
|
wstring server;
|
||||||
wstring username;
|
wstring username;
|
||||||
wstring password;
|
wstring password;
|
||||||
|
vector<byte> encryptedPassword;
|
||||||
wstring dataFolder;
|
wstring dataFolder;
|
||||||
private:
|
private:
|
||||||
wstring path;
|
wstring path;
|
||||||
@ -55,7 +66,50 @@ public:
|
|||||||
void Create()
|
void Create()
|
||||||
{
|
{
|
||||||
CheckInit();
|
CheckInit();
|
||||||
|
DeterminePath();
|
||||||
|
|
||||||
|
// Set up the account
|
||||||
|
OpenProfileAdmin();
|
||||||
|
EncryptPassword();
|
||||||
|
CreateMessageService();
|
||||||
|
GetEntryId();
|
||||||
|
CreateAccount();
|
||||||
|
CommitAccountKey();
|
||||||
|
PatchMessageStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadFromAccountId(const wstring &accountId)
|
||||||
|
{
|
||||||
|
OpenAccountKey(accountId);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
accountName = RegReadAccountKey(R_ACCOUNT_NAME);
|
||||||
|
displayName = RegReadAccountKey(R_DISPLAY_NAME);
|
||||||
|
email = RegReadAccountKey(R_EMAIL);
|
||||||
|
server = RegReadAccountKey(R_SERVER_URL);
|
||||||
|
username = RegReadAccountKey(R_USERNAME);
|
||||||
|
encryptedPassword = RegReadAccountKeyBinary(R_PASSWORD);
|
||||||
|
}
|
||||||
|
// Clean up
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (hKeyNewAccount)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKeyNewAccount);
|
||||||
|
hKeyNewAccount = nullptr;
|
||||||
|
}
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
if (hKeyNewAccount)
|
||||||
|
{
|
||||||
|
RegCloseKey(hKeyNewAccount);
|
||||||
|
hKeyNewAccount = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void DeterminePath()
|
||||||
|
{
|
||||||
// Determine the .ost path
|
// Determine the .ost path
|
||||||
if (dataFolder.empty())
|
if (dataFolder.empty())
|
||||||
{
|
{
|
||||||
@ -65,25 +119,27 @@ public:
|
|||||||
}
|
}
|
||||||
// Somehow it only works if there's a number in between parentheses
|
// Somehow it only works if there's a number in between parentheses
|
||||||
path = dataFolder + email + L" - " + profileName + L"(1).ost";
|
path = dataFolder + email + L" - " + profileName + L"(1).ost";
|
||||||
|
|
||||||
// Set up the account
|
|
||||||
OpenProfileAdmin();
|
|
||||||
CreateMessageService();
|
|
||||||
GetEntryId();
|
|
||||||
CreateAccount();
|
|
||||||
CommitAccountKey();
|
|
||||||
PatchMessageStore();
|
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
void EncryptPassword()
|
||||||
|
{
|
||||||
|
// TODO: handle the case password is not set in registry
|
||||||
|
if (encryptedPassword.empty())
|
||||||
|
encryptedPassword = EncryptPassword(password, L"EAS Password");
|
||||||
|
}
|
||||||
|
|
||||||
void CheckInit()
|
void CheckInit()
|
||||||
{
|
{
|
||||||
#define DoCheckInit(field) do{ if (field.empty()) throw exception("Field " #field " not initialised"); } while(0)
|
#define DoCheckInit(field) do{ if (field.empty()) throw exception("Field " #field " not initialised"); } while(0)
|
||||||
DoCheckInit(profileName);
|
DoCheckInit(profileName);
|
||||||
|
DoCheckInit(outlookVersion);
|
||||||
DoCheckInit(accountName);
|
DoCheckInit(accountName);
|
||||||
DoCheckInit(displayName);
|
DoCheckInit(displayName);
|
||||||
DoCheckInit(email);
|
DoCheckInit(email);
|
||||||
DoCheckInit(server);
|
DoCheckInit(server);
|
||||||
DoCheckInit(username);
|
DoCheckInit(username);
|
||||||
|
if (encryptedPassword.empty())
|
||||||
|
DoCheckInit(password);
|
||||||
#undef DoCheckInit
|
#undef DoCheckInit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +193,8 @@ private:
|
|||||||
msprops[2].Value.lpszW = (LPWSTR)displayName.c_str();
|
msprops[2].Value.lpszW = (LPWSTR)displayName.c_str();
|
||||||
|
|
||||||
msprops[3].ulPropTag = PR_PROFILE_SECURE_MAILBOX;
|
msprops[3].ulPropTag = PR_PROFILE_SECURE_MAILBOX;
|
||||||
vector<byte> encPassword = EncryptPassword(password, L"S010267f0");
|
msprops[3].Value.bin.cb = (ULONG)encryptedPassword.size();
|
||||||
msprops[3].Value.bin.cb = (ULONG)encPassword.size();
|
msprops[3].Value.bin.lpb = &encryptedPassword[0];
|
||||||
msprops[3].Value.bin.lpb = &encPassword[0];
|
|
||||||
|
|
||||||
msprops[4].ulPropTag = PR_RESOURCE_FLAGS;
|
msprops[4].ulPropTag = PR_RESOURCE_FLAGS;
|
||||||
msprops[4].Value.l = SERVICE_NO_PRIMARY_IDENTITY | SERVICE_CREATE_WITH_STORE;
|
msprops[4].Value.l = SERVICE_NO_PRIMARY_IDENTITY | SERVICE_CREATE_WITH_STORE;
|
||||||
@ -182,13 +237,31 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocateAccountKey()
|
void OpenAccountsKey()
|
||||||
{
|
{
|
||||||
|
if (hKeyAccounts != nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
wchar_t keyPath[MAX_PATH];
|
wchar_t keyPath[MAX_PATH];
|
||||||
|
|
||||||
// Open the accounts key
|
// Open the accounts key
|
||||||
swprintf_s(keyPath, ARRAYSIZE(keyPath), KEY_ACCOUNTS, 16, profileName.c_str());
|
swprintf_s(keyPath, ARRAYSIZE(keyPath), KEY_ACCOUNTS, outlookVersion.c_str(), profileName.c_str());
|
||||||
CHECK_L(RegOpenKey(HKEY_CURRENT_USER, keyPath, &hKeyAccounts), "OpenAccountsKey");
|
CHECK_L(RegOpenKey(HKEY_CURRENT_USER, keyPath, &hKeyAccounts), "OpenAccountsKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenAccountKey(const wstring &accountId)
|
||||||
|
{
|
||||||
|
OpenAccountsKey();
|
||||||
|
|
||||||
|
// Open the subkey
|
||||||
|
CHECK_L(RegOpenKey(hKeyAccounts, accountId.c_str(), &hKeyNewAccount), "OpenAccountKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllocateAccountKey()
|
||||||
|
{
|
||||||
|
OpenAccountsKey();
|
||||||
|
|
||||||
|
wchar_t keyPath[MAX_PATH];
|
||||||
|
|
||||||
// Get the NextAccountID value
|
// Get the NextAccountID value
|
||||||
DWORD size = sizeof(accountId);
|
DWORD size = sizeof(accountId);
|
||||||
@ -199,6 +272,23 @@ private:
|
|||||||
CHECK_L(RegCreateKey(hKeyAccounts, keyPath, &hKeyNewAccount), "CreateAccountKey");
|
CHECK_L(RegCreateKey(hKeyAccounts, keyPath, &hKeyNewAccount), "CreateAccountKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wstring RegReadAccountKey(const wstring &name)
|
||||||
|
{
|
||||||
|
wchar_t buffer[4096];
|
||||||
|
DWORD size = sizeof(buffer);
|
||||||
|
CHECK_L(RegQueryValueEx(hKeyNewAccount, name.c_str(), nullptr, nullptr, (LPBYTE)buffer, &size), "RegReadAccountKey");
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<byte> RegReadAccountKeyBinary(const wstring &name)
|
||||||
|
{
|
||||||
|
vector<byte> buffer(4096);
|
||||||
|
DWORD size = (DWORD)buffer.size();
|
||||||
|
CHECK_L(RegQueryValueEx(hKeyNewAccount, name.c_str(), nullptr, nullptr, (LPBYTE)&buffer[0], &size), "RegReadAccountKey");
|
||||||
|
buffer.resize(size);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void WriteAccountKey(const wstring &name, const wstring &value)
|
void WriteAccountKey(const wstring &name, const wstring &value)
|
||||||
{
|
{
|
||||||
CHECK_L(RegSetValueEx(hKeyNewAccount, name.c_str(), 0, REG_SZ, (LPBYTE)value.data(), (DWORD)value.size() * 2), "WriteAccountKey");
|
CHECK_L(RegSetValueEx(hKeyNewAccount, name.c_str(), 0, REG_SZ, (LPBYTE)value.data(), (DWORD)value.size() * 2), "WriteAccountKey");
|
||||||
@ -290,15 +380,18 @@ private:
|
|||||||
AllocateAccountKey();
|
AllocateAccountKey();
|
||||||
|
|
||||||
// Write the values
|
// Write the values
|
||||||
WriteAccountKey(L"Account Name", accountName);
|
WriteAccountKey(R_ACCOUNT_NAME, accountName);
|
||||||
WriteAccountKey(L"Display Name", displayName);
|
WriteAccountKey(R_DISPLAY_NAME, displayName);
|
||||||
WriteAccountKey(L"EAS Server URL", server);
|
WriteAccountKey(R_SERVER_URL, server);
|
||||||
WriteAccountKey(L"EAS User", username);
|
WriteAccountKey(R_USERNAME, username);
|
||||||
WriteAccountKey(L"Email", email);
|
WriteAccountKey(R_EMAIL, email);
|
||||||
|
|
||||||
|
if (!emailOriginal.empty())
|
||||||
|
WriteAccountKey(R_EMAIL_ORIGINAL, emailOriginal);
|
||||||
|
|
||||||
WriteAccountKey(L"clsid", L"{ED475415-B0D6-11D2-8C3B-00104B2A6676}");
|
WriteAccountKey(L"clsid", L"{ED475415-B0D6-11D2-8C3B-00104B2A6676}");
|
||||||
|
|
||||||
vector<byte> encrypted = EncryptPassword(password, L"EAS Password");
|
WriteAccountKey(R_PASSWORD, &encryptedPassword[0], encryptedPassword.size());
|
||||||
WriteAccountKey(L"EAS Password", &encrypted[0], encrypted.size());
|
|
||||||
|
|
||||||
WriteAccountKey(L"Service UID", &service, sizeof(service));
|
WriteAccountKey(L"Service UID", &service, sizeof(service));
|
||||||
|
|
||||||
@ -400,6 +493,9 @@ private:
|
|||||||
// Delete existing store
|
// Delete existing store
|
||||||
DeleteFile(path.c_str());
|
DeleteFile(path.c_str());
|
||||||
|
|
||||||
|
if (entryId.size() == 0)
|
||||||
|
throw exception("entryId not initialised");
|
||||||
|
|
||||||
// Open the msg store to finalise creation
|
// Open the msg store to finalise creation
|
||||||
CHECK_H(session->OpenMsgStore(0, (ULONG)entryId.size(), (LPENTRYID)&entryId[0], nullptr,
|
CHECK_H(session->OpenMsgStore(0, (ULONG)entryId.size(), (LPENTRYID)&entryId[0], nullptr,
|
||||||
MDB_NO_DIALOG | MDB_WRITE | MAPI_DEFERRED_ERRORS, &msgStore), "OpenMsgStore");
|
MDB_NO_DIALOG | MDB_WRITE | MAPI_DEFERRED_ERRORS, &msgStore), "OpenMsgStore");
|
||||||
@ -430,15 +526,27 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int __cdecl wmain(int, wchar_t **)
|
int __cdecl wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
// Parse the command line
|
|
||||||
// Usage:
|
|
||||||
Account account;
|
Account account;
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (argc != 7)
|
||||||
|
{
|
||||||
|
fwprintf(stderr, L"EASAccount: <profile> <outlook version> <accountid> <username> <email> <display>\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
account.profileName = argv[1];
|
||||||
|
account.outlookVersion = argv[2];
|
||||||
|
account.LoadFromAccountId(argv[3]);
|
||||||
|
account.username = account.username + L"+share+" + argv[4];
|
||||||
|
account.emailOriginal = account.email;
|
||||||
|
account.email = argv[5];
|
||||||
|
account.accountName = account.email;
|
||||||
|
account.displayName = argv[6];
|
||||||
|
|
||||||
// Create the account
|
// Create the account
|
||||||
account.Create();
|
account.Create();
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static const wchar_t *KEY_ACCOUNTS = L"SOFTWARE\\Microsoft\\Office\\%d.0\\Outlook\\Profiles\\%s\\9375CFF0413111d3B88A00104B2A6676";
|
static const wchar_t *KEY_ACCOUNTS = L"SOFTWARE\\Microsoft\\Office\\%s.0\\Outlook\\Profiles\\%s\\9375CFF0413111d3B88A00104B2A6676";
|
||||||
static const wchar_t *KEY_OLKMAIL = L"{ED475418-B0D6-11D2-8C3B-00104B2A6676}";
|
static const wchar_t *KEY_OLKMAIL = L"{ED475418-B0D6-11D2-8C3B-00104B2A6676}";
|
||||||
static const wchar_t *KEY_OLKADDRESSBOOK = L"{ED475419-B0D6-11D2-8C3B-00104B2A6676}";
|
static const wchar_t *KEY_OLKADDRESSBOOK = L"{ED475419-B0D6-11D2-8C3B-00104B2A6676}";
|
||||||
static const wchar_t *KEY_OLKSTORE = L"{ED475420-B0D6-11D2-8C3B-00104B2A6676}";
|
static const wchar_t *KEY_OLKSTORE = L"{ED475420-B0D6-11D2-8C3B-00104B2A6676}";
|
||||||
|
@ -77,17 +77,25 @@
|
|||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\</IntDir>
|
<IntDir>obj\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformShortName)</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>obj\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformShortName)</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\</IntDir>
|
<IntDir>obj\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformShortName)</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)Build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>obj\$(Configuration)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformShortName)</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -50,13 +50,15 @@ namespace OutlookRestarter
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string procPath = args[1];
|
int procId = int.Parse(args[0]);
|
||||||
List<string> procArgs = args.Skip(2).ToList();
|
string arch = args[1];
|
||||||
|
string procPath = args[2];
|
||||||
|
|
||||||
|
List<string> procArgs = args.Skip(3).ToList();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting1");
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting1");
|
||||||
// Attempt waiting for the process to finish
|
// Attempt waiting for the process to finish
|
||||||
int procId = int.Parse(args[0]);
|
|
||||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting2");
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting2");
|
||||||
Process proc = Process.GetProcessById(procId);
|
Process proc = Process.GetProcessById(procId);
|
||||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting3");
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Waiting3");
|
||||||
@ -76,6 +78,11 @@ namespace OutlookRestarter
|
|||||||
string path = procArgs[i];
|
string path = procArgs[i];
|
||||||
HandleCleanKoe(path);
|
HandleCleanKoe(path);
|
||||||
}
|
}
|
||||||
|
else if (procArgs[i] == "/sharekoe")
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
HandleShareKoe(arch, procArgs[i]);
|
||||||
|
}
|
||||||
else if (procArgs[i].StartsWith("/"))
|
else if (procArgs[i].StartsWith("/"))
|
||||||
{
|
{
|
||||||
useArgs.Add(procArgs[i]);
|
useArgs.Add(procArgs[i]);
|
||||||
@ -87,6 +94,7 @@ namespace OutlookRestarter
|
|||||||
}
|
}
|
||||||
string argsString = string.Join(" ", useArgs);
|
string argsString = string.Join(" ", useArgs);
|
||||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsed arguments: {0}", argsString);
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Parsed arguments: {0}", argsString);
|
||||||
|
|
||||||
// Start the process
|
// Start the process
|
||||||
Process process = new Process();
|
Process process = new Process();
|
||||||
process.StartInfo = new ProcessStartInfo(procPath, argsString);
|
process.StartInfo = new ProcessStartInfo(procPath, argsString);
|
||||||
@ -101,6 +109,40 @@ namespace OutlookRestarter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void HandleShareKoe(string arch, string rawArgs)
|
||||||
|
{
|
||||||
|
string baseDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
|
||||||
|
string path = Path.Combine(baseDir, "EASAccount-" + arch + ".exe");
|
||||||
|
string[] args = rawArgs.Split(':');
|
||||||
|
for (int i = 0; i < args.Length; ++i)
|
||||||
|
args[i] = "\"" + args[i] + "\"";
|
||||||
|
string argsString = string.Join(" ", args);
|
||||||
|
|
||||||
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to open account: {0}: {1}", path, argsString);
|
||||||
|
|
||||||
|
Process process = new Process();
|
||||||
|
process.StartInfo = new ProcessStartInfo(path, argsString);
|
||||||
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
process.StartInfo.UseShellExecute = false;
|
||||||
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
process.StartInfo.RedirectStandardError = true;
|
||||||
|
process.ErrorDataReceived += (s, e) =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(e.Data.Trim()))
|
||||||
|
Logger.Instance.Warning(typeof(OutlookRestarter), "EASAccount: {0}", e.Data.Trim());
|
||||||
|
};
|
||||||
|
process.OutputDataReceived += (s, e) =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(e.Data.Trim()))
|
||||||
|
Logger.Instance.Debug(typeof(OutlookRestarter), "EASAccount: {0}", e.Data.Trim());
|
||||||
|
};
|
||||||
|
process.Start();
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
process.WaitForExit(FINISH_WAIT_TIME);
|
||||||
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Opened accounts: {0}", argsString);
|
||||||
|
}
|
||||||
|
|
||||||
private static void HandleCleanKoe(string path)
|
private static void HandleCleanKoe(string path)
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to remove store: {0}", path);
|
Logger.Instance.Debug(typeof(OutlookRestarter), "Request to remove store: {0}", path);
|
||||||
|
Loading…
Reference in New Issue
Block a user