西方神话备忘录

Α	α	alpha
Β	β	beta
Γ	γ	gamma
Δ	δ	delta
Ε	ε	epsilon
Ζ	ζ	zeta		/'zi:tə/
Η	η	eta		/'i:tə/
Θ	θ	theta
Ι	ι	iota		/aɪ'əʊtə/
Κ	κ	kappa	/'kæpə/
Λ	λ	lambda
Μ	μ	mu		/mju:/

Ν	ν	nu		/nju:/
Ξ	ξ	xi		/ksi/,/ˈksaɪ/,/ˈzaɪ/
Ο	ο	omicron	/əuˈmaikrən/,/ˈɑmɪˌkrɑn/
Π	π	pi
Ρ	ρ	rho		/rəʊ/
Σ	σ/ς	sigma
Τ	τ	tau		/tɔ:/,/taʊ/
Υ	υ	upsilon	/ˈipsilon/,/ˈʌpsɨlɒn/
Φ	φ	phi		/faɪ/
Χ	χ	chi		/kaɪ/
Ψ	ψ	psi		/psaɪ/
Ω	ω	omega

希腊神话

Chronos/Χρόνος: 柯罗诺斯/时间之神

五大创世神
	Gaia/Γαία: 盖亚/Terra特鲁斯
	Tartarus/Τάρταρος: 塔耳塔洛斯/深渊
	Erebus/Ἔρεβος: 厄瑞玻斯/幽冥
		Aether/Αἰθήρ: 埃忒尔/天光
		Hemera/Ἡμέρα: 赫墨拉/白昼
		Charon/Χάρων: 卡戎/冥海渡神
	Nyx/Νύξ: 倪克斯/暗夜
		Morus/Μόρος: 摩洛斯/厄运,惨死
		Cer/Κῆρ: 卡尔/横死,毁灭
		Thanatus/Θάνατς: 塔那托斯/死亡
		Hypnus/Ὕπνος: 修普诺斯/睡眠
		Oneiroi/Ὄνειροι: 俄尼里伊/梦,梦境
		Momus/Μῶμος: 摩墨斯/挑剔,嘲讽
		Ceres/Κῆρες: 刻瑞斯/致死,亡灵
		Oizys/Ὀϊζύς: 俄匊斯/悲惨,哀伤
		Nemesis/Νέμεσις: 涅墨西斯/义愤,报复
		Apate/Ἀπάτη: 阿帕忒/欺骗
		Philotes/Φιλότης: 菲罗忒斯/性欲,情欲
		Geras/Γῆρας: 革剌斯/衰老,老年
		Eris/Ἔρις: 厄里斯/纷争,不和
	Eros/Ἔρως: 厄洛斯/爱欲

Uranos: 乌拉诺斯/Caelus凯路斯/天神
Aphrodite: 阿佛洛狄忒/Venus维纳斯
Pontus: 蓬托斯/海神
Ourea: 乌瑞亚/山神
Prometheus: 普罗米修斯

Oceanus: 俄刻阿诺斯/泰坦十二神老大

Hyperion/Ὑπερίων: 许珀里翁/泰坦十二神之一
Theia/Θεία: 忒亚/视力、光照/泰坦十二神之一
	Helios: 赫利俄斯/太阳
	Phaethon: 法厄同
	Eos: 厄俄斯/曙光
	Selene: 塞勒涅/月亮
	Clytie: 向日葵

Kronos/Cronos/Κρόνος: 克洛诺斯/Saturn萨图恩/泰坦十二神老幺/第二代神王/农神
Rhea: 瑞亚/Ops俄普斯/泰坦十二神之一/时光
	Zeus/Ζεύς/Δίας: 宙斯/Jupiter朱庇特/老幺/第三代神王/Titanomachy泰坦之战
	Hera: 赫拉/Juno朱诺/
	Themis: 忒弥斯/Justitia朱斯提提亚/泰坦十二神之一/法律正义
		Ares: 阿瑞斯/Mars马尔斯
		Hephaestus/Ἥφαιστος: 赫菲斯托斯/Vulcan伏尔甘/火神、工匠
		Hermes: 赫尔墨斯/Mercury墨丘利/信使
		Eris: 厄里斯/Discordia狄斯科耳狄亚/不和女神
	Poseidon: 波塞冬/Neptune尼普顿
	Hades: 哈迪斯/Pluto普路托/冥王星
	Demeter: 得墨忒耳/Ceres刻瑞斯/丰收/谷神星
	
Adelos: 德罗斯岛
Phoebus Apollo/Απόλλων: 福玻斯·阿波罗/文艺、保护神、光明神、预言、雄辩之神、医神以及消灾弥难之神
Daphne: 达芙妮/月桂女神
Artemis: 阿尔忒弥斯/狩猎、接生

Eros/Έρως: 厄洛斯/Cupid丘比特
Psyche: 普赛克

refer to:
https://baike.baidu.com/item/%E5%B8%8C%E8%85%8A%E5%AD%97%E6%AF%8D/4428067?fr=aladdin
https://baike.baidu.com/item/%E4%BA%94%E5%A4%A7%E5%88%9B%E4%B8%96%E7%A5%9E/10466429
https://baike.baidu.com/item/%E5%85%8B%E6%B4%9B%E8%AF%BA%E6%96%AF/3399553
https://zhidao.baidu.com/question/2272801280037695908.html
http://www.360doc.com/content/15/0318/21/4240596_456274573.shtml

asn.1中的方括号

asn.1编码以tag + length + value为基本单元,IMPLICIT模式是用context-specific tag替换后面通常是universal的tag;EXPLICIT模式是用context-specific tag的tlv包裏里层的universal tag的tlv。

ber编码时,会默认为EXPLICIT模式。

在bnf范式语法中

1
2
3
4
5
圆括号(): 相当于C语言算术表达式中圆括号()的作用。
尖括号<>: 内包含的为必选项。 
方括号[]: 内包含的为可选项。 
花括号{}: 内包含的为可重复0至无数次的项。 
|: 或or的意思;若要表示并and的意思,直接两个符号之间空白间隔。

而在asn.1语法中,方括号[Index]指示的是context-specific tag值,即0xA0 + Index;花括号{}用于SEQUENCE,SET或CHOICE的定义。如

1
2
Number2 ::= [7] IMPLICIT [1] INTEGER
AccountedClosed [2] EXPLICIT BOOLEAN

这里Number2的tag值为0xA7;而对于AccountedClosed,当其值为true时其ber编码为

1
0xA2 0x3 0x1 0x1 0xFF

refer to:
https://blog.csdn.net/sever2012/article/details/7767867
https://www.cnblogs.com/qook/p/5957436.html

数字证书备忘录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ca: certification authority
pem: privacy enhanced mail, "begin"+base64+"end"
der: distinguished encoding rules, binary
crt: certificate
cer: certificate
csr: certificate signing request
pkcs: public key cryptography standard
ietf: internet engineering task force
pkcs#12/pfx/p12: file format encoding private keys, certificates and etc, rfc7292
pkcs#7: cryptographic message syntex standard
pkcs#10/p10: certification request syntax specification, rfc2986
x.509: public key certificates format standard
ber: basic encoding rules
per: packed encoding rules
crl: certificate revocation list

refer to:
http://www.360doc.com/content/15/0520/10/21412_471902987.shtml
https://baike.baidu.com/item/BER/19940289?fr=aladdin
https://blog.csdn.net/mao834099514/article/details/109074661
https://datatracker.ietf.org/doc/html/rfc7292

asn.1编码的转换

这个工具在

1
strongswan/src/libstrongswan/asn1

以下是使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
 
#define INTEGER_SIZE 32
 
static chunk_t chunk_to_asn1(chunk_t chunk)
{
	chunk_t x;
	chunk_t y;
	chunk_t hash;
	chunk_t content;
	chunk_t asn1;
 
	x.ptr = chunk.ptr;
	x.len = INTEGER_SIZE;
	y.ptr = chunk.ptr + INTEGER_SIZE;
	y.len = INTEGER_SIZE;
	content.ptr = y.ptr + INTEGER_SIZE;
	content.len = chunk.len - INTEGER_SIZE * 3;
	hash.ptr = content.ptr + content.len;
	hash.len = INTEGER_SIZE;
 
	asn1 = asn1_wrap(ASN1_SEQUENCE, "mmmm",
		asn1_integer("c", x),
		asn1_integer("c", y),
		asn1_simple_object(ASN1_OCTET_STRING, hash),
		asn1_simple_object(ASN1_OCTET_STRING, content));
 
	chunk_free(&chunk);
	return asn1;
}
 
static const asn1Object_t patterns[] = {
	{ 0, "seq",			ASN1_SEQUENCE,		ASN1_NONE }, /*  0 */
	{ 1,   "x",			ASN1_INTEGER,		ASN1_BODY }, /*  1 */
	{ 1,   "y",			ASN1_INTEGER,		ASN1_BODY }, /*  2 */
	{ 1,   "hash",			ASN1_OCTET_STRING,	ASN1_BODY }, /*  3 */
	{ 1,   "content",		ASN1_OCTET_STRING,	ASN1_BODY }, /*  4 */
	{ 0, "exit",			ASN1_EOC,		ASN1_EXIT }
};
#define PATTERN_KEY_X			1
#define PATTERN_KEY_Y			2
#define PATTERN_KEY_HASH		3
#define PATTERN_KEY_CONTENT		4
 
static chunk_t correct_integer(chunk_t chunk)
{
	if (chunk.len == INTEGER_SIZE + 1)
		return chunk_skip(chunk, 1);
	return chunk;
}
 
static bool parse_asn1(chunk_t asn1, chunk_t* x, chunk_t* y, chunk_t* hash, chunk_t* content)
{
	chunk_t object;
	asn1_parser_t *parser;
	bool success = FALSE;
	int object_id, oid, i;
 
	parser = asn1_parser_create(patterns, asn1);
 
	while (parser->iterate(parser, &object_id, &object))
	{
		switch (object_id)
		{
			case PATTERN_KEY_X:
				*x = correct_integer(object);
				break;
			case PATTERN_KEY_Y:
				*y = correct_integer(object);
				break;
			case PATTERN_KEY_HASH:
				*hash = object;
				break;
			case PATTERN_KEY_CONTENT:
				*content = object;
				break;
		}
	}
	success = parser->success(parser);
	parser->destroy(parser);
	return success;
}
 
static bool chunk_from_asn1(chunk_t* chunk, chunk_t asn1)
{
	chunk_t x;
	chunk_t y;
	chunk_t hash;
	chunk_t content;
 
	if (!parse_asn1(asn1, &x, &y, &hash, &content))
		return false;
 
	*chunk = chunk_cat("cccc", x, y, content, hash);
	return true;
}
 
static void random_data(chunk_t chunk)
{
	int fd = open("/dev/urandom", O_RDONLY);
	read(fd, chunk.ptr, chunk.len);
	close(fd);
}
 
int test()
{
	bool is_ok;
	chunk_t result;
	chunk_t asn1;
	chunk_t total = chunk_alloc(INTEGER_SIZE * 3 + 345);
 
	random_data(total);
 
	asn1 = chunk_to_asn1(total);
	is_ok = chunk_from_asn1(&result, asn1);
 
	chunk_free(&result);
	chunk_free(&asn1);
	chunk_free(&total);
	return is_ok;
}

因为asn1模块里对ASN1_INTEGER类型有个two's complement处理,如果这个数最高位为1,则在此数前加一个0值字节,所以correct_integer函数的目地在于更正输出。

转载: linux下的多国语言解决方案

hello.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <libintl.h> // gettext
#include <locale.h>
 
#define _(STRING) gettext(STRING)
#define PACKAGE "hello"
#define LOCALEDIR "/usr/share/locale/"
 
int main(int argv, char* argc[])
{
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	printf(_("Hello, World\n"));
	printf(_("This is a example.\n"));
	return 0;
}

提取字符串

1
xgettext --keyword=_ hello.c -o hello.pot

编辑hello.pot

1
2
3
4
5
6
...
msgid "Hello, World\n"
msgstr "你好,世界!\n"
msgid "This is a example.\n"
msgstr "This is a example.\n"
...

将hello.pot编译为字节码

1
2
msgmerge zh_CN.po hello.pot
msgfmt zh_CN.po -o hello.mo

refer to:
https://leedd.com/linux-c-i18n-l10n-xgettext-msgfmt-rpmbuild/

乐理备忘录

和弦

1
2
3
4
5
6
7
8
9
10
11
12
13
大七和弦:	大小大	1 3 5 7 2 4 6	4 6 1 3 5 7 2
小七和弦:	小大小	6 1 3 5 7 2 4
小七大九和弦:	小大小	6 1 3 5 7 2 4	自然大调VI级
小七小九和弦:	小大小	3 5 7 2 4 6 1	自然大调III级
属七和弦:	大小小	5 7 2 4 6 1 3
属七降九和弦:	大小小	5 7 2 4b6 1 3	和声小调V级
属七升九和弦:	大小小	5 7 2 4#6 1 3	7音到9音=增三度=纯四度
属七alt和弦:	大小小	5 7 2 4		#5或b13、b5或#11、#9、b9,旋律小调VII级
半减七和弦:	小小大	7 2 4 6 1 3 5	自然大调VII级
减七和弦(Co7):	小小小	7 2 4b6 1 3 5	和声小调VII级
增三和弦:	大大	1 3#5		旋律小调3级
Csus2:			1 2 5		
Csus4(Csus):		1 4 5

调式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
自然大调:	全全半全全全半,1 2 3 4 5 6 7 1
和声大调:	全全半全半三半,1 2 3 4 5b6 7 1
旋律大调:	全全半全半全全,1 2 3 4 5b6b7 1
自然小调:	全半全全半全全,6 7 1 2 3 4 5 6
和声小调:	全半全全半三半,6 7 1 2 3 4#5 6
旋律小调:	全半全全全全半,6 7 1 2 3#4#5 6
Ionian:		全全半全全全半,1 2 3 4 5 6 7 1,自然大调
Dorian:		全半全全全半全,2 3 4 5 6 7 1 2
Phrygian:	半全全全半全全,3 4 5 6 7 1 2 3
Lydian:		全全全半全全半,4 5 6 7 1 2 3 4
Mixolydian:	全全半全全半全,5 6 7 1 2 3 4 5
Aeolian:	全半全全半全全,6 7 1 2 3 4 5 6,自然小调
Locrian:	半全全半全全全,7 1 2 3 4 5 6 7
alter音阶:	半全半全全全全,1b2b3 3b5b6b7 1

自然大调4152637

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 C:	 C  D  E  F  G  A  B  C
#C:	#C #D #E #F #G #A #B #C
bD:	bD bE  F bG bA bB  C bD
 D:	 D  E #F  G  A  B #C  D
bE:	bE  F  G bA bB  C  D bE
 E:	 E #F #G  A  B #C #D  E
 F:	 F  G  A bB  C  D  E  F
#F:	#F #G #A  B #C #D #E #F
bG:	bG bA bB bC bD bE  F bG
 G:	 G  A  B  C  D  E #F  G
bA:	bA bB  C bD bE  F  G bA
 A:	 A  B #C  D  E #F #G  A
bB:	bB  C  D bE  F  G  A bB
 B:	 B #C #D  E #F #G #A  B

自然小调

1
2
3
4
5
6
7
 A:	 A  B  C  D  E  F  G  A
 B:	 B #C  D  E #F  G  A  B
 C:	 C  D bE  F  G bA bB  C
 D:	 D  E  F  G  A bB  C  D
 E:	 E #F  G  A  B  C  D  E
 F:	 F  G bA bB  C bD bE  F
 G:	 G  A bB  C  D bE  F  G

refer to:
https://weibo.com/p/1001603900313475143262

音乐中的英文单词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
属七升九和弦: dominant seventh sharp ninth chord
bD: D flat
调: key
纯五度: perfect 5th
半音音阶: chromatic scale
自然音阶: diatonic scale
经过音: passing tone
辅助音: neighboring tone/auxiliary tone/upper to lower
全音音阶: whole tone scale 
五声音阶: pentatonic scale
旋律小调: melodic minor
和声小调: harmonic minor
旋律音程: melodic interval
和声音程: harmonic interval
等音程: enharmonic interval
大三和弦: major triad
七和弦: seventh chord
第一转位: first inversion
 
二三四五六七九十度: 英语序数词
八度: octave
三全音: tri-tone
协和: consonant
不协和: dissonant
转调: modulation
移调: transposition
 
二全音符: breve
全音符: semibreve
二分音符: minim
四分音符: crotchet
八分音符: quaver
十六分音符: semiquaver
三十二分音符: demisemiquaver
六十四分音符: hemidemisemi quaver
 
二拍: duple meters(2/2, 2/4, 2/8)
三拍: triple meters(3/2, 3/4, 3/8)
四拍: quadruple meters(4/2, 4/4, 4/8)
五拍: quintuple meters
普通拍子: common meters
复二拍: compound duple meters(6/2, 6/4, 6/8)
复三拍: compound triple meters(9/4, 9/8)
复四拍: compound quadruple meters(12/4, 12/8, 12/16)
混合拍: irregular meters(7/4, 11/7)
 
二连音: duplet
三连音: triplet
四连音: quadruplet
五连音: quintuplet
六连音: sextuplet
本连音: septuplet
 
主音: tonic
上主音: supertonic
中音: mediant
下属音: subdominant
属音: dominant
下中音: submediant/super-dominant
导音: leading tone/subtonic
 
伊奥尼亚调式: ionian
多利亚调式: dorian
弗里及亚调式: phrygian
利底亚调式: lydian
混合利底亚调式: mixolydian
爱奥利亚调式: aeolian
洛克利亚调式: locrian
 
连音: legato
断音: staccato
持音: sostenuto
震音: trembolo
滑音: glissando
切分音: syncopation
先现音: anticipation
延现音: suspension
装饰音: ornament
颤音: trill
波音: mordent
逆波音: inverted mordent/lower mordent/schneller
复波音: double mordent
回音: inverted turn
琶音: arpeggio
模进: sequence
旋律模进: melodic sequence
和声模进: harmonic sequence
旋律进行: melodic progression
旋律轮廓: melodic contour
 
完全终止: perfect cadence
不完全终止: imperfect cadence
半终止: half cadence
正格终止: authentic cadence
变格终止: plagal cadence
阻碍终止: interrupted cadence
伪终止: deceptive cadence
 
三段式: temary form/ABA
变奏曲式: variation form/A, A1, A2, A3
分节歌: strophic form/a, a, a, ...
回旋曲式: rondo form/ABACA
奏鸣曲式: sonata form
 
前奏: prelude
间奏: interlude
尾声: coda
三声中部: trio
华彩乐段: cadanza
改编(缩编): reduction
 
独奏: solo
二重奏: duet
三重奏: trio
四重奏: quartet
五重奏: quintet
合奏: ensemble
 
受难曲: passion
交响曲: symphony
协奏曲: concerto
奏鸣曲: sonata
小奏鸣曲: sonatina
练习曲: etude
进行曲: march
序曲: overture
叙事曲: ballata
间奏曲: inter mezzo
随想曲: capriccio
幻想曲: fantasia
摇篮曲: lullaby
安魂曲: reguiem
小夜曲: serenade
夜曲: nocturn
狂想曲: rhapsody
小步舞曲: minuet
创意曲: invention
谐谑曲: scherzo
布鲁斯: blues
 
宣叙调: recitative
咏叹调: aria
 
管弦乐队: orchestra
指挥: conductor
指挥台: podium
长笛: flute
单簧管: charinet
小号: trumpet
短号: cornet
长号: trombone
大号: tuba
小提琴: violin
中提琴: viola
大提琴: cello
竖琴: harp
键盘乐器: clavier
木琴: xylophone
萨克斯管: saxophone
打击乐: percussion
手风琴: accordion
风琴: organ
 
女高音: soprano
女中音: mezzo soprano
男高音: tenor
男中音: bariton
 
文艺复兴: Renaissance
巴洛克: Baroque
洛可可: Rococo
复调: polyphony

refer to:
http://blog.sina.com.cn/s/blog_d2b7cd6a0102wts1.html
https://wenku.baidu.com/view/bbaca6e981c758f5f61f6779.html

C标准库中的strtok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
int main()
{
	char str[1000] = "Steven Jobs, Bruce Lee, Jack Chen, George W Bush";
	char* pNames[100];
	int idxNames = 0;
	char* pWords[100];
	int idxWords = 0;
	char* buf = str;
	char* outPtr = NULL;
	char* innerPtr = NULL;
	while (NULL != (buf = strtok_s(buf, ",", &outPtr)))
	{
		pNames[idxNames++] = _strdup(buf);
		while (NULL != (buf = strtok_s(buf, " ", &innerPtr)))
		{
			pWords[idxWords++] = buf;
			buf = NULL;
		}
	}
 
	return 0;
}

Windows驱动从设备名获取dos盘符路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
NTSTATUS querySymbolicLink(PUNICODE_STRING symbolicLinkName, PUNICODE_STRING linkTarget)
{
	OBJECT_ATTRIBUTES oa;
	NTSTATUS status;
	HANDLE handle;
 
	InitializeObjectAttributes(&oa, symbolicLinkName, OBJ_CASE_INSENSITIVE, 0, 0);
	status = ZwOpenSymbolicLinkObject(&handle, GENERIC_READ, &oa);
	if (!NT_SUCCESS(status))
		return status;
 
	linkTarget->MaximumLength = 200 * sizeof(WCHAR);
	linkTarget->Length = 0;
	linkTarget->Buffer = ExAllocatePool(PagedPool, linkTarget->MaximumLength);
	if (!linkTarget->Buffer)
	{
		ZwClose(handle);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	RtlZeroMemory(linkTarget->Buffer, linkTarget->MaximumLength);
 
	status = ZwQuerySymbolicLinkObject(handle, linkTarget, NULL);
	ZwClose(handle);
 
	if (!NT_SUCCESS(status))
	{
		ExFreePool(linkTarget->Buffer);
	}
	return status;
}
 
WCHAR *rtlVolumeDeviceToDosName(WCHAR *deviceName)
{
	NTSTATUS status;
	UNICODE_STRING driveLetterName;
	WCHAR driveLetterNameBuf[128];
	WCHAR c;
	WCHAR driLetter[3];
	UNICODE_STRING linkTarget;
 
	for (c = L'A'; c <= L'Z'; c++)
	{
		RtlInitEmptyUnicodeString(&driveLetterName, driveLetterNameBuf, sizeof(driveLetterNameBuf));
		RtlAppendUnicodeToString(&driveLetterName, L"\\??\\");
		driLetter[0] = c;
		driLetter[1] = L':';
		driLetter[2] = 0;
		RtlAppendUnicodeToString(&driveLetterName, driLetter);
 
		status = querySymbolicLink(&driveLetterName, &linkTarget);
		if (!NT_SUCCESS(status))
			continue;
 
		if (_wcsnicmp(linkTarget.Buffer, deviceName, linkTarget.Length) == 0)
		{
			deviceName += linkTarget.Length - 2;
			deviceName[0] = c;
			deviceName[1] = L":";
			ExFreePool(linkTarget.Buffer);
			break;
		}
		ExFreePool(linkTarget.Buffer);
	}
	return deviceName;
}
 
WCHAR *getDosPath(WCHAR *path)
{
	WCHAR device[] = L"\\Device\\";
 
	if (strIsStartWith(path, device))
	{
		path = rtlVolumeDeviceToDosName(path);
	}
 
	return path;
}

获取HANDLE对应的文件路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <Windows.h>
#include <psapi.h>
#include <wchar.h>
 
WCHAR *getFilePathByHandle(HANDLE hFile, WCHAR* filePath, int filePathLen)
{
	DWORD dwFileSizeHi = 0;
	DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
	HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileSizeLo, NULL);
 
	filePath[0] = 0;
	if (NULL != hFileMap)
	{
		void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
		if (NULL != pMem)
		{
			if (0 == GetMappedFileNameW(GetCurrentProcess(), pMem, filePath, filePathLen))
			{
				// GetLastError
			}
			UnmapViewOfFile(pMem);
		}
		CloseHandle(hFileMap);
	}
	return filePath;
}
 
wchar_t toLower(wchar_t ch)
{
	if ('A' <= ch && ch <= 'Z')
		ch = ch - 'A' + 'a';
	return ch;
}
 
int isNoCaseBeginWith(wchar_t* l, wchar_t* r)
{
	if (*l == 0 && *r == 0)
		return 1;
	if (*l == 0 || *r == 0)
		return 0;
	for (; 0 != *l && 0 != *r; l++, r++)
	{
		if (toLower(*l) != toLower(*r))
			return 0;
	}
	return 1;
}
 
WCHAR* getDosFilePath(WCHAR *dosPath, int len, WCHAR* kernelPath)
{
	wchar_t path[3] = L"C:";
	wchar_t szBuf[MAX_PATH] = { 0 };
	for (wchar_t ch = L'A'; ch <= L'Z'; ch++)
	{
		path[0] = ch;
		QueryDosDevice(path, szBuf, MAX_PATH);
		if (isNoCaseBeginWith(kernelPath, szBuf))
		{
			swprintf_s(dosPath, len, L"%s%s", path, kernelPath + wcslen(szBuf));
			return dosPath;
		}
	}
	dosPath[0] = 0;
	return dosPath;
}
 
int main()
{
	HANDLE hFile = CreateFileW(L"d:\\test.txt",
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		NULL,
		OPEN_EXISTING,
		0x00,
		NULL);
 
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return 0;
	}
 
	WCHAR path[1024];
	getFilePathByHandle(hFile, path, 1024);
 
	WCHAR dosPath[1024];
	getDosFilePath(dosPath, 1024, path);
 
	CloseHandle(hFile);
 
	return 0;
}