private KdbContext ReadXmlElement(KdbContext ctx, XmlReader xr)
{
Debug.Assert(xr.NodeType == XmlNodeType.Element);
switch(ctx)
{
case KdbContext.Null:
if(xr.Name == ElemDocNode)
return SwitchContext(ctx, KdbContext.KeePassFile, xr);
else ReadUnknown(xr);
break;
case KdbContext.KeePassFile:
if(xr.Name == ElemMeta)
return SwitchContext(ctx, KdbContext.Meta, xr);
else if(xr.Name == ElemRoot)
return SwitchContext(ctx, KdbContext.Root, xr);
else ReadUnknown(xr);
break;
case KdbContext.Meta:
if(xr.Name == ElemGenerator)
ReadString(xr); // Ignore
else if(xr.Name == ElemDbName)
m_pwDatabase.Name = ReadString(xr);
else if(xr.Name == ElemDbNameChanged)
m_pwDatabase.NameChanged = ReadTime(xr);
else if(xr.Name == ElemDbDesc)
m_pwDatabase.Description = ReadString(xr);
else if(xr.Name == ElemDbDescChanged)
m_pwDatabase.DescriptionChanged = ReadTime(xr);
else if(xr.Name == ElemDbDefaultUser)
m_pwDatabase.DefaultUserName = ReadString(xr);
else if(xr.Name == ElemDbDefaultUserChanged)
m_pwDatabase.DefaultUserNameChanged = ReadTime(xr);
else if(xr.Name == ElemDbMntncHistoryDays)
m_pwDatabase.MaintenanceHistoryDays = ReadUInt(xr, 365);
else if(xr.Name == ElemDbColor)
{
string strColor = ReadString(xr);
if(!string.IsNullOrEmpty(strColor))
m_pwDatabase.Color = ColorTranslator.FromHtml(strColor);
}
else if(xr.Name == ElemDbKeyChanged)
m_pwDatabase.MasterKeyChanged = ReadTime(xr);
else if(xr.Name == ElemDbKeyChangeRec)
m_pwDatabase.MasterKeyChangeRec = ReadLong(xr, -1);
else if(xr.Name == ElemDbKeyChangeForce)
m_pwDatabase.MasterKeyChangeForce = ReadLong(xr, -1);
else if(xr.Name == ElemMemoryProt)
return SwitchContext(ctx, KdbContext.MemoryProtection, xr);
else if(xr.Name == ElemCustomIcons)
return SwitchContext(ctx, KdbContext.CustomIcons, xr);
else if(xr.Name == ElemRecycleBinEnabled)
m_pwDatabase.RecycleBinEnabled = ReadBool(xr, true);
else if(xr.Name == ElemRecycleBinUuid)
m_pwDatabase.RecycleBinUuid = ReadUuid(xr);
else if(xr.Name == ElemRecycleBinChanged)
m_pwDatabase.RecycleBinChanged = ReadTime(xr);
else if(xr.Name == ElemEntryTemplatesGroup)
m_pwDatabase.EntryTemplatesGroup = ReadUuid(xr);
else if(xr.Name == ElemEntryTemplatesGroupChanged)
m_pwDatabase.EntryTemplatesGroupChanged = ReadTime(xr);
else if(xr.Name == ElemHistoryMaxItems)
m_pwDatabase.HistoryMaxItems = ReadInt(xr, -1);
else if(xr.Name == ElemHistoryMaxSize)
m_pwDatabase.HistoryMaxSize = ReadLong(xr, -1);
else if(xr.Name == ElemLastSelectedGroup)
m_pwDatabase.LastSelectedGroup = ReadUuid(xr);
else if(xr.Name == ElemLastTopVisibleGroup)
m_pwDatabase.LastTopVisibleGroup = ReadUuid(xr);
else if(xr.Name == ElemBinaries)
return SwitchContext(ctx, KdbContext.Binaries, xr);
else if(xr.Name == ElemCustomData)
return SwitchContext(ctx, KdbContext.CustomData, xr);
else ReadUnknown(xr);
break;
case KdbContext.MemoryProtection:
if(xr.Name == ElemProtTitle)
m_pwDatabase.MemoryProtection.ProtectTitle = ReadBool(xr, false);
else if(xr.Name == ElemProtUserName)
m_pwDatabase.MemoryProtection.ProtectUserName = ReadBool(xr, false);
else if(xr.Name == ElemProtPassword)
m_pwDatabase.MemoryProtection.ProtectPassword = ReadBool(xr, true);
else if(xr.Name == ElemProtUrl)
m_pwDatabase.MemoryProtection.ProtectUrl = ReadBool(xr, false);
else if(xr.Name == ElemProtNotes)
m_pwDatabase.MemoryProtection.ProtectNotes = ReadBool(xr, false);
// else if(xr.Name == ElemProtAutoHide)
// m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = ReadBool(xr, true);
else ReadUnknown(xr);
break;
case KdbContext.CustomIcons:
if(xr.Name == ElemCustomIconItem)
return SwitchContext(ctx, KdbContext.CustomIcon, xr);
else ReadUnknown(xr);
break;
case KdbContext.CustomIcon:
if(xr.Name == ElemCustomIconItemID)
m_uuidCustomIconID = ReadUuid(xr);
else if(xr.Name == ElemCustomIconItemData)
{
string strData = ReadString(xr);
if(!string.IsNullOrEmpty(strData))
m_pbCustomIconData = Convert.FromBase64String(strData);
else { Debug.Assert(false); }
}
else ReadUnknown(xr);
break;
case KdbContext.Binaries:
if(xr.Name == ElemBinary)
{
if(xr.MoveToAttribute(AttrId))
{
string strKey = xr.Value;
ProtectedBinary pbData = ReadProtectedBinary(xr);
m_dictBinPool[strKey ?? string.Empty] = pbData;
}
else ReadUnknown(xr);
}
else ReadUnknown(xr);
break;
case KdbContext.CustomData:
if(xr.Name == ElemStringDictExItem)
return SwitchContext(ctx, KdbContext.CustomDataItem, xr);
else ReadUnknown(xr);
break;
case KdbContext.CustomDataItem:
if(xr.Name == ElemKey)
m_strCustomDataKey = ReadString(xr);
else if(xr.Name == ElemValue)
m_strCustomDataValue = ReadString(xr);
else ReadUnknown(xr);
break;
case KdbContext.Root:
if(xr.Name == ElemGroup)
{
Debug.Assert(m_ctxGroups.Count == 0);
if(m_ctxGroups.Count != 0) throw new FormatException();
m_pwDatabase.RootGroup = new PwGroup(false, false);
m_ctxGroups.Push(m_pwDatabase.RootGroup);
m_ctxGroup = m_ctxGroups.Peek();
return SwitchContext(ctx, KdbContext.Group, xr);
}
else if(xr.Name == ElemDeletedObjects)
return SwitchContext(ctx, KdbContext.RootDeletedObjects, xr);
else ReadUnknown(xr);
break;
case KdbContext.Group:
if(xr.Name == ElemUuid)
m_ctxGroup.Uuid = ReadUuid(xr);
else if(xr.Name == ElemName)
m_ctxGroup.Name = ReadString(xr);
else if(xr.Name == ElemNotes)
m_ctxGroup.Notes = ReadString(xr);
else if(xr.Name == ElemIcon)
m_ctxGroup.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Folder);
else if(xr.Name == ElemCustomIconID)
m_ctxGroup.CustomIconUuid = ReadUuid(xr);
else if(xr.Name == ElemTimes)
return SwitchContext(ctx, KdbContext.GroupTimes, xr);
else if(xr.Name == ElemIsExpanded)
m_ctxGroup.IsExpanded = ReadBool(xr, true);
else if(xr.Name == ElemGroupDefaultAutoTypeSeq)
m_ctxGroup.DefaultAutoTypeSequence = ReadString(xr);
else if(xr.Name == ElemEnableAutoType)
m_ctxGroup.EnableAutoType = StrUtil.StringToBoolEx(ReadString(xr));
else if(xr.Name == ElemEnableSearching)
m_ctxGroup.EnableSearching = StrUtil.StringToBoolEx(ReadString(xr));
else if(xr.Name == ElemLastTopVisibleEntry)
m_ctxGroup.LastTopVisibleEntry = ReadUuid(xr);
else if(xr.Name == ElemGroup)
{
m_ctxGroup = new PwGroup(false, false);
m_ctxGroups.Peek().AddGroup(m_ctxGroup, true);
m_ctxGroups.Push(m_ctxGroup);
return SwitchContext(ctx, KdbContext.Group, xr);
}
else if(xr.Name == ElemEntry)
{
m_ctxEntry = new PwEntry(false, false);
m_ctxGroup.AddEntry(m_ctxEntry, true);
m_bEntryInHistory = false;
return SwitchContext(ctx, KdbContext.Entry, xr);
}
else ReadUnknown(xr);
break;
case KdbContext.Entry:
if(xr.Name == ElemUuid)
m_ctxEntry.Uuid = ReadUuid(xr);
else if(xr.Name == ElemIcon)
m_ctxEntry.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Key);
else if(xr.Name == ElemCustomIconID)
m_ctxEntry.CustomIconUuid = ReadUuid(xr);
else if(xr.Name == ElemFgColor)
{
string strColor = ReadString(xr);
if(!string.IsNullOrEmpty(strColor))
m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor);
}
else if(xr.Name == ElemBgColor)
{
string strColor = ReadString(xr);
if(!string.IsNullOrEmpty(strColor))
m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor);
}
else if(xr.Name == ElemOverrideUrl)
m_ctxEntry.OverrideUrl = ReadString(xr);
else if(xr.Name == ElemTags)
m_ctxEntry.Tags = StrUtil.StringToTags(ReadString(xr));
else if(xr.Name == ElemTimes)
return SwitchContext(ctx, KdbContext.EntryTimes, xr);
else if(xr.Name == ElemString)
return SwitchContext(ctx, KdbContext.EntryString, xr);
else if(xr.Name == ElemBinary)
return SwitchContext(ctx, KdbContext.EntryBinary, xr);
else if(xr.Name == ElemAutoType)
return SwitchContext(ctx, KdbContext.EntryAutoType, xr);
else if(xr.Name == ElemHistory)
{
Debug.Assert(m_bEntryInHistory == false);
if(m_bEntryInHistory == false)
{
m_ctxHistoryBase = m_ctxEntry;
return SwitchContext(ctx, KdbContext.EntryHistory, xr);
}
else ReadUnknown(xr);
}
else ReadUnknown(xr);
break;
case KdbContext.GroupTimes:
case KdbContext.EntryTimes:
ITimeLogger tl = ((ctx == KdbContext.GroupTimes) ?
(ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry);
Debug.Assert(tl != null);
if(xr.Name == ElemLastModTime)
tl.LastModificationTime = ReadTime(xr);
else if(xr.Name == ElemCreationTime)
tl.CreationTime = ReadTime(xr);
else if(xr.Name == ElemLastAccessTime)
tl.LastAccessTime = ReadTime(xr);
else if(xr.Name == ElemExpiryTime)
tl.ExpiryTime = ReadTime(xr);
else if(xr.Name == ElemExpires)
tl.Expires = ReadBool(xr, false);
else if(xr.Name == ElemUsageCount)
tl.UsageCount = ReadULong(xr, 0);
else if(xr.Name == ElemLocationChanged)
tl.LocationChanged = ReadTime(xr);
else ReadUnknown(xr);
break;
case KdbContext.EntryString:
if(xr.Name == ElemKey)
m_ctxStringName = ReadString(xr);
else if(xr.Name == ElemValue)
m_ctxStringValue = ReadProtectedString(xr);
else ReadUnknown(xr);
break;
case KdbContext.EntryBinary:
if(xr.Name == ElemKey)
m_ctxBinaryName = ReadString(xr);
else if(xr.Name == ElemValue)
m_ctxBinaryValue = ReadProtectedBinary(xr);
else ReadUnknown(xr);
break;
case KdbContext.EntryAutoType:
if(xr.Name == ElemAutoTypeEnabled)
m_ctxEntry.AutoType.Enabled = ReadBool(xr, true);
else if(xr.Name == ElemAutoTypeObfuscation)
m_ctxEntry.AutoType.ObfuscationOptions =
(AutoTypeObfuscationOptions)ReadInt(xr, 0);
else if(xr.Name == ElemAutoTypeDefaultSeq)
m_ctxEntry.AutoType.DefaultSequence = ReadString(xr);
else if(xr.Name == ElemAutoTypeItem)
return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xr);
else ReadUnknown(xr);
break;
case KdbContext.EntryAutoTypeItem:
if(xr.Name == ElemWindow)
m_ctxATName = ReadString(xr);
else if(xr.Name == ElemKeystrokeSequence)
m_ctxATSeq = ReadString(xr);
else ReadUnknown(xr);
break;
case KdbContext.EntryHistory:
if(xr.Name == ElemEntry)
{
m_ctxEntry = new PwEntry(false, false);
m_ctxHistoryBase.History.Add(m_ctxEntry);
m_bEntryInHistory = true;
return SwitchContext(ctx, KdbContext.Entry, xr);
}
else ReadUnknown(xr);
break;
case KdbContext.RootDeletedObjects:
if(xr.Name == ElemDeletedObject)
{
m_ctxDeletedObject = new PwDeletedObject();
m_pwDatabase.DeletedObjects.Add(m_ctxDeletedObject);
return SwitchContext(ctx, KdbContext.DeletedObject, xr);
}
else ReadUnknown(xr);
break;
case KdbContext.DeletedObject:
if(xr.Name == ElemUuid)
m_ctxDeletedObject.Uuid = ReadUuid(xr);
else if(xr.Name == ElemDeletionTime)
m_ctxDeletedObject.DeletionTime = ReadTime(xr);
else ReadUnknown(xr);
break;
default:
ReadUnknown(xr);
break;
}
return ctx;
}