Α α alpha vowel Β β beta Γ γ gamma Δ δ delta Ε ε epsilon vowel Ζ ζ zeta /'zi:tə/ Η η eta vowel /'i:tə/ Θ θ theta Ι ι iota vowel /aɪ'əʊtə/ Κ κ kappa /'kæpə/ Λ λ lambda Μ μ mu /mju:/ Ν ν nu /nju:/ Ξ ξ xi /ksi/,/ˈksaɪ/,/ˈzaɪ/ Ο ο omicron vowel /əuˈmaikrən/,/ˈɑmɪˌkrɑn/ Π π pi Ρ ρ rho /rəʊ/ Σ σ/ς sigma Τ τ tau /tɔ:/,/taʊ/ Υ υ upsilon vowel /ˈipsilon/,/ˈʌpsɨlɒn/ Φ φ phi /faɪ/ Χ χ chi /kaɪ/ Ψ ψ psi /psaɪ/ Ω ω omega vowel
Month: May 2021
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 16 | 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 dsa: digital signature algorithm |
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 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 | C 1 3 5 C大三和弦 Cm 1 b3 5 C小三和弦 Caug 1 3 #5 C增和弦 Cdim 1 b3 b5 C减和弦 Csus2 1 2 5 C挂二和弦 Csus4 1 4 5 C挂四和弦 C6 1 3 5 6 C大六和弦 Cm6 1 b3 5 6 C小六和弦 Cm7 1 b3 5 b7 C小七和弦 Cmaj7 1 3 5 7 C大七和弦 C7 1 3 5 b7 C大小七和弦(C属七和弦) C7-5 1 3 b5 b7 C七减五和弦 Cm7-5 1 b3 b5 b7 C小七减五和弦 C7sus4 1 4 5 b7 C七挂四和弦 Cdim7 1 b3 b5 bb7 C减七和弦 Cmaj9 1 3 5 7 2 C大九和弦 Cm9 1 b3 5 7 2 C小九和弦 C9 1 3 5 b7 2 C属九和弦 Cadd9 1 3 5 2 C加九和弦 C11 1 3 5 b7 2 4 C属十一和弦 Cm11 1 b3 5 b7 2 4 C小十一和弦 C13 1 3 4 b7 2 4 6 C十三和弦 大七和弦: 大小大 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 六和弦: 3 5 1 四六和弦: 5 1 3 五六和弦: 3 5 7 1 三四和弦: 5 7 1 3 二和弦: 7 1 3 5 高密低疏中空 164536251 |
调式
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 |
十二平均律
1 2 3 4 5 6 7 8 9 10 11 12 13 | C 1 0 #C 1+1/24 1 D 1+1/8 2 #D 1+1/5 3 E 1+1/4 4 F 1+1/3 5 tritone sqrt(2) 6 G 1+1/2 7 #G 1+3/5 8 A 1+2/3 9 #A 1+4/5 10 B 1+7/8 11 octave 2 12 |
中国五声
1 2 3 4 | 宫 商 角 徵 羽 do re mi sol la 1 2 3 5 6 全 全 全半 全 |
日本五声
1 2 3 4 5 6 7 8 9 10 11 12 13 | 吕音阶(阳音阶) do re mi sol la 律音阶 sol la do re mi 全 全半 全 全 阴音阶上行形 1 2 b3 5 6 阴音阶下行形 1 2 b3 5 b6 la si do mi fa 6 7 1 3 4 全 半 全全 半 |
refer to:
https://weibo.com/p/1001603900313475143262
https://www.zhihu.com/question/34528429
https://blog.51cto.com/u_13753151/3158234
音乐中的英文单词
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 173 174 175 | 属七升九和弦: dominant seventh sharp ninth chord bD: D flat 调: key 音高: pitch 调律: temperament 纯五度: perfect 5th 小七度: Minor 7th 半音音阶: 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, whole note 二分音符: minim, half note 四分音符: 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 = Rocaille + Coquilles 复调: polyphony |
歌名后缀
1 2 3 4 5 6 7 8 9 10 11 | explicit 含脏话的 clean 去掉脏话的 feat. Jay 和Jay合作的 instrumental/inst. 无人声的 radio edit 电台编辑版 intro 引子 outro 尾声 acoustic/unplugged 不含电子合成音的 original 原唱 cover 翻唱 remix 重新混音 |
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 27 28 29 30 31 32 33 | #include <stdlib.h> #include <stdio.h> #include <string.h> #ifdef WIN32 #define EU_STRTOK strtok_s #define EU_STRDUP _strdup #else #define EU_STRTOK strtok_r #define EU_STRDUP strdup #endif 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; while (NULL != (buf = EU_STRTOK(NULL == outPtr? buf : NULL, ",", &outPtr))) { char* innerPtr = NULL; pNames[idxNames++] = EU_STRDUP(buf); while (NULL != (buf = EU_STRTOK(NULL == innerPtr? buf : NULL, " ", &innerPtr))) { pWords[idxWords++] = buf; } } return 0; // here, to watch pNames and pWords contents in debug mode. } |
strtok有一个缺陷,比如对于源串",hello,the,world!",分隔符",",分隔结果会少了空串""。
std版字符串token提取
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 | #include <iostream> #include <locale> #include <sstream> struct csv_whitespace : std::ctype<wchar_t> { bool do_is(mask m, char_type c) const { if ((m & space) && c == L' ') { return false; // space will NOT be classified as whitespace } if ((m & space) && c == L',') { return true; // comma will be classified as whitespace } return ctype::do_is(m, c); // leave the rest to the parent class } }; int main() { std::wstring in = L"Column 1, Column 2, Column 3\n123,456,789"; std::wstring token; std::wcout << "default locale:\n"; std::wistringstream s1(in); while (s1 >> token) { std::wcout << ">" << token << '\n'; } std::wcout << "locale with modified ctype:\n"; std::wistringstream s2(in); csv_whitespace* my_ws = new csv_whitespace; s2.imbue(std::locale(s2.getloc(), my_ws)); while (s2 >> token) { std::wcout << ">" << token << '\n'; } return 0; } |
std版宽字符转ASCII字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <iostream> #include <locale> int main() { std::locale loc; const char narrow_phrase[] = "Seventy-seven foxes"; wchar_t wide_phrase[sizeof(narrow_phrase)]; std::wcout << L"The first wide character is: "; wchar_t wc = std::use_facet<std::ctype<wchar_t>>(loc).widen(*narrow_phrase); std::wcout << wc << std::endl; std::wcout << L"The wide-character phrase is: "; std::use_facet<std::ctype<wchar_t>>(loc).widen(narrow_phrase, narrow_phrase + sizeof(narrow_phrase), wide_phrase); std::wcout << wide_phrase << std::endl; return 0; } |
std版日期字符串解析
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 | #include <iostream> #include <sstream> #include <locale> #include <iomanip> int main() { std::tm t = {}; std::istringstream ss("2011-Februar-18 23:12:34"); //ss.imbue(std::locale("de_DE.utf-8")); try { ss.imbue(std::locale("de-DE")); } catch (std::exception e) { std::cout << e.what() << std::endl; } ss >> std::get_time(&t, "%Y-%b-%d %H:%M:%S"); if (ss.fail()) { std::cout << "Parse failed\n"; } else { std::cout << std::put_time(&t, "%c") << '\n'; } return 0; } |
refer to:
https://en.cppreference.com/w/cpp/locale/locale/name
https://social.msdn.microsoft.com/Forums/en-US/0fb287af-bb58-4c60-a3da-14fe84c16948/stdlocaleglobalstdlocalequotzhcnquot-gets-quotbad-locale-namequot?forum=vcgeneral
https://docs.microsoft.com/en-us/cpp/c-runtime-library/locale-names-languages-and-country-region-strings?redirectedfrom=MSDN&view=msvc-160
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; } |