首页 > 其他分享 >解析快捷方式指向的路径

解析快捷方式指向的路径

时间:2023-06-12 11:34:14浏览次数:50  
标签:NULL Last goto 指向 FILE 快捷方式 解析 sizeof hFile

简介

在做垃圾文件清理的时候,会涉及到快捷方式的解析,以确定其是否有效

工作原理

操作系统提供了解析快捷方式的API,其中新型的 msi 快捷方式,多见于Office的程序,其文件路径是类似 msi:xxxx 的ID信息,可以使用 MsiGetShortcutTarget 进行解析。
普通的快捷方式,可以使用IShellLink 来进行解析,但是这种方法有缺陷,比如指向 C:\Program Files\a.exe 的快捷方式,用64位的程序去解析是正确的,但是用32位的程序去解析,就会得到 C:\Program Files (x86)\a.exe,无论是否使用 Wow64DisableWow64FsRedirection 关闭重定向,都是这样,所以只能解析 lnk 数据格式。

优化代码实现

#include <windows.h>
#include <atlbase.h>
#include <atlstr.h>
// (MAX_PATH * 2)
#define LARGE_PATH 520 
LSTATUS ParseLnkGetPath(_In_ CStringA csLnk, _Out_ CStringA& csPath)
{
	csLnk.MakeLower(); // 转为小写
	if (csLnk.GetLength() < 5) return ERROR_INVALID_PARAMETER;
	if (csLnk.Right(4) != ".lnk") return ERROR_INVALID_PARAMETER;
	// 获取新型的快捷方式路径(比如OFFICE的)
	CHAR szTemp[LARGE_PATH] = { 0 };
	CHAR szProductCode[39] = { 0 };
	CHAR szFeatureId[MAX_FEATURE_CHARS + 1] = { 0 };
	CHAR szComponentCode[39] = { 0 };
	LSTATUS ret = MsiGetShortcutTargetA(
		(PCSTR)csLnk, szProductCode, szFeatureId, szComponentCode);
	if (ret == ERROR_SUCCESS)
	{
		DWORD dwSize = LARGE_PATH * sizeof(WCHAR);
		// 未检测szTemp空间是否足够大
		INSTALLSTATE state = MsiGetComponentPathA(
			szProductCode, szComponentCode, szTemp, &dwSize);
		if (state == INSTALLSTATE_LOCAL)
		{
			_strlwr_s(szTemp); // 转为小写
			csPath = szTemp;
			return ERROR_SUCCESS;
		}
		return ERROR_INVALID_PARAMETER;
	}
	// 读取快捷方式的内容
	ret = ERROR_INVALID_PARAMETER;
	HANDLE hFile = CreateFileA((PCSTR)csLnk, GENERIC_READ, FILE_SHARE_READ,
							   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) return ret;
	// 按照特定格式解析内容
	DWORD dwFlag = 0;
	DWORD dwReadLen = 0;
	if (!ReadFile(hFile, &dwFlag, sizeof(DWORD), &dwReadLen, NULL)) goto Last;
	if (dwReadLen != sizeof(DWORD)) goto Last;
	if (dwFlag != 0x0000004CUL) goto Last;

	DWORD dwRet = SetFilePointer(hFile, 0x00000014L, NULL, FILE_BEGIN);
	if (dwRet == INVALID_SET_FILE_POINTER) goto Last;

	if (!ReadFile(hFile, &dwFlag, sizeof(DWORD), &dwReadLen, NULL)) goto Last;
	if (dwReadLen != sizeof(DWORD)) goto Last;

	dwRet = SetFilePointer(hFile, 0x0000004CL, NULL, FILE_BEGIN);
	if (dwRet == INVALID_SET_FILE_POINTER) goto Last;

	if (dwFlag & 0x00000001UL)
	{
		WORD wSize = 0;
		if (!ReadFile(hFile, &wSize, sizeof(WORD), &dwReadLen, NULL)) goto Last;
		if (dwReadLen != sizeof(WORD)) goto Last;

		dwRet = SetFilePointer(hFile, (LONG)wSize, NULL, FILE_CURRENT);
		if (dwRet == INVALID_SET_FILE_POINTER) goto Last;
	}

	dwRet = SetFilePointer(hFile, 0x00000010L, NULL, FILE_CURRENT);
	if (dwRet == INVALID_SET_FILE_POINTER) goto Last;

	if (!ReadFile(hFile, &dwFlag, sizeof(DWORD), &dwReadLen, NULL)) goto Last;
	if (dwReadLen != sizeof(DWORD)) goto Last;

	dwRet = SetFilePointer(hFile, -0x00000010L - (LONG)sizeof(DWORD) + (LONG)dwFlag, NULL, FILE_CURRENT);
	if (dwRet == INVALID_SET_FILE_POINTER) goto Last;

	int i = 0;
	char ch = 0;
	memset(szTemp, 0, sizeof(szTemp));
	do
	{
		if (!ReadFile(hFile, &ch, sizeof(char), &dwReadLen, NULL)) goto Last;
		*(szTemp + i++) = ch; // 未检测szTemp空间是否足够大
	} while (ch != '\0');

	_strlwr_s(szTemp); // 小写
	csPath = szTemp;
	ret = ERROR_SUCCESS;
Last:
	CloseHandle(hFile);
	return ret;
}

转载自:解析快捷方式指向的路径(1)

标签:NULL,Last,goto,指向,FILE,快捷方式,解析,sizeof,hFile
From: https://www.cnblogs.com/jarung/p/17474574.html

相关文章

  • 刷脸支付的奥秘解析
    一、刷脸支付简介刷脸支付目前比较流行的是支付宝或微信刷脸支付,支付宝是蜻蜓系列,微信是青蛙系列,但是你们知道他们采用的是什么技术么?二、刷脸支付技术分析首先无论是微信还是支付宝都发布了第二代的新产品,基于3D结构光技术实现对人活体进行识别,结构光三维成像的硬件主要由相机和投......
  • Spring事件监听机制使用和原理解析
    你好,我是刘牌!前言好久没有更新Spring了,今天来分享一下Spring的事件监听机制,之前分享过一篇Spring监听机制的使用,今天从原理上进行解析,Spring的监听机制基于观察者模式,就是就是我们所说的发布订阅模式,这种模式可以在一定程度上实现代码的解耦,如果想要实现系统层面的解耦,那么消息......
  • Java常用的几种JSON解析工具
    一、Gson:Google开源的JSON解析库1.添加依赖<!--gson--><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId></dependency><!--lombok--><dependency><groupId>org.proje......
  • IP地址解析DNS
    IP地址解析DNS背景指定IP解析域名,查看解析的域名,常用作CDN地址解析查询是否生效。本文章给出几个解决方案的shell脚本#!/bin/bash##****************************************************************************************#Author:wei#**************......
  • Goland 包导入正常,但是无法解析函数和成员属性,编译不报错
    这段时间Goland突然出现了一个毛病,每次goget依赖后,虽然依赖拉下来了,但是代码里使用了这个module的地方无法引用出他的成员和属性,大片的标红,都提示「Unresolvedreference'xxxxx'」,但是只要把项目关了,重新打开,再次触发module的index索引动作,就恢复正常了。本来想看看有没......
  • Python 解析配置模块之ConfigParser详解
      yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。只是粗略的知道yield可以用来为一个函数返回值塞数据,比如下面的例子:defaddlist(alist):foriinalist:yieldi+1取出alist的每一项,然后把i+1塞进去。然后通过......
  • 【Linux的高级应用编程】TCP/IP网络编程函数解析
    TCP/IP网络编程函数解析 Sailor_forever socket(建立一个socket通信)相关函数accept,bind,connect,listen表头文件#include<sys/types.h>#include<sys/socket.h>定义函数intsocket(intdomain,inttype,intprotocol);函数说明socket()用来建立一个新的socket,也就是向系统注......
  • win11 右键添加 .md 文件快捷方式
    尝试用常用方法添加.xmind.md文件,xmind文件成功,但是md文件不成功,因此记录解决方法参考详细方法https://www.cnblogs.com/stblack/p/16637219.html注册表相关https://www.cnblogs.com/sepmaple/articles/9401215.html问题:按照常用方法添加后右键还是不出现md项解决:直......
  • React - 28 redux部分源码解析
    myRedux.jsimport_from'./assets/utils';/*实现redux的部分源码*/exportconstcreateStore=functioncreateStore(reducer){if(typeofreducer!=='function')thrownewError("Expectedtherootreducertobeafunction");......
  • 使用 dom4j 解析 XML
    http://www.ibm.com/developerworks/cn/xml/x-dom4j.html创建文档本节讨论使用dom4jAPI创建XML文档的过程,并创建示例XML文档catalog.xml。使用import语句导入dom4jAPI类:1.importorg.dom4j.Document;2.importorg.dom4j.DocumentHelper;3.importorg.dom4j.......