1
0
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:
Patrick Simpson 2017-11-30 09:26:12 +02:00
parent ae076fe12f
commit 6d50679269
15 changed files with 242 additions and 52 deletions

View File

@ -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
} }
} }

View File

@ -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)

View File

@ -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();

View File

@ -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; } }

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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
{ {

View File

@ -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

View File

@ -72,29 +72,27 @@ namespace Acacia.Stubs.OutlookWrappers
commandLine += " /cleankoe " + Util.QuoteCommandLine(path); commandLine += " /cleankoe " + Util.QuoteCommandLine(path);
} }
} }
foreach(KeyValuePair<ZPushAccount, GABUser> share in _shares)
if (_shares.Count > 0)
{ {
using (RegistryKey key = OutlookRegistryUtils.OpenProfileOutlookKey(_addIn.ProfileName, RegistryKeyPermissionCheck.ReadWriteSubTree)) foreach (KeyValuePair<ZPushAccount, GABUser> share in _shares)
{ {
int accountId = (int)key.GetValue(OutlookConstants.REG_VAL_NEXT_ACCOUNT_ID); // TODO: escaping
using (RegistryKey accountKey = key.CreateSubKey(string.Format("{0:X8}", accountId))) commandLine += " /sharekoe " + Util.QuoteCommandLine(_addIn.ProfileName + ":" +
{ _addIn.VersionMajor + ":" +
accountKey.SetValue(OutlookConstants.REG_VAL_ACCOUNTNAME, share.Value.UserName + " through " + share.Key.DisplayName); share.Key.Account.AccountId + ":" +
accountKey.SetValue(OutlookConstants.REG_VAL_DISPLAYNAME, "Share for " + share.Value.DisplayName); share.Value.UserName + ":" + share.Value.EmailAddress + ":" +
accountKey.SetValue(OutlookConstants.REG_VAL_EMAIL, "test" + share.Key.Account.SmtpAddress); share.Value.EmailAddress);
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

View File

@ -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();
} }

View File

@ -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();
} }

View File

@ -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}";

View File

@ -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>

View File

@ -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);