private static MruType GetType(byte[] header) { MruType result = MruType.My_Computer; switch (header[3]) { case 0x00: case 0x68: result = MruType.Explorer; break; case 0x42: result = MruType.Libraries; break; case 0x44: result = MruType.Users; break; case 0x4C: result = MruType.Public; break; case 0x48: result = MruType.My_Documents; break; case 0x50: result = MruType.My_Computer; break; case 0x58: result = MruType.My_Network; break; case 0x60: case 0x78: result = MruType.Recycle_Bin; break; case 0x70: result = MruType.Control_Panel; break; case 0x80: result = MruType.Game; break; } return(result); }
/// <summary> /// /// </summary> /// <param name="key"></param> /// <param name="reporter"></param> /// <param name="logger"></param> public static void ParseEx(RegistryKey key, Reporter reporter, Logger logger) { RegistryValue[] values = key.GetListOfValues(); if (null != values && 0 < values.Length) { List <KeyValuePair <string, string> > resultSet = new List <KeyValuePair <string, string> >(); // writer対象文字列 string checkedValue = string.Empty; // writer対象文字列 List <int> mruList = new List <int>(); // dir/fileバイト値格納 List <byte> fileList = new List <byte>(); List <byte> dirList = new List <byte>(); // Retrieve values and load into a hash for sorting foreach (RegistryValue value in values) { // Print sorted content to report file if (value.Name.StartsWith("MRUList")) { byte[] data = value.Data; int mru = -1; // MRUはゼロもあり得るので-1を与える for (int count = 0; data.Length > count; count += 4) { mru = BitConverter.ToInt32(data, count); if (0 <= mru) // 0をスキップしない { mruList.Add(mru); } } continue; } else if (null != value.Name) { if (Constants.REG_BINARY != value.Type) { checkedValue = value.GetDataAsString(); } else { MemoryStream stream = new MemoryStream(value.Data); string fileName = string.Empty; byte[] buffer = new byte[2]; string drive = string.Empty; if (key.Name.StartsWith("LastVisited") || key.Name.StartsWith("CIDSize")) // CIDの場合もファイル名を拾う { // get file name List <byte> byteList = new List <byte>(); do { stream.Read(buffer, 0, 2); byteList.AddRange(buffer); } while (0 < BitConverter.ToInt16(buffer, 0)); byteList.RemoveRange(byteList.Count - 2, 2); fileName = Encoding.Unicode.GetString(byteList.ToArray()); if (key.Name.StartsWith("CIDSize")) { checkedValue = fileName; } } if (key.Name.StartsWith("FirstFolder")) // FirstFolderの場合もファイル名を拾う { fileName = Encoding.Unicode.GetString(value.Data); checkedValue = fileName.Replace("\0", " ").TrimEnd(); } stream.Read(buffer, 0, 2); short headerSize = BitConverter.ToInt16(buffer, 0); stream.Seek(-2, SeekOrigin.Current); if (0x14 == headerSize) { byte[] headerBytes = new byte[headerSize]; stream.Read(headerBytes, 0, headerSize); MruType mruType = GetType(headerBytes); // get drive block size stream.Read(buffer, 0, 2); int driveSize = BitConverter.ToInt16(buffer, 0); byte[] driveBlock = new byte[driveSize - 2]; stream.Read(driveBlock, 0, driveSize - 2); // determin if block has drive letter if (MruType.My_Computer.Equals(mruType)) { // パスの先頭に出身地を追加 drive = string.Format("{0}\\", Enum.GetName(typeof(MruType), MruType.My_Computer)); drive += Encoding.ASCII.GetString(new byte[] { driveBlock[1], driveBlock[2], driveBlock[3] }); // Get child paths try { checkedValue = drive + GetPath(ref stream, logger); } catch (Exception exception) { logger.Write(LogLevel.WARNING, key.Name + "において発生:" + exception.Message); } } else if (MruType.My_Network.Equals(mruType)) { // whole skip driveblock // パスの先頭に出身地を追加 drive = string.Format("{0}\\", Enum.GetName(typeof(MruType), MruType.My_Network)); // get next block stream.Read(buffer, 0, 2); short networkSize = BitConverter.ToInt16(buffer, 0); byte[] networkBytes = new byte[networkSize - 2]; stream.Read(networkBytes, 0, networkSize - 2); List <byte> list = new List <byte>(); bool inData = false; foreach (byte item in networkBytes) { if (!inData && 0x5C == item) { inData = true; } else if (inData && 0x00 == item) { inData = false; } if (inData) { list.Add(item); } } drive += Encoding.ASCII.GetString(list.ToArray()) + "\\"; // Get child paths try { checkedValue = drive + GetPath(ref stream, logger); } catch (Exception exception) { logger.Write(LogLevel.WARNING, key.Name + "において発生:" + exception.Message); } } else if (MruType.Libraries.Equals(mruType)) { // whole skip driveblock // パスの先頭に出身地を追加 drive = string.Format("{0}\\", Enum.GetName(typeof(MruType), MruType.Libraries)); // Get child paths stream.Read(buffer, 0, 2); short size = BitConverter.ToInt16(buffer, 0); stream.Seek(-2, SeekOrigin.Current); byte[] block = new byte[size]; try { checkedValue = drive + GetPathFromBlock(block); } catch (Exception exception) { logger.Write(LogLevel.WARNING, key.Name + "において発生:" + exception.Message); } } } else { try { // OpenSaveとLastVisitedのときだけパスを取得する if (key.Name.StartsWith("OpenSave") || key.Name.StartsWith("LastVisited")) { checkedValue = GetPath(ref stream, logger); } } catch (Exception exception) { logger.Write(LogLevel.WARNING, key.Name + "において発生:" + exception.Message); } } } resultSet.Add(new KeyValuePair <string, string>(value.Name, checkedValue)); } } Write(mruList, reporter, logger, resultSet); } else { Library.WriteNoValue(key.KeyPath, reporter); } }