人家故里
type: channel
link: https://fx7.top/
description: 以梦为马，不负韶华
items: 地震知识学习
items: 10 分钟跑通达梦数据库 Flink CDC 数据同步
items: Linux中使用Chrony同步时间
items: docker 部署nacos 并配置达梦数据库作为数据源
items: asyncTool的使用
items: centos 新添加串口方法
items: Golang字典树实现域名匹配
items: 不良人YYDS
items: Windows驱动 - 文件操作(转载)
items: 雨中夜袭长虫山

地震知识学习
type: item
date: 2026-08-19T01:29:00+00:00
description: 地壳与地震地壳地球表层的岩石圈称作地壳。地壳岩层受力后快速破裂错动引起地表振动或破坏就叫地震。由于地质构造活动引发的地震叫构造地震（占地震总数的 95％ 以上）；由于火山活动造成的地震叫火山地震；固岩层（特别是石灰岩）塌陷引起的地震叫塌陷地震。地球内部结构与大气分层示意图断层断层（英语：Fault）是一种分开两种进行相对运动的岩体的岩石破裂面。断层通常出现在地壳活动频繁的区域，并与地震、海啸等天灾有关联性。两条彩色山脊（位于左下角和右上角）曾经形成一条连续的线，但由于沿着断层的运动而被分开。塔克拉瑪干沙漠断层的卫星影像。大型的断层通常是板块运动造成地壳活动的结果，无论是两个板块分离、挤压、隐没、相对旋转或是平移都有可能产生断层。构造分类三种基本断层类型分类断层的方法，是依照断层两侧岩体相对位移的方式。断层滑动方向和倾向（断层面和水平面的夹角）平行的断层称为 走向滑移断层。一般分为正断层及逆冲断层。正断层 是岩层因为受张力或是重力的作用而产生拉裂的断层，上盘相对下降，下盘相对上升。由于受张力作用，因此断层面较粗糙，擦痕一般不太发育，产状较陡；其破碎带中常形成棱角明显的断层角砾岩。大规模的正断层活动易造成陷落，形成盆地等下沉构造。逆冲断层 是岩层因为受到挤压的力量而产生的断层。上盘相对上升，下盘相对下降。断层面呈舒缓波状，断层擦痕较发育；断层破碎带中角砾岩常被压扁，棱角不明显；断层面倾角大小不等，大于 45° 为高角度逆断层或高角度逆冲断层，小于 45° 为低角度逆断层。一般来说，逆冲断层的长度可达数十千米，是东亚地区最常见的断层型态。参考：认识正断层地震有哪些类型？地震的类型根据不同的需要和角度，有多种不同的分类方法。按地震形成的原因分类构造地震： 由于地下深处岩层破裂、错动所形成的地震。这类地震发生的次数最多，约占全球地震总数的 90％ 以上，破坏力也最大。火山地震： 由于火山作用，岩浆活动，气体爆炸等引起的地震。火山地震一般影响范围较小，发生的次数也较少，约占全球地震总数的 7％。陷落地震： 由于地层陷落引起的地震。如地下溶洞支撑不住顶部的重量时，就会塌陷引起振动。这类地震更少，约占全球地震总数的 3％，引起的破坏也较小。根据震源深度进行分类浅源地震： 震源深度小于 60 公里的地震，大多数破坏性地震是浅源地震。中源地震： 震源深度为 60—300 公里。深源地震： 震源深度在 300 公里以上的地震，到目前为止，世界上纪录到的最深地震的震源深度为 786 公里。一年中，全球所有地震释放的能量约有 85％ 来自浅源地震，12％ 来自中源地震，3％ 来自深源地震。按地震的远近分类地方震： 震中距小于 100 公里的地震。近震： 震中距为 100—1000 公里。远震： 震中距大于 1000 公里的地震。按震级大小分类弱震： 震级小于 3 级的地震。有感地震： 指震级在 3.0—4.5 级之间，人能感觉到的地震。中强地震： 震级大于 4.5 级，小于 6 级的地震。强震： 震级大于 6.0 级的地震，其中又把震级小于 8.0 级的地震称为强烈破坏性地震，大于 8.0 级的地震称为巨大地震。构造地震的分类孤立型地震： 没有前震，余震小而少，且与主震震级相差悬殊，地震能量基本上是通过主震一次性释放的。（最大与次大震级差 ≥2.5）主震—余震型地震： 一次地震的序列中，最大的地震特别突出，所释放的能量占全序列能量的 90％ 以上。这个最大的地震叫主震，其它较小的地震中，发生在主震之前的叫前震，发生在主震之后的叫余震。（最大与次大震级差 0.6-2.4，占比约 59%）双震型地震： 一次地震活动序列中，90％ 以上的能量主要由发生时间接近，地点接近，大小接近的两次地震释放。（最大两震震级差 ≤0.5）震群型地震： 一次地震序列的主要能量是通过多个震级相近的地震释放的，没有明显的“老大”，其释放的能量占全序列的 80％ 以上。（至少三个震级差 ≤0.5 的地震）震级与烈度震级是根据地震释放能量的多少来划分地震大小的量度。目前记录到的最大震级是 8.9 级。一次地震只能有一个震级。震级相差 1 级，能量约差 30 倍。不同震级的地震所释放出来能量大致如下表：震 级能量（单位：尔格 ①）震 级能 量0$6.3×10^{11}$5$2×10^{19}$1$2×10^{13}$6$6.3×10^{20}$2$6.3×10^{14}$7$2×10^{22}$2.5$3.55×10^{15}$8$6.3×10^{23}$3$2×10^{16}$8.5$3.55×10^{24}$4$6.3×10^{17}$8.9$1.4×10^{25}$① 尔格：能量单位。一度电（一千瓦小时）的能量为 $3.6×10^{13}$地震烈度是地震引起的地面震动及其影响的强…

10 分钟跑通达梦数据库 Flink CDC 数据同步
type: item
date: 2026-03-27T08:16:00+00:00
description: 要做什么因为项目需要异地对达梦数据库进行实时数据同步，需要采用一个免费的方案，所以采用 达梦8 Flink CDC方案。在我的场景中，需要将20个子节点的数据同步到一个中心节点，且子节点与中心节点的网络并不稳定。因此有如下设计：子节点1 (DM) ──► Flink CDC Job1 ──► Kafka Topic (node1) 子节点2 (DM) ──► Flink CDC Job2 ──► Kafka Topic (node2) ... 子节点20 (DM) ──► Flink CDC Job20 ──► Kafka Topic (node20) Kafka ──► Flink Merge Job (1 个) ──► 顶级节点 (DM)简单来说，流程如下：1.每个子节点都有自己的 达梦8 数据库，在达梦数据库中开启归档模式以支持CDC；2.每个子节点单独配置一个Flink CDC Job，从达梦8 数据库中读取数据库变化记录；将读取到的记录转成 SQL 语句，随后写入 Kafka中；3.顶级节点从Kafka中订阅记录并通过 JDBC 写入自己的数据库中；怎么做按照上面说的流程，分为三个大的步骤：达梦8开启归档模式使用SYSDBA用户开启归档模式-- 1. 切换数据库到 MOUNT 状态 ALTER DATABASE MOUNT; -- 2. 开启归档模式 ALTER DATABASE ARCHIVELOG; -- 3. 添加一个本地归档配置（目录、文件大小、空间限制请按需修改， DEST指定的目录需要先创建好，并且这个目录数据库用户要有写入权限） ALTER DATABASE ADD ARCHIVELOG 'DEST = /dm8/arch, TYPE = LOCAL, FILE_SIZE = 1024, SPACE_LIMIT = 20480'; -- 4. 切回 OPEN 状态 ALTER DATABASE OPEN;验证是否成功-- 以 SYSDBA 执行 SELECT para_name, para_value FROM v$dm_ini WHERE para_name IN ('ARCH_INI', 'RLOG_APPEND_LOGIC');查询结果应该是这样的：LINEID PARA_NAME PARA_VALUE---------- ----------------- ----------1 RLOG_APPEND_LOGIC 22 ARCH_INI 1查出来的两个结果应该都不为 0 ，如果你查出来的值为0 ，可以通过以下 SQL 更改：-- 1. 切换数据库到 MOUNT 状态 ALTER DATABASE MOUNT; -- 2. 设置（推荐值，多数教程一致） SP_SET_PARA_VALUE(1, 'ARCH_INI', 1); SP_SET_PARA_VALUE(1, 'RLOG_APPEND_LOGIC', 2); -- 1 或 2 均可，2 更全面支持 UPDATE/DELETE -- 3. 切回 OPEN 状态 ALTER DATABASE OPEN; 特别注意：有的文章中只是用 select arch_mode from v$database; 来验证是否开启了归档模式。当 arch_mode 值为 Y 时，即代码开启了归档模式，其可以实现对历史数据的记录归档，但是如果此时上面写到的 RLOG_APPEND_LOGIC 值是 0，则 UPDATE、DELETE 等语句实际没有被记录到。这也是很多人反馈更新记录没有获取到的原因。搭建 Flink +Kafka 环境（docker）环境搭建我们采用最简单的方式进行，直接使用 docker-compose一键启动即可！要的资源不多，在本地的4G的虚拟机上也能正常启动，唯一到担心的就是你的网络能不能顺利的把镜像拉下来docker-compose.yaml注意：启动前把里面 kafka 的配置里面 IP改为自己服务器的IP，目前我写的是 192.168.20.220，只有一个地方version: "3.8" services: # ==================== Flink JobManager ==================== jobmanager: image: flink:1.20.3-scala_2.12-java17 container_name: flink-jobmanager hostname: jobmanager restart: unless-stopped ports: - "8081:8081" - "6123:6123" command: jobmanager environment: TZ: Asia/…

Linux中使用Chrony同步时间
type: item
date: 2025-11-19T02:19:21+00:00
description: Linux中使用Chrony同步时间Chrony是什么?Chrony 是网络时间协议(NTP)的一种实现。可以使用 Chrony:将系统时钟与 NTP 服务器同步，将系统时钟与参考时钟同步，如ASCII 接收器.要将系统时钟与手动时间输入同步，作为 NTPv4(RFC 5905) 服务器或对等服务器，为网络中的其他计算机提供时间服务。简而言之，Chrony是一个NTP协议的实现，能够同步其他NTP服务器的时间，也可以作为NTP服务器供其他服务器同步时间。Chrony怎么用？假设你的所有服务器都在 10.0.0.0/8 网段中,且此网段中所有服务器之间的网络策略是互通的。此时你可以将一台服务器作为Chrony服务器让其他服务器同步它的时间。例如，我在 10.0.0.0/8 网段中选择 10.10.2.101作为Chrony服务器，然后允许本网段中其他服务器来同步时间，那么配置如下：服务端：备份并修改chrony配置文件cp /etc/chrony.conf /etc/chrony.conf_bak vim /etc/chrony.conf文件内容：# 手动控制时间源（用于手工调整） manual # 修改 chrony 对外服务端口（默认 123 → 改为 11123） # 可以不修改，也可以修改，看需求 port 11123 # 允许 10 段网段访问 allow 10.0.0.0/8 # driftfile 和日志 driftfile /var/lib/chrony/drift logdir /var/log/chrony # 启用本地时间源，即使没有外部同步源也能提供服务 local stratum 10 # 外部同步源，如果有外部时间源，chrony服务器也可以通过外部时间来更新自己的时间，没有的话就注释 # 如果服务器通互联网，也可以配置互联网上的 ntp 服务器地址 #server 10.15.163.89 iburst修改完成后保存退出，重启chrony服务即可：systemctl restart chronyd客户端：备份并修改chrony配置文件cp /etc/chrony.conf /etc/chrony.conf_bak vim /etc/chrony.conf文件内容：server 10.10.2.101 port 11123 iburst driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync logdir /var/log/chrony修改完成后保存退出，重启chrony服务即可：systemctl restart chronyd配置成功后可以通过这条指令来查看当前同步状态chronyc tracking输出示例：[root@server1 ~]# chronyc tracking Reference ID : 0A055046 (10.10.2.101) Stratum : 11 Ref time (UTC) : Wed Nov 19 02:11:31 2025 System time : 0.000006415 seconds slow of NTP time Last offset : -0.000008004 seconds RMS offset : 0.000010776 seconds Frequency : 3.412 ppm fast Residual freq : -0.001 ppm Skew : 0.013 ppm Root delay : 0.000045834 seconds Root dispersion : 0.000062100 seconds Update interval : 260.9 seconds Leap status : Normal其中查看最后一行的 Leap status ，如果是Normal则证明与 Reference ID中的IP同步成功，否则代表不成功。使用下面这条指令可以手动同步一次时间chronyc makestep执行以下指令会打印出chrony正在访问的时间源的信息chronyc sources -v输出示例：[root@server1 ~]# chronyc sources -v 210 Number of sources = 1 .-- Source mode '^' = server, '=' = peer, '#' = local clock. / .- Source state '*' = current synced, '+' = combined , '-' = not combined, | / '?' = unreachable, 'x' = time may be …

docker 部署nacos 并配置达梦数据库作为数据源
type: item
date: 2024-06-20T13:13:00+00:00
description: 背景国产化的推行，项目开始使用达梦数据库，使用Nacos作为配置中心，需要对数据进行持久化存储。此处使用docker-compose部署nacos。参考文章Nacos适配达梦数据库(不修改源码)，基于Docker-compose_nacos 达梦数据库Nacos数据库适配插件实现步骤第一步：部署一个没有使用外部数据源的nacos此处部署的是 nacos 2.3.2版本，docker-compose配置文件内容如下，运行启动后默认账号密码都是nacosversion: "3" services: nacos: image: nacos/nacos-server:v2.3.2-slim container_name: nacos environment: - PREFER_HOST_MODE=hostname - MODE=standalone - NACOS_AUTH_ENABLE=true - NACOS_AUTH_IDENTITY_KEY=serverIdentity - NACOS_AUTH_IDENTITY_VALUE=security - NACOS_AUTH_TOKEN=ZDFhMTUyMDItYjAyZi00ZTM3LTkzYzctNmQxNTIyOTUyNzQ1 volumes: - ./standalone-logs/:/home/nacos/logs ports: - 8848:8848 - 9848:9848部署完成之后，使用docker exec -it nacos /bin/bash命令进入到容器中，执行ll可以看到当前目录下的文件信息如下图nacos容器目录结构进入conf目录下可以看到nacos启动的配置文件： application.properties第二步：拷贝出nacos启动的配置文件进行修改确定容器中application.properties配置文件的路径之后，退出容器，使用docker cp命令将文件从容器中拷贝出来：docker cp nacos:/home/nacos/conf/application.properties ./conf/application.properties使用vim编辑器打开application.properties进行修改，修改后的文件内容如下：# spring server.servlet.contextPath=${SERVER_SERVLET_CONTEXTPATH:/nacos} server.contextPath=/nacos server.port=${NACOS_APPLICATION_PORT:8848} server.tomcat.accesslog.max-days=30 server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i server.tomcat.accesslog.enabled=${TOMCAT_ACCESSLOG_ENABLED:false} server.error.include-message=ALWAYS # default current work dir server.tomcat.basedir=file:. #*************** Config Module Related Configurations ***************# ### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced. #spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:} #spring.sql.init.platform=${SPRING_DATASOURCE_PLATFORM:} spring.sql.init.platform=mysql nacos.cmdb.dumpTaskInterval=3600 nacos.cmdb.eventTaskInterval=10 nacos.cmdb.labelTaskInterval=300 nacos.cmdb.loadDataAtStart=false #db.num=${MYSQL_DATABASE_NUM:1} #db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?${MYSQL_SERVICE_…

asyncTool的使用
type: item
date: 2024-03-06T02:24:00+00:00
description: asyncTool是个啥官方仓库这样说：解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架，可以任意组合各线程的执行顺序，带全链路执行结果回调。多线程编排一站式解决方案。来自于京东主App后台怎么用1、引入Maven依赖<repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository><dependency> <groupId>com.gitee.jd-platform-opensource</groupId> <artifactId>asyncTool</artifactId> <version>V1.4-SNAPSHOT</version> </dependency>2、自定义任务类IWorker<Input, Output>是一个泛型接口，其中：Input代表入参类型，Output代表返回值类型下面的示例中，入参类型为fastjson包中的JSONObject类型，返回值类型为String字符串类型@Slf4j public class JobWorker implements IWorker<JSONObject, String>, ICallback<JSONObject, String> { @Override public void begin() { log.info("任务开始执行"); } @Override public void result(boolean b, JSONObject params, WorkResult<String> workResult) { log.info("任务执行完毕, 成功:{}, 入参:{}, 输出结果:{}", b, params, workResult); } @Override public String action(JSONObject params, Map<String, WorkerWrapper> map) { // 这里是要执行的耗时操作 return ""; } @Override public String defaultValue() { return "自定义默认值"; } }3、任务编排执行 JobWorker w = new JobWorker(); WorkerWrapper<JSONObject, String> workerWrapper = new WorkerWrapper .Builder<JSONObject, String>() .worker(w) .callback(w) .param(param) .build(); try { Async.beginWork(60000, workerWrapper); } catch (ExecutionException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } WorkResult<String> workResult = workerWrapper.getWorkResult(); log.info("result: {}", workResult);参考文章官方仓库

centos 新添加串口方法
type: item
date: 2024-01-23T02:11:00+00:00
description: 需求在某台设备上，安装有Centos7操作系统，此设备本身拥有6个串口，但centos默认只识别了4个串口，但某些数据被输出到了串口6上，所以需要识别出另外两个串口信息，以能够接收使用数据。修改步骤查看当前串口信息使用如下指令可以查看当前操作系统识别到的串口信息cat /proc/tty/driver/serial在centos下默认只有四个串口，串口信息展示如下图所示：默认串口信息编辑/etc/default/grub文件在我的设备上实际有6个串口，但是默认只识别了4个，现在在配置文件中进行配置：在文件的GRUB_CMDLINE_LINUX这一行末尾添加 8250.nr_uarts=6, 这里的数字6就是你的设备实际的串口数量，例如实际是10个串口，那就改为10，修改后的文件示例如下图所示：添加配置信息后的示例重新编译grub使用如下指令重新编译grub：grub2-mkconfig -o /boot/grub2/grub.cfg 注意如果是UEFI 系统上则需要执行命令grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg如何查看是不是UEFI 你可以在启动的时候进入bios里面查看一下是不是设置的UEFI都不会的可以两条都执行一下，执行完成后重启操作系统。效果重新查看串口信息重启完成之后，再次执行查看串口信息的命令：cat /proc/tty/driver/serial可以看到输出的信息中多出了4、5两条记录，总共6条。最终效果至此配置完成。参考文章centos下 新添加串口方法

Golang字典树实现域名匹配
type: item
date: 2023-11-14T15:50:00+00:00
description: 字典树定义字典树，顾名思义，是关于“字典”的一棵树。即：它是对于字典的一种存储方式（所以是一种数据结构而不是算法）。这个词典中的每个“单词”就是从根节点出发一直到某一个目标节点的路径，路径中每条边的字母连起来就是一个单词。结构实例trie1字典树的功能根据字典树的概念，我们可以发现：字典树的本质是把很多字符串拆成单个字符的形式，以树的方式存储起来。所以我们说字典树维护的是”字典“。那么根据这个最基本的性质，我们可以由此延伸出字典树的很多妙用。简单总结起来大体如下：1、维护字符串集合（即字典）。2、向字符串集合中插入字符串（即建树）。3、查询字符串集合中是否有某个字符串（即查询）。4、统计字符串在集合中出现的个数（即统计）。5、将字符串集合按字典序排序（即字典序排序）。6、求集合内两个字符串的LCP（Longest Common Prefix，最长公共前缀）（即求最长公共前缀）。我们可以发现，以上列举出的功能都是建立在“字符串集合”的基础上的。再一次强调，字典树是“字典”的树，一切功能都是“字典”的功能。这也为我们使用字典树的时候提供了一个准则：看到一大堆字符串同时出现，就往哈希和Trie树那边想一下。基于字典树实现的域名匹配有一个需求，给出一个域名名单，当输入一个新域名之后判断其是否存在域名名单中，要求支持通配符匹配代码实现根据字典树结构，使用go语言实现如下：package main import ( "fmt" "github.com/gookit/goutil/arrutil" "github.com/gookit/goutil/maputil" "strings" ) type TrieNode struct { children map[string]*TrieNode isEnd bool } type Trie struct { root *TrieNode } func initTrie() *Trie { return &Trie{root: &TrieNode{children: make(map[string]*TrieNode)}} } func (t *Trie) insertDomain(domain string) { parts := strings.Split(domain, ".") arrutil.Reverse(parts) node := t.root for _, part := range parts { if node.children[part] == nil { node.children[part] = &TrieNode{children: make(map[string]*TrieNode)} } node = node.children[part] } node.isEnd = true } func (t *Trie) searchDomain(domain string) bool { parts := strings.Split(domain, ".") arrutil.Reverse(parts) node := t.root for _, part := range parts { isNil := node.children[part] == nil if isNil && !maputil.HasKey(node.children, "*") { return false } if isNil { node = node.children["*"] } else { node = node.children[part] } } return node != nil && node.isEnd } func main() { trie := initTrie() // 示例域名 domains := []string{"wx.*.com", "example.com", "test.org"} // 插入域名到 Trie 中 for _, domain := range domains { trie.insertDomain(domain) } // 搜索示例 searchDomains := []string{"wx.qq.com", "openai.com", "test.org", "wx.qq1.com"} // 搜索域名是否存在于 Trie 中 for _, domain := range searchDomains { if trie.searchDomain(domain) { fmt.Printf("%s 存在\n", domain) } else { fmt.Printf("%s 不存在\n", domain) } } }参考文档字典树(…

不良人YYDS
type: item
date: 2023-09-23T09:06:00+00:00

Windows驱动 - 文件操作(转载)
type: item
date: 2023-09-14T02:08:00+00:00
description: 本文来自转载，补充了函数参考文档地址，调整了代码格式原文地址0x00 文件操作函数ZwDeleteFile 删除指定的文件 ZwOpenFile 打开现有文件、目录、设备或卷 ZwClose 关闭对象句柄ZwQueryInformationFile 返回有关文件对象的各种信息ZwReadFile 从打开的文件读取数据ZwWriteFile 将数据写入打开的文件ZwCreateFile 创建新文件或打开现有文件调用Zw函数会进行参数检查,检查完成后再调用nt函数代码示例#include <Ntifs.h> #include <wdm.h> //文件删除 NTSTATUS FileDelete(PWSTR wFilePath) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING uFilePath = { 0 }; RtlInitUnicodeString(&uFilePath, wFilePath); OBJECT_ATTRIBUTES objectAttributes = { 0 }; InitializeObjectAttributes(&objectAttributes, &uFilePath, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwDeleteFile(&objectAttributes); if (status == STATUS_SUCCESS) DbgPrint("FileDelete -> DeleteFile success"); else DbgPrint("FileDelete -> DeleteFile failed"); return status; } //文件复制 NTSTATUS FileCopy(PWSTR wDestinationPath, PWSTR wSourcePath) { NTSTATUS status = STATUS_SUCCESS; //打开源文件 HANDLE hSourceFile = NULL; //句柄 - 参数1 UNICODE_STRING uSourcePath = { 0 }; //路径名 RtlInitUnicodeString(&uSourcePath, wSourcePath); OBJECT_ATTRIBUTES oaSourceFile = { 0 }; //对象属性,包含路径名 - 参数3 InitializeObjectAttributes(&oaSourceFile, &uSourcePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); IO_STATUS_BLOCK isbSourceFile = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态 -> 参数4 status = ZwOpenFile(&hSourceFile, GENERIC_READ, &oaSourceFile, &isbSourceFile, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); if (status != STATUS_SUCCESS) { //没有需要释放的资源 DbgPrint("FileCopy -> ZwOpenFile failed"); return status; } //获取文件大小 IO_STATUS_BLOCK isbQuery = { 0 }; //IO_STATUS_BLOCK -> 接收完成状态 FILE_STANDARD_INFORMATION FileInformation = { 0 }; status = ZwQueryInformationFile(hSourceFile, &isbQuery, &FileInformation, sizeof(FileInformation), FileStandardInformation); if (status != STATUS_SUCCESS) { //需要释放资源 ZwClose(hSourceFile); //关闭源文件 DbgPrint("FileCopy -> ZwQueryInformationFile failed"); return status; } if (FileInformation.EndOfFile.QuadPart == 0) { //需要释放资源 ZwClose(hSourceFile); //关闭源文件 DbgPrint("FileCopy -> ZwQueryInforma…

雨中夜袭长虫山
type: item
date: 2023-09-09T14:44:00+00:00
description: 下午五点多，一时兴起，约上了两位挚友，来了一场说走就走的郊游，刚出门就雷声大作，刚到半路就已经是瓢泼大雨了，三个人都表示无所谓，干就完了。于是乎驱车到达山下，到了山下发现这边还没开始下雨，未作停留开始爬山，其中乐趣，在于许久未见的老友依然无话不说。三个段子手聚到了一起，一路上山都是笑声不断。快到山顶时，小雨便开始淅淅沥沥的落了下来，继续上行，雨也开始愈发的大了起来，终于一气呵成登顶，一览城市的夜景，顺手拍了几张照片纪念一下，奈何座机画质有点惨不忍睹！大帅比大帅比长虫山长虫山