private LINK_FLAGS Read_LinkFlags(uint value) { LINK_FLAGS flags = new LINK_FLAGS(); flags.hasLinkTargetIDList = Get_Boolean(value); value >>= 1; flags.hasLinkInfo = Get_Boolean(value); value >>= 1; flags.hasName = Get_Boolean(value); value >>= 1; flags.hasRelativePath = Get_Boolean(value); value >>= 1; flags.hasWorkingDir = Get_Boolean(value); value >>= 1; flags.hasArguments = Get_Boolean(value); value >>= 1; flags.hasIconLocation = Get_Boolean(value); value >>= 1; flags.isUnicode = Get_Boolean(value); value >>= 1; flags.forceNoLinkInfo = Get_Boolean(value); value >>= 1; flags.hasExpString = Get_Boolean(value); value >>= 1; flags.runInSeparateProcess = Get_Boolean(value); value >>= 1; flags.unused1 = Get_Boolean(value); value >>= 1; flags.hasDarwinID = Get_Boolean(value); value >>= 1; flags.runAsUser = Get_Boolean(value); value >>= 1; flags.hasExpIcon = Get_Boolean(value); value >>= 1; flags.noPidlAlias = Get_Boolean(value); value >>= 1; flags.unused2 = Get_Boolean(value); value >>= 1; flags.runWithShimLayer = Get_Boolean(value); value >>= 1; flags.forceNoLinkTrack = Get_Boolean(value); value >>= 1; flags.enableTargetMetadata = Get_Boolean(value); value >>= 1; flags.disableLinkPathTracking = Get_Boolean(value); value >>= 1; flags.disableKnownFolderAlias = Get_Boolean(value); value >>= 1; flags.allowLinkToLink = Get_Boolean(value); value >>= 1; flags.unaliasOnSave = Get_Boolean(value); value >>= 1; flags.preferEnvironmentPath = Get_Boolean(value); value >>= 1; flags.keepLocalIDListForUNCTarget = Get_Boolean(value); return(flags); }
private ShellLink(byte[] bytes, FileRecord record) { Path = record.FullName; HeaderSize = BitConverter.ToInt32(bytes, 0x00); if (HeaderSize == 0x4C) { #region SHELL_LINK_HEADER LinkCLSID = new Guid(NativeMethods.GetSubArray(bytes, 0x04, 0x10)); LinkFlags = (LINK_FLAGS)BitConverter.ToUInt32(bytes, 0x14); FileAttributes = (FILEATTRIBUTE_FLAGS)BitConverter.ToUInt32(bytes, 0x18); CreationTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x1C)); AccessTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x24)); WriteTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x2C)); FileSize = BitConverter.ToUInt32(bytes, 0x34); IconIndex = BitConverter.ToInt32(bytes, 0x38); ShowCommand = (SHOWCOMMAND)BitConverter.ToUInt32(bytes, 0x3C); #region HotKey HotKey = new HOTKEY_FLAGS[2]; HotKey[0] = (HOTKEY_FLAGS)bytes[0x40]; HotKey[1] = (HOTKEY_FLAGS)bytes[0x41]; #endregion HotKey int offset = 0x4C; #endregion SHELL_LINK_HEADER // I want to remove one layer of objects #region LINKTARGET_IDLIST if ((LinkFlags & LINK_FLAGS.HasLinkTargetIdList) == LINK_FLAGS.HasLinkTargetIdList) { IdListSize = BitConverter.ToUInt16(bytes, offset); IdList = new IdList(bytes, offset + 0x02, IdListSize); offset += IdListSize + 0x02; } #endregion LINKTARGET_IDLIST #region LINKINFO if ((LinkFlags & LINK_FLAGS.HasLinkInfo) == LINK_FLAGS.HasLinkInfo) { LinkInfoSize = BitConverter.ToUInt32(bytes, offset); LinkInfoHeaderSize = BitConverter.ToUInt32(bytes, offset + 0x04); LinkInfoFlags = (LINKINFO_FLAGS)BitConverter.ToUInt32(bytes, offset + 0x08); if ((LinkInfoFlags & LINKINFO_FLAGS.VolumeIDAndLocalBasePath) == LINKINFO_FLAGS.VolumeIDAndLocalBasePath) { VolumeIdOffset = BitConverter.ToUInt32(bytes, offset + 0x0C); VolumeId = new VolumeId(bytes, offset + (int)VolumeIdOffset); LocalBasePathOffset = BitConverter.ToUInt32(bytes, offset + 0x10); LocalBasePath = Encoding.Default.GetString(bytes, offset + (int)LocalBasePathOffset, (int)LinkInfoSize - (int)LocalBasePathOffset).Split('\0')[0]; } if ((LinkInfoFlags & LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix) == LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix) { CommonNetworkRelativeLinkOffset = BitConverter.ToUInt32(bytes, offset + 0x14); CommonNetworkRelativeLink = new CommonNetworkRelativeLink(bytes, offset + (int)CommonNetworkRelativeLinkOffset); CommonPathSuffixOffset = BitConverter.ToUInt32(bytes, offset + 0x18); CommonPathSuffix = Encoding.Default.GetString(bytes, offset + (int)CommonPathSuffixOffset, (int)LinkInfoSize - (int)CommonPathSuffixOffset).Split('\0')[0]; } if (LinkInfoHeaderSize >= 0x24) { LocalBasePathOffsetUnicode = BitConverter.ToUInt32(bytes, offset + 0x1C); LocalBasePathUnicode = Encoding.Unicode.GetString(bytes, offset + (int)LocalBasePathOffsetUnicode, (int)LinkInfoSize - (int)LocalBasePathOffsetUnicode).Split('\0')[0]; CommonPathSuffixOffsetUnicode = BitConverter.ToUInt32(bytes, offset + 0x20); CommonPathSuffixUnicode = Encoding.Unicode.GetString(bytes, offset + (int)CommonPathSuffixOffsetUnicode, (int)LinkInfoSize - (int)CommonPathSuffixOffsetUnicode).Split('\0')[0]; } offset += (int)LinkInfoSize; } #endregion LINKINFO #region STRING_DATA if ((LinkFlags & LINK_FLAGS.HasName) == LINK_FLAGS.HasName) { NameSize = BitConverter.ToUInt16(bytes, offset); Name = Encoding.Unicode.GetString(bytes, offset + 0x02, NameSize * 2); offset += 2 + (NameSize * 2); } if ((LinkFlags & LINK_FLAGS.HasRelativePath) == LINK_FLAGS.HasRelativePath) { RelativePathSize = BitConverter.ToUInt16(bytes, offset); RelativePath = Encoding.Unicode.GetString(bytes, offset + 0x02, RelativePathSize * 2); offset += 2 + (RelativePathSize * 2); } if ((LinkFlags & LINK_FLAGS.HasWorkingDir) == LINK_FLAGS.HasWorkingDir) { WorkingDirectorySize = BitConverter.ToUInt16(bytes, offset); WorkingDirectory = Encoding.Unicode.GetString(bytes, offset + 0x02, WorkingDirectorySize * 2); offset += 2 + (WorkingDirectorySize * 2); } if ((LinkFlags & LINK_FLAGS.HasArguments) == LINK_FLAGS.HasArguments) { CommandLineArgumentsSize = BitConverter.ToUInt16(bytes, offset); CommandLineArguments = Encoding.Unicode.GetString(bytes, offset + 0x02, CommandLineArgumentsSize * 2); offset += 2 + (CommandLineArgumentsSize * 2); } if ((LinkFlags & LINK_FLAGS.HasIconLocation) == LINK_FLAGS.HasIconLocation) { IconLocationSize = BitConverter.ToUInt16(bytes, offset); IconLocation = Encoding.Unicode.GetString(bytes, offset + 0x02, IconLocationSize * 2); offset += 2 + (IconLocationSize * 2); } #endregion STRING_DATA #region EXTRA_DATA List<ExtraData> edList = new List<ExtraData>(); int datalength = 0; do { datalength = BitConverter.ToInt32(bytes, offset); switch (BitConverter.ToUInt32(bytes, offset + 0x04)) { case 0xA0000001: edList.Add(new EnvironmentVariableDataBlock(bytes, offset)); break; case 0xA0000002: edList.Add(new ConsoleDataBlock(bytes, offset)); break; case 0xA0000003: edList.Add(new TrackerDataBlock(bytes, offset)); break; case 0xA0000004: edList.Add(new ConsoleFeDataBlock(bytes, offset)); break; case 0xA0000005: edList.Add(new SpecialFolderDataBlock(bytes, offset)); break; case 0xA0000006: edList.Add(new DarwinDataBlock(bytes, offset)); break; case 0xA0000007: edList.Add(new IconEnvironmentDataBlock(bytes, offset)); break; case 0xA0000008: edList.Add(new ShimDataBlock(bytes, offset)); break; case 0xA0000009: edList.Add(new PropertyStoreDataBlock(bytes, offset)); break; case 0xA000000B: edList.Add(new KnownFolderDataBlock(bytes, offset)); break; case 0xA000000C: edList.Add(new VistaAndAboveIDListDataBlock(bytes, offset)); break; } offset += datalength; } while (offset < bytes.Length - 0x04); ExtraData = edList.ToArray(); #endregion EXTRA_DATA } else { throw new Exception("Invalid ShellLink Header."); } }
private ShellLink(byte[] bytes, FileRecord record) { Path = record.FullName; HeaderSize = BitConverter.ToInt32(bytes, 0x00); if (HeaderSize == 0x4C) { #region SHELL_LINK_HEADER LinkCLSID = new Guid(Helper.GetSubArray(bytes, 0x04, 0x10)); LinkFlags = (LINK_FLAGS)BitConverter.ToUInt32(bytes, 0x14); FileAttributes = (FILEATTRIBUTE_FLAGS)BitConverter.ToUInt32(bytes, 0x18); CreationTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x1C)); AccessTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x24)); WriteTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0x2C)); FileSize = BitConverter.ToUInt32(bytes, 0x34); IconIndex = BitConverter.ToInt32(bytes, 0x38); ShowCommand = (SHOWCOMMAND)BitConverter.ToUInt32(bytes, 0x3C); #region HotKey HotKey = new HOTKEY_FLAGS[2]; HotKey[0] = (HOTKEY_FLAGS)bytes[0x40]; HotKey[1] = (HOTKEY_FLAGS)bytes[0x41]; #endregion HotKey int offset = 0x4C; #endregion SHELL_LINK_HEADER // I want to remove one layer of objects #region LINKTARGET_IDLIST if ((LinkFlags & LINK_FLAGS.HasLinkTargetIdList) == LINK_FLAGS.HasLinkTargetIdList) { IdListSize = BitConverter.ToUInt16(bytes, offset); IdList = new IdList(bytes, offset + 0x02, IdListSize); offset += IdListSize + 0x02; } #endregion LINKTARGET_IDLIST #region LINKINFO if ((LinkFlags & LINK_FLAGS.HasLinkInfo) == LINK_FLAGS.HasLinkInfo) { LinkInfoSize = BitConverter.ToInt32(bytes, offset); LinkInfoHeaderSize = BitConverter.ToUInt32(bytes, offset + 0x04); LinkInfoFlags = (LINKINFO_FLAGS)BitConverter.ToUInt32(bytes, offset + 0x08); if ((LinkInfoFlags & LINKINFO_FLAGS.VolumeIDAndLocalBasePath) == LINKINFO_FLAGS.VolumeIDAndLocalBasePath) { VolumeIdOffset = BitConverter.ToInt32(bytes, offset + 0x0C); VolumeId = new VolumeId(bytes, offset + VolumeIdOffset); LocalBasePathOffset = BitConverter.ToInt32(bytes, offset + 0x10); LocalBasePath = Encoding.Default.GetString(bytes, offset + LocalBasePathOffset, LinkInfoSize - LocalBasePathOffset).Split('\0')[0]; } if ((LinkInfoFlags & LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix) == LINKINFO_FLAGS.CommonNetworkRelativeLinkAndPathSuffix) { CommonNetworkRelativeLinkOffset = BitConverter.ToInt32(bytes, offset + 0x14); CommonNetworkRelativeLink = new CommonNetworkRelativeLink(bytes, offset + CommonNetworkRelativeLinkOffset); CommonPathSuffixOffset = BitConverter.ToInt32(bytes, offset + 0x18); CommonPathSuffix = Encoding.Default.GetString(bytes, offset + CommonPathSuffixOffset, LinkInfoSize - CommonPathSuffixOffset).Split('\0')[0]; } if (LinkInfoHeaderSize >= 0x24) { LocalBasePathOffsetUnicode = BitConverter.ToInt32(bytes, offset + 0x1C); LocalBasePathUnicode = Encoding.Unicode.GetString(bytes, offset + LocalBasePathOffsetUnicode, LinkInfoSize - LocalBasePathOffsetUnicode).Split('\0')[0]; CommonPathSuffixOffsetUnicode = BitConverter.ToInt32(bytes, offset + 0x20); CommonPathSuffixUnicode = Encoding.Unicode.GetString(bytes, offset + CommonPathSuffixOffsetUnicode, LinkInfoSize - CommonPathSuffixOffsetUnicode).Split('\0')[0]; } offset += LinkInfoSize; } #endregion LINKINFO #region STRING_DATA if ((LinkFlags & LINK_FLAGS.HasName) == LINK_FLAGS.HasName) { NameSize = BitConverter.ToUInt16(bytes, offset); Name = Encoding.Unicode.GetString(bytes, offset + 0x02, NameSize * 2); offset += 2 + (NameSize * 2); } if ((LinkFlags & LINK_FLAGS.HasRelativePath) == LINK_FLAGS.HasRelativePath) { RelativePathSize = BitConverter.ToUInt16(bytes, offset); RelativePath = Encoding.Unicode.GetString(bytes, offset + 0x02, RelativePathSize * 2); offset += 2 + (RelativePathSize * 2); } if ((LinkFlags & LINK_FLAGS.HasWorkingDir) == LINK_FLAGS.HasWorkingDir) { WorkingDirectorySize = BitConverter.ToUInt16(bytes, offset); WorkingDirectory = Encoding.Unicode.GetString(bytes, offset + 0x02, WorkingDirectorySize * 2); offset += 2 + (WorkingDirectorySize * 2); } if ((LinkFlags & LINK_FLAGS.HasArguments) == LINK_FLAGS.HasArguments) { CommandLineArgumentsSize = BitConverter.ToUInt16(bytes, offset); CommandLineArguments = Encoding.Unicode.GetString(bytes, offset + 0x02, CommandLineArgumentsSize * 2); offset += 2 + (CommandLineArgumentsSize * 2); } if ((LinkFlags & LINK_FLAGS.HasIconLocation) == LINK_FLAGS.HasIconLocation) { IconLocationSize = BitConverter.ToUInt16(bytes, offset); IconLocation = Encoding.Unicode.GetString(bytes, offset + 0x02, IconLocationSize * 2); offset += 2 + (IconLocationSize * 2); } #endregion STRING_DATA #region EXTRA_DATA List <ExtraData> edList = new List <ExtraData>(); int datalength = 0; do { datalength = BitConverter.ToInt32(bytes, offset); switch (BitConverter.ToUInt32(bytes, offset + 0x04)) { case 0xA0000001: edList.Add(new EnvironmentVariableDataBlock(bytes, offset)); break; case 0xA0000002: edList.Add(new ConsoleDataBlock(bytes, offset)); break; case 0xA0000003: edList.Add(new TrackerDataBlock(bytes, offset)); break; case 0xA0000004: edList.Add(new ConsoleFeDataBlock(bytes, offset)); break; case 0xA0000005: edList.Add(new SpecialFolderDataBlock(bytes, offset)); break; case 0xA0000006: edList.Add(new DarwinDataBlock(bytes, offset)); break; case 0xA0000007: edList.Add(new IconEnvironmentDataBlock(bytes, offset)); break; case 0xA0000008: edList.Add(new ShimDataBlock(bytes, offset)); break; case 0xA0000009: edList.Add(new PropertyStoreDataBlock(bytes, offset)); break; case 0xA000000B: edList.Add(new KnownFolderDataBlock(bytes, offset)); break; case 0xA000000C: edList.Add(new VistaAndAboveIDListDataBlock(bytes, offset)); break; } offset += datalength; } while (offset < bytes.Length - 0x04); ExtraData = edList.ToArray(); #endregion EXTRA_DATA } else { throw new Exception("Invalid ShellLink Header."); } }
private LINK_FLAGS Read_LinkFlags(uint value) { LINK_FLAGS flags = new LINK_FLAGS(); flags.hasLinkTargetIDList = Get_Boolean(value); value >>= 1; flags.hasLinkInfo = Get_Boolean(value); value >>= 1; flags.hasName = Get_Boolean(value); value >>= 1; flags.hasRelativePath = Get_Boolean(value); value >>= 1; flags.hasWorkingDir = Get_Boolean(value); value >>= 1; flags.hasArguments = Get_Boolean(value); value >>= 1; flags.hasIconLocation = Get_Boolean(value); value >>= 1; flags.isUnicode = Get_Boolean(value); value >>= 1; flags.forceNoLinkInfo = Get_Boolean(value); value >>= 1; flags.hasExpString = Get_Boolean(value); value >>= 1; flags.runInSeparateProcess = Get_Boolean(value); value >>= 1; flags.unused1 = Get_Boolean(value); value >>= 1; flags.hasDarwinID = Get_Boolean(value); value >>= 1; flags.runAsUser = Get_Boolean(value); value >>= 1; flags.hasExpIcon = Get_Boolean(value); value >>= 1; flags.noPidlAlias = Get_Boolean(value); value >>= 1; flags.unused2 = Get_Boolean(value); value >>= 1; flags.runWithShimLayer = Get_Boolean(value); value >>= 1; flags.forceNoLinkTrack = Get_Boolean(value); value >>= 1; flags.enableTargetMetadata = Get_Boolean(value); value >>= 1; flags.disableLinkPathTracking = Get_Boolean(value); value >>= 1; flags.disableKnownFolderAlias = Get_Boolean(value); value >>= 1; flags.allowLinkToLink = Get_Boolean(value); value >>= 1; flags.unaliasOnSave = Get_Boolean(value); value >>= 1; flags.preferEnvironmentPath = Get_Boolean(value); value >>= 1; flags.keepLocalIDListForUNCTarget = Get_Boolean(value); return flags; }