mirror of
https://github.com/reactos/reactos
synced 2025-10-06 08:22:58 +02:00
Compare commits
876 Commits
ReactOS-0.
...
ReactOS-0.
Author | SHA1 | Date | |
---|---|---|---|
|
6caaf63c2c | ||
|
90e1f4cbf9 | ||
|
921363d647 | ||
|
8234dea660 | ||
|
88cb154d19 | ||
|
faac123528 | ||
|
e857e97df1 | ||
|
d508a1f0bf | ||
|
013fc117b8 | ||
|
3d1f2d98ba | ||
|
de66c40007 | ||
|
6cc53dd4b3 | ||
|
fb7f4582cd | ||
|
a11a76eaef | ||
|
be132afdf2 | ||
|
686387f8e0 | ||
|
492a608e06 | ||
|
fd411d8b8c | ||
|
6f3d53f751 | ||
|
462fe323eb | ||
|
4d8c6a710b | ||
|
623093eaaa | ||
|
453f513ed3 | ||
|
57919a833e | ||
|
e6b5c8bfc7 | ||
|
974095c413 | ||
|
a8ca53d761 | ||
|
c54d897571 | ||
|
17afcb4dfd | ||
|
2284e742b3 | ||
|
c7580dacf3 | ||
|
9446011fc1 | ||
|
586433918e | ||
|
b9579544e7 | ||
|
005106acbb | ||
|
38d1018911 | ||
|
ea5959a772 | ||
|
6b50f46c2f | ||
|
4d5643a96a | ||
|
128cfc8af0 | ||
|
a7a23b4dc3 | ||
|
dbd051cad4 | ||
|
1667a4589a | ||
|
6a617736e9 | ||
|
d832a87f14 | ||
|
13541861b1 | ||
|
dfa5f04c63 | ||
|
cc5dc64c30 | ||
|
8abc09ec0d | ||
|
5b86e3a918 | ||
|
e5b9e13d59 | ||
|
bfaef27782 | ||
|
4e94397e24 | ||
|
683932b845 | ||
|
4ce5c9d3b4 | ||
|
6b53b3acea | ||
|
81547d8842 | ||
|
1b0b103796 | ||
|
98a6084104 | ||
|
96aed594a2 | ||
|
ca6a107ee2 | ||
|
414cd229d9 | ||
|
a09b668be6 | ||
|
7f63532d94 | ||
|
8bbcdc3d4a | ||
|
43d5d0b2f0 | ||
|
a409988b36 | ||
|
33009b967e | ||
|
4c2f15bfb9 | ||
|
c40b27bbc4 | ||
|
ac7a3aa542 | ||
|
90e6a2244e | ||
|
8c2f4d55e3 | ||
|
9a22766e36 | ||
|
53b1677997 | ||
|
2cecd9846d | ||
|
f822a2a9d9 | ||
|
a590b25e46 | ||
|
5d2dc4de65 | ||
|
55fef42029 | ||
|
0ce89e21d9 | ||
|
910f27a570 | ||
|
14ac854378 | ||
|
e0e40991af | ||
|
db262c9a74 | ||
|
81310b4307 | ||
|
77c8585f1c | ||
|
43f46ed4f8 | ||
|
66f738dbd1 | ||
|
45043db6ff | ||
|
b14104f1e7 | ||
|
424d757107 | ||
|
a1c7df6990 | ||
|
c7b7c5b0b6 | ||
|
815a52debe | ||
|
dbf662da37 | ||
|
5d99e9003a | ||
|
ec235d7468 | ||
|
f09720f7d7 | ||
|
258912bf48 | ||
|
9d84d82bd7 | ||
|
904da6e474 | ||
|
915ff9328d | ||
|
61c3984818 | ||
|
4a02ce0c1e | ||
|
f30ade19b8 | ||
|
9530a7d656 | ||
|
5716745a13 | ||
|
680589c149 | ||
|
2efd99afb2 | ||
|
b001203a86 | ||
|
09edfdc32f | ||
|
ae12418822 | ||
|
f9d4545552 | ||
|
bb25ff0f3a | ||
|
4b70175e11 | ||
|
ba58b241e5 | ||
|
7c574c2d6e | ||
|
47551b9846 | ||
|
d0c1e25256 | ||
|
d4c340c696 | ||
|
43014d0391 | ||
|
e28f90e740 | ||
|
ead0eeacdd | ||
|
cf693462e6 | ||
|
67ad8387f3 | ||
|
eae47571c9 | ||
|
2ea8bb5aa4 | ||
|
13436cd7f7 | ||
|
3bee100dae | ||
|
2eccd28b8f | ||
|
d2c016b5ab | ||
|
b72dc46819 | ||
|
e2e5efb9d7 | ||
|
6d3a97eb5e | ||
|
0d630c9ee3 | ||
|
8b829113cb | ||
|
c18e7f06ce | ||
|
dfa8364302 | ||
|
ed3ca3d52c | ||
|
e77c8000db | ||
|
05a567fce3 | ||
|
9b614b887d | ||
|
1a0765f6c5 | ||
|
ec4a27aeb7 | ||
|
b986ce1cac | ||
|
e510811de7 | ||
|
a7e6e9c1f8 | ||
|
64915d3ebe | ||
|
c8689122b1 | ||
|
e0c1e02c47 | ||
|
b09592bf32 | ||
|
174adb3955 | ||
|
8a20ddc7d4 | ||
|
82a0c31208 | ||
|
d25098ba0c | ||
|
aba30a453f | ||
|
fde8b62215 | ||
|
e04faee634 | ||
|
0d7b93783b | ||
|
b361e13fab | ||
|
44744d8d36 | ||
|
614f99e406 | ||
|
6e605e712e | ||
|
96d5e2c715 | ||
|
6767fd7f43 | ||
|
85a3f3844c | ||
|
c114003cb5 | ||
|
c52cbf8517 | ||
|
abd233d61a | ||
|
b0ff680e0e | ||
|
1a8f8005ae | ||
|
5bc02dd95a | ||
|
44866ccf87 | ||
|
d431c0fa6d | ||
|
58b907b668 | ||
|
761e03c5a1 | ||
|
ea4204ce87 | ||
|
eae6fb6efc | ||
|
157d5b3fa2 | ||
|
63665d54ed | ||
|
eb2d1c2110 | ||
|
dbbb7e41f0 | ||
|
6758f479ef | ||
|
18a01fd10d | ||
|
cfb22d72df | ||
|
83c2d22a5e | ||
|
96c9969a90 | ||
|
f0f8791763 | ||
|
31c5b7839f | ||
|
dabbe50e39 | ||
|
68fbd54f2c | ||
|
766e6a262e | ||
|
c1795e9778 | ||
|
f886c2b9d6 | ||
|
7d45bbd5da | ||
|
8d87ab9d07 | ||
|
95fcdd0943 | ||
|
11d7e1e18c | ||
|
863afe8930 | ||
|
788e4dc053 | ||
|
125a62f79a | ||
|
99d62b4808 | ||
|
3c1e76b027 | ||
|
2bd986927c | ||
|
ad5e850736 | ||
|
6cc79a481e | ||
|
c0b2b118a0 | ||
|
a53e883bb0 | ||
|
bb0715f8e7 | ||
|
bc08c68af9 | ||
|
28df2503d3 | ||
|
a5dd3430d6 | ||
|
36f33622cc | ||
|
583a7209da | ||
|
727671f12a | ||
|
13e2e79e44 | ||
|
0300e2a9d1 | ||
|
ec16aa4c44 | ||
|
e6f624f0e7 | ||
|
7228dc135c | ||
|
d2e85caa9e | ||
|
bff71dc524 | ||
|
a0570e7cbe | ||
|
ff9ce85a65 | ||
|
f3d9743503 | ||
|
a66a6e5dba | ||
|
8690858184 | ||
|
9e4fec3838 | ||
|
8001413b88 | ||
|
bae73138e8 | ||
|
dad291cf6f | ||
|
22b26024cd | ||
|
3e6e6c12ee | ||
|
93a0fa88d2 | ||
|
9b2fc03fc7 | ||
|
7975fc7fe7 | ||
|
a23adc0492 | ||
|
36e229b42f | ||
|
29812be566 | ||
|
4551dfba1e | ||
|
babfe77ea9 | ||
|
81a9f1c4b0 | ||
|
74031c2379 | ||
|
348ccdd39f | ||
|
1d4d689bf2 | ||
|
8578ba8ac6 | ||
|
a77eef4a53 | ||
|
648301897c | ||
|
2076e94020 | ||
|
c2829c9869 | ||
|
49f51f37f3 | ||
|
1e637da493 | ||
|
51cbed48ab | ||
|
e8abc51177 | ||
|
29f5cf1341 | ||
|
c33edc6cb7 | ||
|
1d786dd865 | ||
|
3174c5069a | ||
|
d63c23131c | ||
|
56e30e8907 | ||
|
1241612f69 | ||
|
ddc9e680c9 | ||
|
15e29ff254 | ||
|
52498a577a | ||
|
ee3dc0f0c1 | ||
|
58eedf7620 | ||
|
e6359887bb | ||
|
cda1c38bae | ||
|
d82310b692 | ||
|
45dd256ee3 | ||
|
e0058203bb | ||
|
3255097117 | ||
|
40f81ce970 | ||
|
bbcc7f9179 | ||
|
0c91339480 | ||
|
5249698af3 | ||
|
037d59aef7 | ||
|
70f14aa73f | ||
|
b779c01fb6 | ||
|
fe56845ebe | ||
|
70140f5ea7 | ||
|
fe27d316df | ||
|
1fc6701c79 | ||
|
09d88da5e9 | ||
|
a06d619eca | ||
|
242138f832 | ||
|
af1ff6be3b | ||
|
8c0b595a5e | ||
|
4280f4f60d | ||
|
d5014c3bb3 | ||
|
d81a116aba | ||
|
155d1ff5ae | ||
|
fbccd722a1 | ||
|
648c68ff1a | ||
|
c92eafe2f1 | ||
|
b0e64d6cf7 | ||
|
fa74a12186 | ||
|
40bd704148 | ||
|
4027ccab60 | ||
|
ff511b446a | ||
|
e31d342bc7 | ||
|
7cf48757dc | ||
|
07a2fbf7f7 | ||
|
fa3a5c2c71 | ||
|
5aaaad5c93 | ||
|
7bcdd2ea10 | ||
|
a35e54e5f8 | ||
|
0b84d00506 | ||
|
c4385e9139 | ||
|
2c4de44226 | ||
|
1f636015ba | ||
|
e9703bfa98 | ||
|
676e6609ce | ||
|
dbb9546d9d | ||
|
007128eb66 | ||
|
90129544e0 | ||
|
f72b0c8878 | ||
|
36df88668d | ||
|
9957d94c20 | ||
|
2a466eda80 | ||
|
6cb529270a | ||
|
cb7f83ac74 | ||
|
9907c63794 | ||
|
fc200ca733 | ||
|
bebdd316d5 | ||
|
e7cf9302fa | ||
|
69dc48c09f | ||
|
e3c471cf82 | ||
|
0063a30376 | ||
|
b9a38fb83d | ||
|
1ff56406ca | ||
|
c69899317f | ||
|
b3995a1493 | ||
|
3975f17012 | ||
|
3f261fab5d | ||
|
b6ae20fcd0 | ||
|
d2eea59593 | ||
|
6ac1592420 | ||
|
04f2911330 | ||
|
743df9ab84 | ||
|
e2a59404d8 | ||
|
367fbb2a1f | ||
|
932d4770ec | ||
|
0584d3755f | ||
|
221e27f1fa | ||
|
581f2c7495 | ||
|
6ef820374f | ||
|
ce373b0c40 | ||
|
01034d9c59 | ||
|
fad2f584e9 | ||
|
86b93a6ac8 | ||
|
6fcd126954 | ||
|
2a01ea22a9 | ||
|
84d1d53870 | ||
|
5050cf437e | ||
|
9162781f47 | ||
|
b63d64cc90 | ||
|
858aaeac37 | ||
|
bd4786ea76 | ||
|
bcb831f3c9 | ||
|
1bfb0f94d9 | ||
|
10f222cd92 | ||
|
7f7c26ae4d | ||
|
56b4626f56 | ||
|
b3f7f2d945 | ||
|
4d7dcc6886 | ||
|
8ae06e50f1 | ||
|
19a76ae9af | ||
|
15714a3ea7 | ||
|
9ccf887c5a | ||
|
62cdaf7f99 | ||
|
fdb2041671 | ||
|
11cbd32ea6 | ||
|
8d5b94094a | ||
|
3d0fe049f6 | ||
|
1e589af8e1 | ||
|
6409ce374c | ||
|
11d31698d5 | ||
|
e0c5a61982 | ||
|
d913de5c14 | ||
|
5b3ccbfc02 | ||
|
f2a6a55325 | ||
|
4aa2c7952d | ||
|
b54e7a6efa | ||
|
8ae5eb02c7 | ||
|
34a9792f1e | ||
|
44a536a421 | ||
|
c5e296fcf0 | ||
|
c8cd1fe03c | ||
|
0a1f866c8f | ||
|
a5e573f1b3 | ||
|
06938a9103 | ||
|
b5118cc48f | ||
|
31268dc661 | ||
|
9dc68f3b65 | ||
|
1af4e48747 | ||
|
154db698c9 | ||
|
f298282475 | ||
|
9083091f7b | ||
|
c4ba9a330d | ||
|
46a0e6e16e | ||
|
f53177b2b2 | ||
|
380ae8a262 | ||
|
28f788e6ed | ||
|
126768af64 | ||
|
0deeaa0d83 | ||
|
da7f2bf2b2 | ||
|
6709ff7e24 | ||
|
d415ba8508 | ||
|
9377d51b1a | ||
|
662c77c00c | ||
|
5169949e78 | ||
|
480d6d6388 | ||
|
389b5fe480 | ||
|
d89e0df163 | ||
|
36a7c3cf0d | ||
|
b887962d1d | ||
|
5f710be5ef | ||
|
47ee1b5a90 | ||
|
c9b6355479 | ||
|
5c91ed98f2 | ||
|
1cdff7f03d | ||
|
d21b624ded | ||
|
4b60f335f5 | ||
|
c805537640 | ||
|
2b96374f2a | ||
|
2854aac246 | ||
|
ae32243b6a | ||
|
ed003aa199 | ||
|
ebf6630e2b | ||
|
2a87426631 | ||
|
e30ffd7e27 | ||
|
659762910c | ||
|
cfe42a37eb | ||
|
42dfa65049 | ||
|
d22c45fab2 | ||
|
f234e93d1e | ||
|
905776a29b | ||
|
56b16dbf01 | ||
|
9ade7d9aaf | ||
|
3bc13b6875 | ||
|
cf7d159791 | ||
|
0495cfd8d4 | ||
|
77360caec8 | ||
|
64f28f26bd | ||
|
e3876459ef | ||
|
72df55f2e2 | ||
|
55b8b93555 | ||
|
b06daa620f | ||
|
6275e70165 | ||
|
0344d1a114 | ||
|
7aaccee0e9 | ||
|
b5d3b3bf2d | ||
|
5d7bcb07bd | ||
|
9ef17eada6 | ||
|
b9bbf8287b | ||
|
88df0b7726 | ||
|
c6b0f56200 | ||
|
0a70b0080a | ||
|
b2274fda0d | ||
|
6ddcb50e38 | ||
|
19c00dc04f | ||
|
acc9e8fbc3 | ||
|
3ed33156f2 | ||
|
d2e0015ab7 | ||
|
4251bd8513 | ||
|
60f4a025ef | ||
|
9bdf8fd314 | ||
|
e1e75da515 | ||
|
2711eadf8a | ||
|
2eb223d16f | ||
|
7e62c34fdd | ||
|
603bb75198 | ||
|
db37f2cecd | ||
|
76691783b3 | ||
|
fc506149ce | ||
|
5edb029d51 | ||
|
acd3d263c1 | ||
|
a2e9c0c7a4 | ||
|
d0fbe6c728 | ||
|
6bac8b1c92 | ||
|
3f9e43cbf2 | ||
|
078d8a8502 | ||
|
d927063dd4 | ||
|
ffbc9d9c03 | ||
|
6a7adfd71f | ||
|
e9ecf45119 | ||
|
169894bcc5 | ||
|
b9354028e0 | ||
|
0107a0743b | ||
|
901449bfe8 | ||
|
09b99f1097 | ||
|
7f7d1d57b0 | ||
|
25cd7e1e5a | ||
|
3cee782a23 | ||
|
ae4cb21e55 | ||
|
27cfdf8b3b | ||
|
0064915ad7 | ||
|
14e5e06271 | ||
|
781ba31ad3 | ||
|
0072db2e5e | ||
|
70b2252a9d | ||
|
bc291ce04e | ||
|
73d37669c4 | ||
|
d5f96518f2 | ||
|
490e4d94fc | ||
|
ddd8467f99 | ||
|
278a6c540b | ||
|
241b23c24d | ||
|
c842409323 | ||
|
e5bfd35667 | ||
|
f661ec6b08 | ||
|
27de25f464 | ||
|
e68d320afc | ||
|
56461438cb | ||
|
cee2ad3925 | ||
|
9f95b317f2 | ||
|
2890508a82 | ||
|
97c1f757f6 | ||
|
98a3f0d6f5 | ||
|
67d7e92025 | ||
|
54378dbf2a | ||
|
321081bb62 | ||
|
ad3c512ae2 | ||
|
3fe1c6d5f4 | ||
|
36322cffcd | ||
|
73a193b7fe | ||
|
94f82b0796 | ||
|
81b9b25bc7 | ||
|
db068d0cae | ||
|
dcd4ed3e62 | ||
|
9adc8d3ca1 | ||
|
d2f7f11cfc | ||
|
4946832715 | ||
|
5a3243d494 | ||
|
6f801aae22 | ||
|
6becb71b7c | ||
|
a1418887c0 | ||
|
1644f93c49 | ||
|
464c5c2187 | ||
|
eda973b1cc | ||
|
7e74c066a7 | ||
|
64037e6939 | ||
|
079a92a658 | ||
|
ff1e3c7b18 | ||
|
731f19e9b1 | ||
|
ebb6fcbc30 | ||
|
97c260445b | ||
|
5d97b74881 | ||
|
ed08466464 | ||
|
b68aceef62 | ||
|
42965fae3b | ||
|
600e81c60c | ||
|
0691de94b5 | ||
|
d837d19fac | ||
|
eee72fe55d | ||
|
98d0da7e1c | ||
|
7c8b54eee0 | ||
|
fd78805ffc | ||
|
9221d5c854 | ||
|
5503a0f0e4 | ||
|
99fa281af1 | ||
|
29b9e3f0b4 | ||
|
0c6333ed01 | ||
|
e8cbdde2a7 | ||
|
de56bed16d | ||
|
5a25898d41 | ||
|
fbe6ae7bc0 | ||
|
a3576ceb06 | ||
|
63a3377143 | ||
|
240b550d9c | ||
|
839118b9b3 | ||
|
472aba6da2 | ||
|
d7acbe2251 | ||
|
3763d9c0dd | ||
|
3277301592 | ||
|
572d45daca | ||
|
e4bcefde7d | ||
|
74b0d03ccc | ||
|
9e3fe0593a | ||
|
aa77254872 | ||
|
bbc8fd7b21 | ||
|
dff0889c02 | ||
|
03f9e7b713 | ||
|
fbcc7fb423 | ||
|
140b387c62 | ||
|
867fa342e3 | ||
|
db7bc7b4e8 | ||
|
e4981e3a09 | ||
|
42c50bfaa8 | ||
|
8688a2a272 | ||
|
3f0a7424cb | ||
|
00f2fc414e | ||
|
4f928dad27 | ||
|
150a9789e6 | ||
|
b3c424cd40 | ||
|
8bf8d53376 | ||
|
5bd64e22e4 | ||
|
0dc103b08e | ||
|
108fcceee2 | ||
|
b172b0df42 | ||
|
9f7f2c0f72 | ||
|
af3d943b02 | ||
|
d704562082 | ||
|
bf4de1d7cd | ||
|
f6a2bede37 | ||
|
282bc306f8 | ||
|
481a3a687c | ||
|
48f92902c5 | ||
|
0c215b202d | ||
|
98071efc7e | ||
|
ad037179b4 | ||
|
9d1624980f | ||
|
3276df883d | ||
|
7994f333ab | ||
|
49d35cfc27 | ||
|
a1c0b9b92a | ||
|
75a9d9fc5f | ||
|
a0945c2aa2 | ||
|
ee4c094831 | ||
|
9ee6327262 | ||
|
24160311c0 | ||
|
275be13b58 | ||
|
3a2897ef52 | ||
|
2e61a84b9d | ||
|
c00639bf8c | ||
|
09abfa6348 | ||
|
01f4ff78c5 | ||
|
9fd228d402 | ||
|
1db33360e3 | ||
|
97a4cb23d5 | ||
|
eec445ded5 | ||
|
5a9cee4031 | ||
|
b7b31cec92 | ||
|
15df73e6b3 | ||
|
d58a6ad5d6 | ||
|
7946500988 | ||
|
d9625dff78 | ||
|
e66f3f0e7b | ||
|
b57dd9d5b6 | ||
|
f929f4c00b | ||
|
eef71ffb98 | ||
|
87028edf14 | ||
|
38c0489092 | ||
|
77ed4e360b | ||
|
37f381130a | ||
|
f6e36a9f86 | ||
|
2c7fb0c72e | ||
|
4ad5db5d9c | ||
|
95a2cd9225 | ||
|
ddbc094b81 | ||
|
4e237f23ce | ||
|
93e68a6285 | ||
|
17a714dfcd | ||
|
25f46657b5 | ||
|
e177bf992c | ||
|
c3e2bc8f4d | ||
|
bd305c8221 | ||
|
b16dd07968 | ||
|
bc669554a9 | ||
|
276842493c | ||
|
32835c2a47 | ||
|
edabb16494 | ||
|
d4164f1a07 | ||
|
ace5da2d0d | ||
|
6752566cd2 | ||
|
2c6653bf1c | ||
|
6cbc9243c9 | ||
|
9c602cda2e | ||
|
fc52fb7648 | ||
|
621baeefa5 | ||
|
9f5cc5a859 | ||
|
00ec608e15 | ||
|
2f1849aae9 | ||
|
36714219d9 | ||
|
6e66d97592 | ||
|
cadd577325 | ||
|
d6995d6c9c | ||
|
638ba1c9e4 | ||
|
9e65542bad | ||
|
3315d25a64 | ||
|
a649212d32 | ||
|
4b8117cedc | ||
|
b9da76d7ef | ||
|
0a828ed745 | ||
|
a943c76484 | ||
|
70f7c7269c | ||
|
02e70516ef | ||
|
e5dfcc9871 | ||
|
f8492b9ae3 | ||
|
6bee27aa2a | ||
|
dbad901d31 | ||
|
e51b6b925d | ||
|
f45b570cc3 | ||
|
55d6c152b6 | ||
|
3aed7d1da4 | ||
|
df27ab373b | ||
|
67c37a748e | ||
|
d4195242ff | ||
|
9bcc89126c | ||
|
d7a481490e | ||
|
bfd196dfd9 | ||
|
f4e6240546 | ||
|
5ba4cc87c5 | ||
|
e999320cb5 | ||
|
88987510df | ||
|
5cb80487c2 | ||
|
3fcccd0b8c | ||
|
a984daa5de | ||
|
9a068f8b4b | ||
|
0bcca89137 | ||
|
531f88e833 | ||
|
a3232e28c6 | ||
|
1908a698e8 | ||
|
97b7ce3ac3 | ||
|
f03f3933bc | ||
|
85e4809132 | ||
|
e9b21d3c1d | ||
|
f9a230ad49 | ||
|
efa169ca61 | ||
|
8f3084dc6d | ||
|
93afbbc9d6 | ||
|
5998255e83 | ||
|
a1fca3d3ae | ||
|
1e4904f8dd | ||
|
ac9c590908 | ||
|
107f6406fc | ||
|
12ea84e3c9 | ||
|
8551dc320b | ||
|
512966336f | ||
|
ed27871348 | ||
|
51f310e703 | ||
|
804bfa6fb9 | ||
|
c2059de8af | ||
|
73d2af04d9 | ||
|
d01f8c3180 | ||
|
6298d37c71 | ||
|
dd705acbd0 | ||
|
455be0fece | ||
|
2d3181f734 | ||
|
2b59b2c1c2 | ||
|
3c80407d9b | ||
|
93b8081eed | ||
|
a044d562b8 | ||
|
523aba9a89 | ||
|
b0cbc91ce1 | ||
|
dc7be08202 | ||
|
01e34a063a | ||
|
29ef6b5bac | ||
|
4159ed2941 | ||
|
1e09a4813f | ||
|
36902d624f | ||
|
4850652d25 | ||
|
c92156be04 | ||
|
17b6b4d72a | ||
|
66658f3d1a | ||
|
35f07df64f | ||
|
06a593cc64 | ||
|
20ef31f3cc | ||
|
2d14c3e110 | ||
|
02e3d7b08e | ||
|
d55d012d33 | ||
|
de8fc633f8 | ||
|
3244132cc7 | ||
|
6ce4528a80 | ||
|
43fd2f2579 | ||
|
a984573ad4 | ||
|
6fd4505b6f | ||
|
4209cfec73 | ||
|
e007300ee0 | ||
|
3ecc11334b | ||
|
1628f7a89e | ||
|
b161ff0650 | ||
|
6cd2bc16b8 | ||
|
a9ce8c6379 | ||
|
5d1ddcb775 | ||
|
962e8486ea | ||
|
8f8c71dfb9 | ||
|
e017266cd0 | ||
|
316713be6b | ||
|
937e125ad7 | ||
|
43c24d3654 | ||
|
7e398d4e22 | ||
|
0d71cd85bd | ||
|
f5d7376e5a | ||
|
570be7966c | ||
|
6b8cb5c939 | ||
|
6eaf6180fd | ||
|
4bc75819a3 | ||
|
8587170853 | ||
|
683ed8c5a1 | ||
|
bc06faa8cd | ||
|
4bc8aa3713 | ||
|
b097125d77 | ||
|
13e75fd710 | ||
|
37af92952e | ||
|
159ee3800d | ||
|
82d21c903e | ||
|
b6187e2de7 | ||
|
98d405409a | ||
|
ce0b82afeb | ||
|
fd5a21279e | ||
|
e96765787f | ||
|
a06ebb79bb | ||
|
f075faafdf | ||
|
043bc3b058 | ||
|
a3a5ebb7c7 | ||
|
f93f98a522 | ||
|
93263fa722 | ||
|
d6830ac891 | ||
|
1302d0fe3b | ||
|
45a6e16434 | ||
|
c89930f961 | ||
|
bc9bf59740 | ||
|
a998ae77b0 | ||
|
7499a5965d | ||
|
f530e60c76 | ||
|
409861205e | ||
|
33e768c8cd | ||
|
5dd16d52fe | ||
|
3c0b32b97a | ||
|
b5be07756f | ||
|
8134515a1a | ||
|
a3fbbaa42d | ||
|
8b29e69d3d | ||
|
e3a11b68b8 | ||
|
09215f3126 | ||
|
e68e2e431a | ||
|
267b8c4e8c | ||
|
dc5f3e0195 | ||
|
74ff8524ad | ||
|
37529daf35 | ||
|
d0c8759887 | ||
|
8909f04b2c | ||
|
e1d692c393 | ||
|
1d9a6c728c | ||
|
0805f2913e | ||
|
135e1512ef | ||
|
a7dd9bd3f9 | ||
|
6144b903c3 | ||
|
3afc66723c | ||
|
537bf0fdf6 | ||
|
c38258c97a | ||
|
3f988bd286 | ||
|
ee81c811cd | ||
|
645218d5c8 | ||
|
5c0fb0f108 | ||
|
22ebf085eb | ||
|
cb0fe70650 | ||
|
9a55f0f7ed | ||
|
7967ac94a2 | ||
|
4bbc8ea6ef | ||
|
099d789b13 | ||
|
6bdaf42c26 | ||
|
40473b6aba | ||
|
ffc37c2cfd | ||
|
e8652909ce | ||
|
153b0ad928 | ||
|
ca01965c67 | ||
|
b903d86810 | ||
|
809b4b1eab | ||
|
bb9cc48934 | ||
|
f29364e917 | ||
|
38389db926 | ||
|
50b41bfae6 | ||
|
b40b785ec0 | ||
|
35cc27eee0 | ||
|
bbddb2c838 | ||
|
b4be455beb | ||
|
2fe2a748af | ||
|
4ef8280497 | ||
|
1189c35dd7 | ||
|
9cef58c15d | ||
|
cdafa11dc1 | ||
|
b5efc5cfc5 |
2
reactos/.cvsignore
Normal file
2
reactos/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
errors
|
14
reactos/CREDITS
Normal file
14
reactos/CREDITS
Normal file
@@ -0,0 +1,14 @@
|
||||
In no particular order
|
||||
|
||||
Rex Jolliff (rex@lvcablemodem.com)
|
||||
Boudewijn Dekker (ariadne@xs4all.nl)
|
||||
Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
Emanuele Aliberti (ea@iol.it)
|
||||
David Welch (welch@cwcom.net)
|
||||
Iwan Fatahi (i_fatahi@hotmail.com)
|
||||
Robert Bergkvist (fragdance@hotmail.com)
|
||||
Victor Kirhenshtein (sauros@iname.com)
|
||||
Jason Filby (jasonfilby@yahoo.com)
|
||||
Brian Palmer (brianp@sginet.com)
|
||||
Phillip Susi (phreak@iag.net)
|
||||
Paolo Pantaleo (paolopan@freemail.it)
|
12
reactos/ChangeLog
Normal file
12
reactos/ChangeLog
Normal file
@@ -0,0 +1,12 @@
|
||||
9/6/99: Implemented ZwOpenProcess
|
||||
Partially implemented killing other threads (possible memory
|
||||
leaks)
|
||||
Made a start on a proper implemention of APCs (based on
|
||||
article in NT insider)
|
||||
|
||||
8/12/98: Corrected bug in shell (Read two keypresses and assumed they
|
||||
where the key going up and down respectively)
|
||||
Corrected race in dpc handling
|
||||
Took out cleanup sections in ZwReadFile (now handled by the APC)
|
||||
Disabled broken code in kernel32
|
||||
|
31
reactos/INSTALL
Normal file
31
reactos/INSTALL
Normal file
@@ -0,0 +1,31 @@
|
||||
1. Build environment
|
||||
|
||||
To build the system you need either mingw32 installed on Windows or a
|
||||
mingw32 cross compiler running on unix.
|
||||
|
||||
2. Building
|
||||
|
||||
To build from Windows run make. To build from unix, edit rules.mak and change
|
||||
the PREFIX variable to the correct value for your cross-compiler, then run
|
||||
'make'.
|
||||
|
||||
3. Installation
|
||||
|
||||
Installation isn't yet automated, sorry. The system can only be installed on
|
||||
the first partition which must be formatted for DOS. Set up a directory
|
||||
structure like the following
|
||||
|
||||
make directories C:\reactos,C:\reactos\system,C:\reactos\system\drivers
|
||||
|
||||
Copy apps/shell/shell.exe to C:\reactos\system32
|
||||
Copy subsys/smss/smss.exe to C:\reactos\system32
|
||||
Copy services/dd/keyboard/keyboard.sys to C:\reactos\system32\drivers
|
||||
Copy services/dd/blue/blue.sys to C:\reactos\system32\drivers
|
||||
Copy lib/ntdll/ntdll.dll to C:\reactos\system32
|
||||
Copy lib/kernel32/kernel32.dll to C:\reactos\system32
|
||||
Copy lib/crtdll/crtdll.dll to C:\reactos\system32
|
||||
|
||||
The system can only be started from DOS. Copy the following files,
|
||||
services/dd/ide/ide.sys, services/fs/vfat/vfatfsd.sys and
|
||||
loaders/dos/loadros.com, to a suitable directory. The system can then be
|
||||
booted with the command 'loadros.com ide.sys vfatfsd.sys'.
|
280
reactos/Makefile
Normal file
280
reactos/Makefile
Normal file
@@ -0,0 +1,280 @@
|
||||
#
|
||||
# Global makefile
|
||||
#
|
||||
|
||||
#
|
||||
# Select your host
|
||||
#
|
||||
#HOST = mingw32-linux
|
||||
#HOST = djgpp-msdos
|
||||
#HOST = mingw32-windows
|
||||
|
||||
include rules.mak
|
||||
|
||||
#
|
||||
# Required to run the system
|
||||
#
|
||||
COMPONENTS = iface_native ntoskrnl
|
||||
DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32
|
||||
#DLLS = mingw32 user32
|
||||
SUBSYS = smss win32k
|
||||
#SUBSYS = csrss
|
||||
|
||||
#
|
||||
# Select the server(s) you want to build
|
||||
#
|
||||
SERVERS = win32
|
||||
# SERVERS = posix linux os2
|
||||
|
||||
#
|
||||
# Select the loader(s) you want to build
|
||||
#
|
||||
LOADERS = dos
|
||||
# LOADERS = boot
|
||||
|
||||
#
|
||||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
DEVICE_DRIVERS = blue ide keyboard null parallel serial
|
||||
# DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1
|
||||
FS_DRIVERS = vfat
|
||||
# FS_DRIVERS = minix ext2 template
|
||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
|
||||
|
||||
APPS = args hello shell test cat bench apc shm lpc thread event
|
||||
|
||||
all: buildno $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
|
||||
|
||||
.PHONY: all
|
||||
|
||||
clean: buildno_clean $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
|
||||
$(KERNEL_SERVICES:%=%_clean) $(SUBSYS:%=%_clean) $(APPS:%=%_clean)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
floppy: make_floppy_dirs autoexec_floppy $(COMPONENTS:%=%_floppy) \
|
||||
$(DLLS:%=%_floppy) $(LOADERS:%=%_floppy) \
|
||||
$(KERNEL_SERVICES:%=%_floppy) $(SUBSYS:%=%_floppy) \
|
||||
$(APPS:%=%_floppy)
|
||||
|
||||
dist: clean_dist_dir make_dist_dirs $(COMPONENTS:%=%_dist) $(DLLS:%=%_dist) \
|
||||
$(LOADERS:%=%_dist) $(KERNEL_SERVICES:%=%_dist) $(SUBSYS:%=%_dist) \
|
||||
$(APPS:%=%_dist)
|
||||
|
||||
#
|
||||
# Build number generator
|
||||
#
|
||||
buildno: include/reactos/version.h
|
||||
make -C apps/buildno
|
||||
|
||||
buildno_clean:
|
||||
make -C apps/buildno clean
|
||||
|
||||
buildno_floppy:
|
||||
|
||||
buildno_dist:
|
||||
|
||||
.PHONY: buildno buildno_clean buildno_floppy buildno_dist
|
||||
|
||||
#
|
||||
# Applications
|
||||
#
|
||||
$(APPS): %:
|
||||
make -C apps/$*
|
||||
|
||||
$(APPS:%=%_clean): %_clean:
|
||||
make -C apps/$* clean
|
||||
|
||||
$(APPS:%=%_floppy): %_floppy:
|
||||
make -C apps/$* floppy
|
||||
|
||||
$(APPS:%=%_dist): %_dist:
|
||||
make -C apps/$* dist
|
||||
|
||||
.PHONY: $(APPS) $(APPS:%=%_clean) $(APPS:%=%_floppy) $(APPS:%=%_dist)
|
||||
|
||||
#
|
||||
# Interfaces
|
||||
#
|
||||
iface_native:
|
||||
make -C iface/native
|
||||
|
||||
iface_native_clean:
|
||||
make -C iface/native clean
|
||||
|
||||
iface_native_floppy:
|
||||
|
||||
iface_native_dist:
|
||||
|
||||
.PHONY: iface_native iface_native_clean iface_native_floppy \
|
||||
iface_native_dist
|
||||
|
||||
#
|
||||
# Device driver rules
|
||||
#
|
||||
$(DEVICE_DRIVERS): %:
|
||||
make -C services/dd/$*
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_clean): %_clean:
|
||||
make -C services/dd/$* clean
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_floppy): %_floppy:
|
||||
make -C services/dd/$* floppy
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_dist): %_dist:
|
||||
make -C services/dd/$* dist
|
||||
|
||||
.PHONY: $(DEVICE_DRIVERS) $(DEVICE_DRIVERS:%=%_clean) \
|
||||
$(DEVICE_DRIVERS:%=%_floppy) $(DEVICE_DRIVERS:%=%_dist)
|
||||
|
||||
$(FS_DRIVERS): %:
|
||||
make -C services/fs/$*
|
||||
|
||||
$(FS_DRIVERS:%=%_clean): %_clean:
|
||||
make -C services/fs/$* clean
|
||||
|
||||
$(FS_DRIVERS:%=%_floppy): %_floppy:
|
||||
make -C services/fs/$* floppy
|
||||
|
||||
$(FS_DRIVERS:%=%_dist): %_dist:
|
||||
make -C services/fs/$* dist
|
||||
|
||||
.PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_clean) $(FS_DRIVERS:%=%_floppy) \
|
||||
$(FS_DRIVERS:%=%_dist)
|
||||
|
||||
#
|
||||
# Kernel loaders
|
||||
#
|
||||
|
||||
$(LOADERS): %:
|
||||
make -C loaders/$*
|
||||
|
||||
$(LOADERS:%=%_clean): %_clean:
|
||||
make -C loaders/$* clean
|
||||
|
||||
$(LOADERS:%=%_floppy): %_floppy:
|
||||
make -C loaders/$* floppy
|
||||
|
||||
$(LOADERS:%=%_dist): %_dist:
|
||||
make -C loaders/$* dist
|
||||
|
||||
.PHONY: $(LOADERS) $(LOADERS:%=%_clean) $(LOADERS:%=%_floppy) \
|
||||
$(LOADERS:%=%_dist)
|
||||
|
||||
#
|
||||
# Required system components
|
||||
#
|
||||
|
||||
ntoskrnl:
|
||||
make -C ntoskrnl
|
||||
|
||||
ntoskrnl_clean:
|
||||
make -C ntoskrnl clean
|
||||
|
||||
ntoskrnl_floppy:
|
||||
make -C ntoskrnl floppy
|
||||
|
||||
ntoskrnl_dist:
|
||||
make -C ntoskrnl dist
|
||||
|
||||
.PHONY: ntoskrnl ntoskrnl_clean ntoskrnl_floppy ntoskrnl_dist
|
||||
|
||||
#
|
||||
# Required DLLs
|
||||
#
|
||||
|
||||
$(DLLS): %:
|
||||
make -C lib/$*
|
||||
|
||||
$(DLLS:%=%_clean): %_clean:
|
||||
make -C lib/$* clean
|
||||
|
||||
$(DLLS:%=%_floppy): %_floppy:
|
||||
make -C lib/$* floppy
|
||||
|
||||
$(DLLS:%=%_dist): %_dist:
|
||||
make -C lib/$* dist
|
||||
|
||||
.PHONY: $(DLLS) $(DLLS:%=%_clean) $(DLLS:%=%_floppy) $(DLLS:%=%_dist)
|
||||
|
||||
#
|
||||
# Kernel Subsystems
|
||||
#
|
||||
$(SUBSYS): %:
|
||||
make -C subsys/$*
|
||||
|
||||
$(SUBSYS:%=%_clean): %_clean:
|
||||
make -C subsys/$* clean
|
||||
|
||||
$(SUBSYS:%=%_floppy): %_floppy:
|
||||
make -C subsys/$* floppy
|
||||
|
||||
$(SUBSYS:%=%_dist): %_dist:
|
||||
make -C subsys/$* dist
|
||||
|
||||
.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean) $(SUBSYS:%=%_floppy) \
|
||||
$(SUBSYS:%=%_dist)
|
||||
|
||||
#
|
||||
# Make an install floppy
|
||||
#
|
||||
|
||||
install: all
|
||||
./install.sh /mnt/hda1
|
||||
|
||||
make_floppy_dirs:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
mkdir $(FLOPPY_DIR)\dlls
|
||||
mkdir $(FLOPPY_DIR)\apps
|
||||
mkdir $(FLOPPY_DIR)\drivers
|
||||
mkdir $(FLOPPY_DIR)\subsys
|
||||
else
|
||||
mkdir $(FLOPPY_DIR)/dlls $(FLOPPY_DIR)/apps $(FLOPPY_DIR)/drivers
|
||||
mkdir $(FLOPPY_DIR)/subsys
|
||||
endif
|
||||
|
||||
.PHONY: make_floppy_dirs
|
||||
|
||||
autoexec_floppy: $(FLOPPY_DIR)/autoexec.bat
|
||||
|
||||
$(FLOPPY_DIR)/autoexec.bat: bootflop.bat
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) bootflop.bat $(FLOPPY_DIR)\autoexec.bat
|
||||
else
|
||||
$(CP) bootflop.bat $(FLOPPY_DIR)/autoexec.bat
|
||||
endif
|
||||
|
||||
#
|
||||
# Make a distribution saveset
|
||||
#
|
||||
|
||||
clean_dist_dir:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
- $(RM) $(DIST_DIR)\dlls\*.dll
|
||||
- $(RM) $(DIST_DIR)\apps\*.exe
|
||||
- $(RM) $(DIST_DIR)\drivers\*.sys
|
||||
- $(RM) $(DIST_DIR)\subsys\*.exe
|
||||
- $(RMDIR) $(DIST_DIR)\dlls
|
||||
- $(RMDIR) $(DIST_DIR)\apps
|
||||
- $(RMDIR) $(DIST_DIR)\drivers
|
||||
- $(RMDIR) $(DIST_DIR)\subsys
|
||||
- $(RMDIR) $(DIST_DIR)
|
||||
else
|
||||
$(RM) -r $(DIST_DIR)
|
||||
endif
|
||||
|
||||
make_dist_dirs:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
mkdir $(DIST_DIR)
|
||||
mkdir $(DIST_DIR)\dlls
|
||||
mkdir $(DIST_DIR)\apps
|
||||
mkdir $(DIST_DIR)\drivers
|
||||
mkdir $(DIST_DIR)\dlls
|
||||
mkdir $(DIST_DIR)\subsys
|
||||
else
|
||||
mkdir $(DIST_DIR) $(DIST_DIR)/dlls $(DIST_DIR)/apps $(DIST_DIR)/drivers
|
||||
mkdir $(DIST_DIR)/subsys
|
||||
endif
|
||||
|
||||
.PHONY: clean_dist_dir make_dist_dirs
|
||||
|
15
reactos/NEWS
Normal file
15
reactos/NEWS
Normal file
@@ -0,0 +1,15 @@
|
||||
0.0.14: Converted to PE format
|
||||
All system libraries are now dlls
|
||||
|
||||
0.0.13: Mostly bugfixes (I think)
|
||||
|
||||
0.0.12: Added support for multiple processes (not really tested)
|
||||
System calls
|
||||
kernel32 now compiles (only as a static library)
|
||||
Fixed invalid tss bug (hopefully)
|
||||
Added section support
|
||||
Added some of the ZwxxxVirtual calls
|
||||
Added prototype caching functions (only the Minix fsd actually
|
||||
uses them)
|
||||
Added handle access and type checking
|
||||
Prototype APC implementation (no support for user APCs)
|
24
reactos/README
Normal file
24
reactos/README
Normal file
@@ -0,0 +1,24 @@
|
||||
About Reactos
|
||||
|
||||
1. What is Reactos
|
||||
|
||||
A project aiming to make an approximate clone of Windows NT, compatible
|
||||
with most Windows applications.
|
||||
|
||||
The project has a website at http://www.reactos.com/
|
||||
|
||||
2. Building Reactos
|
||||
|
||||
See the INSTALL file for more details.
|
||||
|
||||
3. More information
|
||||
|
||||
See the doc subdirectory for some sparse notes
|
||||
|
||||
4. Who is responsible
|
||||
|
||||
See the CREDITS file
|
||||
|
||||
5. Recent developments
|
||||
|
||||
See the NEWS file
|
33
reactos/apps/common/crt0.c
Normal file
33
reactos/apps/common/crt0.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <windows.h>
|
||||
|
||||
extern int main(int args, char* argv[], char* environ[]);
|
||||
|
||||
static unsigned int _argc = 0;
|
||||
static char** _argv = NULL;
|
||||
static char** _environ = NULL;
|
||||
|
||||
int mainCRTStartup(PWSTR args)
|
||||
{
|
||||
int nRet;
|
||||
|
||||
// SetUnhandledExceptionFilter(NULL);
|
||||
|
||||
// _fpreset();
|
||||
|
||||
// __GetMainArgs(&_argc, &_argv, &_environ, 0);
|
||||
|
||||
nRet = main(_argc, _argv, _environ);
|
||||
|
||||
// _cexit();
|
||||
|
||||
ExitProcess(nRet);
|
||||
}
|
||||
|
||||
int WinMainCRTStartup()
|
||||
{
|
||||
return mainCRTStartup(NULL);
|
||||
}
|
||||
|
||||
void __main(void)
|
||||
{
|
||||
}
|
97
reactos/apps/tests/apc/apc.c
Normal file
97
reactos/apps/tests/apc/apc.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
VOID STDCALL ApcRoutine(PVOID Context,
|
||||
PIO_STATUS_BLOCK IoStatus,
|
||||
ULONG Reserved)
|
||||
{
|
||||
printf("(apc.exe) ApcRoutine(Context %x)\n", Context);
|
||||
}
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING FileName;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
CHAR Buffer[256];
|
||||
HANDLE EventHandle;
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
printf("APC test program\n");
|
||||
|
||||
EventHandle = CreateEventW(NULL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (EventHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Failed to create event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening file\n");
|
||||
RtlInitUnicodeString(&FileName,
|
||||
L"\\C:\\a.txt");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&FileName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
printf("Creating file\n");
|
||||
FileHandle = CreateFileW(L"C:\\a.txt",
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Open failed\n");
|
||||
return;
|
||||
}
|
||||
printf("Reading file\n");
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL,
|
||||
ApcRoutine,
|
||||
0xdeadbeef,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
256,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("Read failed\n");
|
||||
}
|
||||
printf("Waiting\n");
|
||||
WaitForSingleObjectEx(EventHandle, INFINITE, TRUE);
|
||||
printf("Returned from wait\n");
|
||||
ZwClose(FileHandle);
|
||||
printf("Program finished\n");
|
||||
for(;;);
|
||||
}
|
||||
|
44
reactos/apps/tests/apc/makefile
Normal file
44
reactos/apps/tests/apc/makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= ../common/crt0.o apc.o
|
||||
PROGS= apc.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) apc.o
|
||||
- $(RM) apc.exe
|
||||
- $(RM) apc.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
apc.exe: $(OBJECTS) $(LIBS)
|
||||
$(LD) $(OBJECTS) $(LIBS) -o apc.exe
|
||||
$(NM) --numeric-sort apc.exe > apc.sym
|
||||
|
||||
include ../../rules.mak
|
39
reactos/apps/tests/args/args.c
Normal file
39
reactos/apps/tests/args/args.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
debug_printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
debug_printf("argc %d\n", argc);
|
||||
for (i=0; i<argc; i++)
|
||||
{
|
||||
debug_printf("Argv[%d]: %x\n",i,argv[i]);
|
||||
debug_printf("Argv[%d]: '%s'\n",i,argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
42
reactos/apps/tests/args/makefile
Normal file
42
reactos/apps/tests/args/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= args.o
|
||||
PROGS= args.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) args.o
|
||||
- $(RM) args.exe
|
||||
- $(RM) args.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
args.exe: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o args.exe
|
||||
$(NM) --numeric-sort args.exe > args.sym
|
||||
|
||||
include ../../rules.mak
|
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
}
|
82
reactos/apps/tests/bench/bench-thread.c
Normal file
82
reactos/apps/tests/bench/bench-thread.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NR_THREADS (0x1)
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
thread_main1(LPVOID param)
|
||||
{
|
||||
printf("Thread 1 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
thread_main2(LPVOID param)
|
||||
{
|
||||
printf("Thread 2 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD i=0;
|
||||
DWORD id;
|
||||
|
||||
#if 1
|
||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
/* CreateThread(NULL,
|
||||
0,
|
||||
thread_main2,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);*/
|
||||
}
|
||||
|
||||
printf("All threads created...\n");
|
||||
|
||||
/*
|
||||
* Waiting for threads is not implemented yet.
|
||||
* If you want to see all threads running, uncomment the
|
||||
* call to SuspendThread(). The test application will
|
||||
* freeze after all threads are created.
|
||||
*/
|
||||
/* SuspendThread (GetCurrentThread()); */
|
||||
|
||||
#else
|
||||
|
||||
printf("Creating thread...\n");
|
||||
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
printf("Thread created. Waiting for termination...\n");
|
||||
|
||||
WaitForSingleObject (hThread,
|
||||
-1);
|
||||
|
||||
CloseHandle (hThread);
|
||||
|
||||
printf("Thread terminated...\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
41
reactos/apps/tests/bench/makefile
Normal file
41
reactos/apps/tests/bench/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = bench-thread
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
bench-thread.exe: bench-thread.c
|
||||
$(CC) $(CFLAGS) bench-thread.c -lkernel32 -o bench-thread.exe
|
||||
$(NM) --numeric-sort bench-thread.exe > bench-thread.sym
|
||||
|
||||
include ../../rules.mak
|
33
reactos/apps/tests/event/event.c
Normal file
33
reactos/apps/tests/event/event.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE events[2];
|
||||
|
||||
DWORD WINAPI thread( LPVOID crap )
|
||||
{
|
||||
SetEvent( events[0] );
|
||||
if( crap )
|
||||
SetEvent( events[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DWORD id, Status;
|
||||
printf( "Creating events\n" );
|
||||
events[0] = CreateEvent( 0, TRUE, FALSE, 0 );
|
||||
events[1] = CreateEvent( 0, TRUE, FALSE, 0 );
|
||||
printf( "Created events\n" );
|
||||
CreateThread( 0, 0, thread, 0, 0, &id );
|
||||
printf( "WaitForSingleObject %s\n", ( WaitForSingleObject( events[0], INFINITE ) == WAIT_OBJECT_0 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
CreateThread( 0, 0, thread, 0, 0, &id );
|
||||
printf( "WaitForMultipleObjects with waitall = FALSE %s\n", ( WaitForMultipleObjects( 2, events, FALSE, INFINITE ) == WAIT_OBJECT_0 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
CreateThread( 0, 0, thread, (void *)1, 0, &id );
|
||||
Status = WaitForMultipleObjects( 2, events, TRUE, INFINITE );
|
||||
printf( "WaitForMultipleObjects with waitall = TRUE %s\n", ( Status == WAIT_OBJECT_0 || Status == WAIT_OBJECT_0 + 1 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
printf( "WaitForSingleObject with timeout %s\n", ( WaitForSingleObject( events[0], 100 ) == WAIT_TIMEOUT ? "worked" : "failed" ) );
|
||||
return 0;
|
||||
}
|
41
reactos/apps/tests/event/makefile
Normal file
41
reactos/apps/tests/event/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = event
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
event.exe: event.c
|
||||
$(CC) $(CFLAGS) event.c -lkernel32 -o event.exe
|
||||
$(NM) --numeric-sort event.exe > event.sym
|
||||
|
||||
include ../../rules.mak
|
8
reactos/apps/tests/hello/hello.c
Normal file
8
reactos/apps/tests/hello/hello.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("Hello world\n");
|
||||
return(0);
|
||||
}
|
39
reactos/apps/tests/hello/makefile
Normal file
39
reactos/apps/tests/hello/makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS = hello.o
|
||||
PROGS = hello.exe
|
||||
LIBS =
|
||||
CLEAN_FILES = hello.o hello.exe
|
||||
|
||||
all: hello.exe
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
hello.exe: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o hello.exe
|
||||
|
||||
include ../../rules.mak
|
205
reactos/apps/tests/lpc/conport.c
Normal file
205
reactos/apps/tests/lpc/conport.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/* $Id: conport.c,v 1.5 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/conport.c
|
||||
*
|
||||
* To be run in a real WNT 4.0 system with
|
||||
* "\SmApiPort" as argument. Do not try to
|
||||
* connect to "\Windows\ApiPort" since that
|
||||
* reboots immeditely.
|
||||
*
|
||||
* Use Russinovich' HandleEx to verify
|
||||
* conport.exe owns two unnamed LPC ports:
|
||||
* the one created by kernel32.dll connecting
|
||||
* to csrss.exe, and one connected to here.
|
||||
*
|
||||
* 19990627 (Emanuele Aliberti)
|
||||
* Initial implementation.
|
||||
* 19990704 (EA)
|
||||
* Dump object's attributes moved in dumpinfo.c.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define PROTO_LPC
|
||||
#include <ddk/ntddk.h>
|
||||
#include "dumpinfo.h"
|
||||
|
||||
#define LPC_CONNECT_FLAG1 0x00000001
|
||||
#define LPC_CONNECT_FLAG2 0x00000010
|
||||
#define LPC_CONNECT_FLAG3 0x00000100
|
||||
#define LPC_CONNECT_FLAG4 0x00001000
|
||||
#define LPC_CONNECT_FLAG5 0x00010000
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * ConnectPort)(
|
||||
OUT PHANDLE PortHandle,
|
||||
IN PUNICODE_STRING PortName,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN DWORD Unknown3,
|
||||
IN DWORD Unknown4,
|
||||
IN DWORD Unknown5,
|
||||
IN DWORD Unknown6,
|
||||
IN ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * YieldExecution)(VOID);
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAXARG 1000000
|
||||
|
||||
|
||||
VOID
|
||||
TryConnectPort(char *port_name)
|
||||
{
|
||||
DWORD Status = 0;
|
||||
HANDLE Port = 0;
|
||||
int i;
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
WORD Name [BUF_SIZE] = {0};
|
||||
int dwx = 0;
|
||||
char * port_name_save = port_name;
|
||||
|
||||
/*
|
||||
* Convert the port's name to Unicode.
|
||||
*/
|
||||
for (
|
||||
PortName.Length = 0;
|
||||
( *port_name
|
||||
&& (PortName.Length < BUF_SIZE)
|
||||
);
|
||||
)
|
||||
{
|
||||
Name[PortName.Length++] = (WORD) *port_name++;
|
||||
}
|
||||
Name[PortName.Length] = 0;
|
||||
|
||||
PortName.Length = PortName.Length * sizeof (WORD);
|
||||
PortName.MaximumLength = PortName.Length + sizeof (WORD);
|
||||
PortName.Buffer = (PWSTR) Name;
|
||||
/*
|
||||
* Prepare the port object attributes.
|
||||
*/
|
||||
ObjectAttributes.Length =
|
||||
sizeof (OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory =
|
||||
NULL;
|
||||
ObjectAttributes.ObjectName =
|
||||
NULL /*& PortName */;
|
||||
ObjectAttributes.Attributes =
|
||||
OBJ_CASE_INSENSITIVE;
|
||||
ObjectAttributes.SecurityDescriptor =
|
||||
NULL;
|
||||
ObjectAttributes.SecurityQualityOfService =
|
||||
NULL;
|
||||
/*
|
||||
* Try to issue a connection request.
|
||||
*/
|
||||
Port = 0;
|
||||
Status = ConnectPort(
|
||||
& Port,
|
||||
& PortName,
|
||||
& ObjectAttributes,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
LPC_CONNECT_FLAG5
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DumpInfo(
|
||||
Name,
|
||||
Status,
|
||||
"connected",
|
||||
Port
|
||||
);
|
||||
/* Hot waiting */
|
||||
for (dwx=0; dwx<MAXARG; ++dwx)
|
||||
{
|
||||
YieldExecution();
|
||||
}
|
||||
if (FALSE == CloseHandle(Port))
|
||||
{
|
||||
printf(
|
||||
"Could not close the port handle %08X.\n",
|
||||
Port
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf(
|
||||
"Connection to port \"%s\" failed (Status = %08X).\n",
|
||||
port_name_save,
|
||||
Status
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
main( int argc, char * argv[] )
|
||||
{
|
||||
HINSTANCE ntdll;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("WNT LPC Port Connector\n");
|
||||
printf("Usage: %s [port_name]\n",argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("LoadLibrary(NTDLL)\n");
|
||||
ntdll = LoadLibrary("NTDLL");
|
||||
if (ntdll == NULL)
|
||||
{
|
||||
printf("Could not load NTDLL\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtConnectPort)\n");
|
||||
ConnectPort = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtConnectPort"
|
||||
);
|
||||
if (ConnectPort == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtConnectPort\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtQueryObject)\n");
|
||||
QueryObject = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtQueryObject"
|
||||
);
|
||||
if (QueryObject == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtQueryObject\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtYieldExecution)\n");
|
||||
YieldExecution = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtYieldExecution"
|
||||
);
|
||||
if (YieldExecution == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtYieldExecution\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("TryConnectPort(%s)\n",argv[1]);
|
||||
TryConnectPort(argv[1]);
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
192
reactos/apps/tests/lpc/creport.c
Normal file
192
reactos/apps/tests/lpc/creport.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/* $Id: creport.c,v 1.2 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/creport.c
|
||||
*
|
||||
* To be run in a real WNT 4.0 system to
|
||||
* create an LPC named port.
|
||||
*
|
||||
* Use Russinovich' HandleEx to verify
|
||||
* creport.exe owns the named LPC port
|
||||
* you asked to create.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define PROTO_LPC
|
||||
#include <ddk/ntddk.h>
|
||||
#include "dumpinfo.h"
|
||||
|
||||
#define LPC_CONNECT_FLAG1 0x00000001
|
||||
#define LPC_CONNECT_FLAG2 0x00000010
|
||||
#define LPC_CONNECT_FLAG3 0x00000100
|
||||
#define LPC_CONNECT_FLAG4 0x00001000
|
||||
#define LPC_CONNECT_FLAG5 0x00010000
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * CreatePort)(
|
||||
/*OUT PHANDLE PortHandle,*/
|
||||
PVOID Buffer,
|
||||
IN POBJECT_ATTRIBUTES PortAttributes OPTIONAL,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN DWORD Unknown3,
|
||||
IN ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * YieldExecution)(VOID);
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAXARG 5000000
|
||||
|
||||
|
||||
VOID
|
||||
TryCreatePort(char *port_name)
|
||||
{
|
||||
DWORD Status = 0;
|
||||
HANDLE Port = 0;
|
||||
int i;
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
WORD Name [BUF_SIZE] = {0};
|
||||
int dwx = 0;
|
||||
char * port_name_save = port_name;
|
||||
|
||||
/*
|
||||
* Convert the port's name to Unicode.
|
||||
*/
|
||||
for (
|
||||
PortName.Length = 0;
|
||||
( *port_name
|
||||
&& (PortName.Length < BUF_SIZE)
|
||||
);
|
||||
)
|
||||
{
|
||||
Name[PortName.Length++] = (WORD) *port_name++;
|
||||
}
|
||||
Name[PortName.Length] = 0;
|
||||
|
||||
PortName.Length = PortName.Length * sizeof (WORD);
|
||||
PortName.MaximumLength = PortName.Length + sizeof (WORD);
|
||||
PortName.Buffer = (PWSTR) Name;
|
||||
/*
|
||||
* Prepare the port object attributes.
|
||||
*/
|
||||
ObjectAttributes.Length =
|
||||
sizeof (OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory =
|
||||
NULL;
|
||||
ObjectAttributes.ObjectName =
|
||||
& PortName;
|
||||
ObjectAttributes.Attributes =
|
||||
0; //OBJ_CASE_INSENSITIVE --> STATUS_INVALID_PARAMETER ==> case sensitive!;
|
||||
ObjectAttributes.SecurityDescriptor =
|
||||
NULL;
|
||||
ObjectAttributes.SecurityQualityOfService =
|
||||
NULL;
|
||||
/*
|
||||
* Try to issue a connection request.
|
||||
*/
|
||||
Port = 0;
|
||||
Status = CreatePort(
|
||||
& Port,
|
||||
& ObjectAttributes,
|
||||
0, /* ACCESS_MASK? */
|
||||
0, /* Unknown3 */
|
||||
LPC_CONNECT_FLAG5
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DumpInfo(
|
||||
Name,
|
||||
Status,
|
||||
"created",
|
||||
Port
|
||||
);
|
||||
/* Hot waiting */
|
||||
for (dwx=0; dwx<MAXARG; ++dwx)
|
||||
{
|
||||
YieldExecution();
|
||||
}
|
||||
if (FALSE == CloseHandle(Port))
|
||||
{
|
||||
printf(
|
||||
"Could not close the port handle %08X.\n",
|
||||
Port
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf(
|
||||
"Creating port \"%s\" failed (Status = %08X).\n",
|
||||
port_name_save,
|
||||
Status
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
main( int argc, char * argv[] )
|
||||
{
|
||||
HINSTANCE ntdll;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("WNT LPC Port Creator\n");
|
||||
printf("Usage: %s [port_name]\n",argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("LoadLibrary(NTDLL)\n");
|
||||
ntdll = LoadLibrary("NTDLL");
|
||||
if (ntdll == NULL)
|
||||
{
|
||||
printf("Could not load NTDLL\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtCreatePort)\n");
|
||||
CreatePort = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtCreatePort"
|
||||
);
|
||||
if (CreatePort == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtCreatePort\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtQueryObject)\n");
|
||||
QueryObject = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtQueryObject"
|
||||
);
|
||||
if (QueryObject == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtQueryObject\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtYieldExecution)\n");
|
||||
YieldExecution = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtYieldExecution"
|
||||
);
|
||||
if (YieldExecution == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtYieldExecution\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("TryCreatePort(%s)\n",argv[1]);
|
||||
TryCreatePort(argv[1]);
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
239
reactos/apps/tests/lpc/dumpinfo.c
Normal file
239
reactos/apps/tests/lpc/dumpinfo.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* $Id: dumpinfo.c,v 1.2 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/dumpinfo.c
|
||||
*
|
||||
* ReactOS Operating System
|
||||
*
|
||||
* Dump a kernel object's attributes by its handle.
|
||||
*
|
||||
* 19990627 (Emanuele Aliberti)
|
||||
* Initial implementation.
|
||||
* 19990704 (EA)
|
||||
* Added code to find the basic information buffer size
|
||||
* for the LPC port object.
|
||||
* 19990710 (EA)
|
||||
*
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAX_BASIC_INFO_SIZE 512
|
||||
|
||||
|
||||
extern
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
extern
|
||||
NTSTATUS
|
||||
(STDCALL * QueryInformationPort)(
|
||||
IN HANDLE PortHandle,
|
||||
IN CINT PortInformationClass, /* guess */
|
||||
OUT PVOID PortInformation, /* guess */
|
||||
IN ULONG PortInformationLength, /* guess */
|
||||
OUT PULONG ReturnLength /* guess */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
static
|
||||
VOID
|
||||
DumpBuffer(
|
||||
char *Name,
|
||||
BYTE *buffer,
|
||||
ULONG size
|
||||
)
|
||||
{
|
||||
register ULONG i = 0;
|
||||
|
||||
printf("%s [%d] = ",Name,size);
|
||||
for ( i = 0;
|
||||
i != size;
|
||||
++i
|
||||
)
|
||||
{
|
||||
printf("%02X",buffer[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
VOID
|
||||
DumpInfo (
|
||||
LPCWSTR Name,
|
||||
NTSTATUS Status,
|
||||
LPCWSTR Comment,
|
||||
HANDLE Port
|
||||
)
|
||||
{
|
||||
BYTE ObjectInformation [BUF_SIZE] = {0};
|
||||
ULONG ResultLength;
|
||||
|
||||
wprintf(
|
||||
L"Port \"%s\" %s:\n",
|
||||
Name,
|
||||
Comment
|
||||
);
|
||||
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
printf("\tPort = %08X\n\n",Port);
|
||||
/*
|
||||
* Query object information.
|
||||
*/
|
||||
printf("Basic Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectBasicInformation,
|
||||
ObjectInformation,
|
||||
sizeof (LPC_PORT_BASIC_INFORMATION),
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
PLPC_PORT_BASIC_INFORMATION i;
|
||||
|
||||
i = (PLPC_PORT_BASIC_INFORMATION) ObjectInformation;
|
||||
|
||||
printf( "\tUnknown01 = 0x%08X\n", i->Unknown0 );
|
||||
printf( "\tUnknown02 = 0x%08X\n", i->Unknown1 );
|
||||
printf( "\tUnknown03 = 0x%08X\n", i->Unknown2 );
|
||||
printf( "\tUnknown04 = 0x%08X\n", i->Unknown3 );
|
||||
printf( "\tUnknown05 = 0x%08X\n", i->Unknown4 );
|
||||
printf( "\tUnknown06 = 0x%08X\n", i->Unknown5 );
|
||||
printf( "\tUnknown07 = 0x%08X\n", i->Unknown6 );
|
||||
printf( "\tUnknown08 = 0x%08X\n", i->Unknown7 );
|
||||
printf( "\tUnknown09 = 0x%08X\n", i->Unknown8 );
|
||||
printf( "\tUnknown10 = 0x%08X\n", i->Unknown9 );
|
||||
printf( "\tUnknown11 = 0x%08X\n", i->Unknown10 );
|
||||
printf( "\tUnknown12 = 0x%08X\n", i->Unknown11 );
|
||||
printf( "\tUnknown13 = 0x%08X\n", i->Unknown12 );
|
||||
printf( "\tUnknown14 = 0x%08X\n", i->Unknown13 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Type Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectTypeInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_TYPE_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_TYPE_INFORMATION *) ObjectInformation;
|
||||
|
||||
wprintf(
|
||||
L"\tName: \"%s\"\n",
|
||||
(i->Name.Length ? i->Name.Buffer : L"")
|
||||
);
|
||||
/*
|
||||
FIXME: why this always raise an access violation exception?
|
||||
wprintf(
|
||||
L"\tType: \"%s\"\n",
|
||||
(i->Type.Length ? i->Type.Buffer : L"")
|
||||
);
|
||||
/**/
|
||||
printf(
|
||||
"\tTotal Handles: %d\n",
|
||||
i->TotalHandles
|
||||
);
|
||||
printf(
|
||||
"\tReference Count: %d\n",
|
||||
i->ReferenceCount
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Name Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectNameInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_NAME_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_NAME_INFORMATION *) ObjectInformation;
|
||||
wprintf(
|
||||
L"\tName: \"%s\"\n",
|
||||
(i->Name.Length ? i->Name.Buffer : L"")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Data Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectDataInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_DATA_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_DATA_INFORMATION *) ObjectInformation;
|
||||
printf(
|
||||
"\tInherit Handle: %s\n",
|
||||
(i->bInheritHandle ? "TRUE" : "FALSE")
|
||||
);
|
||||
printf(
|
||||
"\tProtect from Close: %s\n",
|
||||
(i->bProtectFromClose ? "TRUE" : "FALSE")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
//---
|
||||
printf("Port Information:\n");
|
||||
/* Status = QueryInformationPort(
|
||||
Port,
|
||||
1, /* info class * /
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DWORD * i = ObjectInformation;
|
||||
int j = 0;
|
||||
|
||||
while (j < ResultLength / sizeof (DWORD))
|
||||
{
|
||||
printf("\t%08X\n",i[j]);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
8
reactos/apps/tests/lpc/dumpinfo.h
Normal file
8
reactos/apps/tests/lpc/dumpinfo.h
Normal file
@@ -0,0 +1,8 @@
|
||||
VOID
|
||||
DumpInfo (
|
||||
LPCWSTR Name,
|
||||
NTSTATUS Status,
|
||||
LPCWSTR Comment,
|
||||
HANDLE Port
|
||||
);
|
||||
|
62
reactos/apps/tests/lpc/lpcclt.c
Normal file
62
reactos/apps/tests/lpc/lpcclt.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
UNICODE_STRING PortName;
|
||||
NTSTATUS Status;
|
||||
HANDLE PortHandle;
|
||||
LPCMESSAGE Request;
|
||||
ULONG ConnectInfoLength;
|
||||
|
||||
printf("(lpcclt.exe) Lpc client\n");
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\TestPort");
|
||||
|
||||
printf("(lpcclt.exe) Connecting to port\n");
|
||||
ConnectInfoLength = 0;
|
||||
Status = NtConnectPort(&PortHandle,
|
||||
&PortName,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ConnectInfoLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcclt.exe) Failed to connect\n");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(Request.MessageData, GetCommandLineA());
|
||||
Request.ActualMessageLength = strlen(Request.MessageData);
|
||||
Request.TotalMessageLength = sizeof(LPCMESSAGE);
|
||||
|
||||
printf("(lpcclt.exe) Sending message\n");
|
||||
Status = NtRequestPort(PortHandle, &Request);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcclt.exe) Failed to send request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcclt.exe) Succeeded\n");
|
||||
}
|
98
reactos/apps/tests/lpc/lpcsrv.c
Normal file
98
reactos/apps/tests/lpc/lpcsrv.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
HANDLE NamedPortHandle;
|
||||
HANDLE PortHandle;
|
||||
LPCMESSAGE ConnectMsg;
|
||||
|
||||
printf("(lpcsrv.exe) Lpc test server\n");
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\TestPort");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&PortName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
printf("(lpcsrv.exe) Creating port\n");
|
||||
Status = NtCreatePort(&NamedPortHandle,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to create port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
printf("(lpcsrv.exe) Listening for connections\n");
|
||||
Status = NtListenPort(NamedPortHandle,
|
||||
&ConnectMsg);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to listen for connections\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Accepting connections\n");
|
||||
Status = NtAcceptConnectPort(&PortHandle,
|
||||
NamedPortHandle,
|
||||
NULL,
|
||||
1,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to accept connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Completing connection\n");
|
||||
Status = NtCompleteConnectPort(PortHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to complete connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
LPCMESSAGE Request;
|
||||
|
||||
Status = NtReplyWaitReceivePort(PortHandle,
|
||||
0,
|
||||
NULL,
|
||||
&Request);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to receive request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Message contents are <%s>\n", Request.MessageData);
|
||||
}
|
||||
}
|
51
reactos/apps/tests/lpc/makefile
Normal file
51
reactos/apps/tests/lpc/makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
SRV_OBJECTS= ../common/crt0.o lpcsrv.o
|
||||
CLT_OBJECTS= ../common/crt0.o lpcclt.o
|
||||
|
||||
PROGS= lpcsrv.exe lpcclt.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) lpcsrv.o
|
||||
- $(RM) lpcsrv.exe
|
||||
- $(RM) lpcsrv.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
lpcsrv.exe: $(SRV_OBJECTS) $(LIBS)
|
||||
$(LD) $(SRV_OBJECTS) $(LIBS) -o lpcsrv.exe
|
||||
$(NM) --numeric-sort lpcsrv.exe > lpcsrv.sym
|
||||
|
||||
lpcclt.exe: $(CLT_OBJECTS) $(LIBS)
|
||||
$(LD) $(CLT_OBJECTS) $(LIBS) -o lpcclt.exe
|
||||
$(NM) --numeric-sort lpcclt.exe > lpcclt.sym
|
||||
|
||||
|
||||
include ../../rules.mak
|
51
reactos/apps/tests/shm/makefile
Normal file
51
reactos/apps/tests/shm/makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
SRV_OBJECTS= ../common/crt0.o shmsrv.o
|
||||
CLT_OBJECTS= ../common/crt0.o shmclt.o
|
||||
|
||||
PROGS= shmsrv.exe shmclt.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) *.o
|
||||
- $(RM) *.exe
|
||||
- $(RM) *.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
shmsrv.exe: $(SRV_OBJECTS) $(LIBS)
|
||||
$(LD) $(SRV_OBJECTS) $(LIBS) -o shmsrv.exe
|
||||
$(NM) --numeric-sort shmsrv.exe > shmsrv.sym
|
||||
|
||||
shmclt.exe: $(CLT_OBJECTS) $(LIBS)
|
||||
$(LD) $(CLT_OBJECTS) $(LIBS) -o shmclt.exe
|
||||
$(NM) --numeric-sort shmsrv.exe > shmclt.sym
|
||||
|
||||
|
||||
include ../../rules.mak
|
60
reactos/apps/tests/shm/shmclt.c
Normal file
60
reactos/apps/tests/shm/shmclt.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
HANDLE Section;
|
||||
PVOID BaseAddress;
|
||||
char buffer[256];
|
||||
|
||||
printf("Shm test server\n");
|
||||
|
||||
Section = OpenFileMappingW (
|
||||
// PAGE_EXECUTE_READWRITE, invalid parameter
|
||||
FILE_MAP_WRITE,
|
||||
FALSE,
|
||||
L"TestSection"
|
||||
);
|
||||
if (Section == NULL)
|
||||
{
|
||||
printf("Failed to open section (err=%d)", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
BaseAddress = MapViewOfFile(Section,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
8192);
|
||||
if (BaseAddress == NULL)
|
||||
{
|
||||
printf("Failed to map section (err=%d)\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
printf("BaseAddress %x\n", (UINT) BaseAddress);
|
||||
printf("Copying from section\n");
|
||||
strcpy(buffer, BaseAddress);
|
||||
printf("Copyed <%s>\n", buffer);
|
||||
|
||||
// for(;;);
|
||||
return 0;
|
||||
}
|
||||
|
52
reactos/apps/tests/shm/shmsrv.c
Normal file
52
reactos/apps/tests/shm/shmsrv.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* $Id: shmsrv.c,v 1.3 1999/12/30 01:51:36 dwelch Exp $
|
||||
*
|
||||
* FILE : reactos/apps/shm/shmsrv.c
|
||||
* AUTHOR: David Welch
|
||||
*/
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HANDLE Section;
|
||||
PVOID BaseAddress;
|
||||
|
||||
printf("Shm test server\n");
|
||||
|
||||
Section = CreateFileMappingW (
|
||||
(HANDLE) 0xFFFFFFFF,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
8192,
|
||||
L"TestSection"
|
||||
);
|
||||
if (Section == NULL)
|
||||
{
|
||||
printf("Failed to create section (err=%d)", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Mapping view of section\n");
|
||||
BaseAddress = MapViewOfFile(Section,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
8192);
|
||||
printf("BaseAddress %x\n", (UINT) BaseAddress);
|
||||
if (BaseAddress == NULL)
|
||||
{
|
||||
printf("Failed to map section\n");
|
||||
}
|
||||
|
||||
printf("Copying to section\n");
|
||||
printf("Copying %s\n", GetCommandLineA());
|
||||
strcpy(BaseAddress, GetCommandLineA());
|
||||
|
||||
for(;;);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
11
reactos/apps/tests/test_old/bug2.c
Normal file
11
reactos/apps/tests/test_old/bug2.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int i;
|
||||
puts ("This should print \"wow = I\" for I from 0 to 39 inclusive.");
|
||||
for (i = 0; i < 40; i++)
|
||||
printf ("%s = %d\n", "wow", i);
|
||||
return 0;
|
||||
}
|
53
reactos/apps/tests/test_old/bug3.c
Normal file
53
reactos/apps/tests/test_old/bug3.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
const char filename[] = "/tmp/bug3.test";
|
||||
|
||||
f = fopen(filename, "w+");
|
||||
for (i=0; i<9000; i++)
|
||||
putc ('x', f);
|
||||
fseek (f, 8180L, 0);
|
||||
fwrite ("Where does this text go?", 1, 24, f);
|
||||
fflush (f);
|
||||
|
||||
rewind (f);
|
||||
for (i=0; i<9000; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
if ((j = getc(f)) != 'x')
|
||||
{
|
||||
if (i != 8180)
|
||||
{
|
||||
printf ("Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[25];
|
||||
|
||||
buf[0] = j;
|
||||
fread (buf + 1, 1, 23, f);
|
||||
buf[24] = '\0';
|
||||
if (strcmp (buf, "Where does this text go?") != 0)
|
||||
{
|
||||
printf ("%s\nTest FAILED!\n", buf);
|
||||
return 1;
|
||||
}
|
||||
i += 23;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
remove(filename);
|
||||
|
||||
puts ("Test succeeded.");
|
||||
|
||||
return 0;
|
||||
}
|
74
reactos/apps/tests/test_old/makefile
Normal file
74
reactos/apps/tests/test_old/makefile
Normal file
@@ -0,0 +1,74 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS= test-stdio tst-printf tstdiomisc bug2 bug3 \
|
||||
temptest test-fseek test_rdwr
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
bug2.exe: bug2.c
|
||||
$(CC) bug2.c -lkernel32 -o bug2.exe
|
||||
$(NM) --numeric-sort bug2.exe > bug2.sym
|
||||
|
||||
bug3.exe: bug3.c
|
||||
$(CC) bug3.c -lkernel32 -o bug3.exe
|
||||
$(NM) --numeric-sort bug3.exe > bug3.sym
|
||||
|
||||
temptest.exe: temptest.c
|
||||
$(CC) temptest.c -lkernel32 -o temptest.exe
|
||||
$(NM) --numeric-sort temptest.exe > temptest.sym
|
||||
|
||||
test-fseek.exe: test-fseek.c
|
||||
$(CC) test-fseek.c -lkernel32 -o test-fseek.exe
|
||||
$(NM) --numeric-sort test-fseek.exe > test-fseek.sym
|
||||
|
||||
test-fwrite.exe: test-fwrite.c
|
||||
$(CC) test-fwrite.c -lkernel32 -o test-fwrite.exe
|
||||
$(NM) --numeric-sort test-fwrite.exe > test-fwrite.sym
|
||||
|
||||
test_rdwr.exe: test_rdwr.c
|
||||
$(CC) test_rdwr.c -lkernel32 -o test_rdwr.exe
|
||||
$(NM) --numeric-sort test_rdwr.exe > test_rdwr.sym
|
||||
|
||||
test-stdio.exe: test-stdio.c
|
||||
$(CC) test-stdio.c -lkernel32 -o test-stdio.exe
|
||||
$(NM) --numeric-sort test-stdio.exe > test-stdio.sym
|
||||
|
||||
tst-printf.exe: tst-printf.c
|
||||
$(CC) tst-printf.c -lkernel32 -o tst-printf.exe
|
||||
$(NM) --numeric-sort tst-printf.exe > tst-printf.sym
|
||||
|
||||
tstdiomisc.exe: tstdiomisc.c
|
||||
$(CC) tstdiomisc.c -lkernel32 -o tstdiomisc.exe
|
||||
$(NM) --numeric-sort tstdiomisc.exe > tstdiomisc.sym
|
||||
|
||||
include ../../rules.mak
|
27
reactos/apps/tests/test_old/temptest.c
Normal file
27
reactos/apps/tests/test_old/temptest.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char *files[500];
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 500; i++) {
|
||||
files[i] = tempnam (NULL, "file");
|
||||
if (files[i] == NULL) {
|
||||
printf ("tempnam failed\n");
|
||||
exit (1);
|
||||
}
|
||||
printf ("file: %s\n", files[i]);
|
||||
fp = fopen (files[i], "w");
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
remove (files[i]);
|
||||
|
||||
exit (0);
|
||||
}
|
85
reactos/apps/tests/test_old/test-fseek.c
Normal file
85
reactos/apps/tests/test_old/test-fseek.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TESTFILE "/tmp/test.dat"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
FILE *fp;
|
||||
int i, j;
|
||||
|
||||
puts ("\nFile seek test");
|
||||
fp = fopen (TESTFILE, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
perror (TESTFILE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
putc (i, fp);
|
||||
if (freopen (TESTFILE, "r", fp) != fp)
|
||||
{
|
||||
perror ("Cannot open file for reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i <= 255; i++)
|
||||
{
|
||||
printf ("%3d\n", i);
|
||||
fseek (fp, (long) -i, SEEK_END);
|
||||
if ((j = getc (fp)) != 256 - i)
|
||||
{
|
||||
printf ("SEEK_END failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) i, SEEK_SET))
|
||||
{
|
||||
puts ("Cannot SEEK_SET");
|
||||
break;
|
||||
}
|
||||
if ((j = getc (fp)) != i)
|
||||
{
|
||||
printf ("SEEK_SET failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) i, SEEK_SET))
|
||||
{
|
||||
puts ("Cannot SEEK_SET");
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR))
|
||||
{
|
||||
puts ("Cannot SEEK_CUR");
|
||||
break;
|
||||
}
|
||||
if ((j = getc (fp)) != (i >= 128 ? i - 128 : i + 128))
|
||||
{
|
||||
printf ("SEEK_CUR failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
remove (TESTFILE);
|
||||
|
||||
puts ((i > 255) ? "Test succeeded." : "Test FAILED!");
|
||||
return (i > 255) ? 0 : 1;
|
||||
}
|
68
reactos/apps/tests/test_old/test-fwrite.c
Normal file
68
reactos/apps/tests/test_old/test-fwrite.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *f = tmpfile ();
|
||||
char obuf[99999], ibuf[sizeof obuf];
|
||||
char *line;
|
||||
size_t linesz;
|
||||
|
||||
if (! f)
|
||||
{
|
||||
perror ("tmpfile");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fputs ("line\n", f) == EOF)
|
||||
{
|
||||
perror ("fputs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset (obuf, 'z', sizeof obuf);
|
||||
memset (ibuf, 'y', sizeof ibuf);
|
||||
|
||||
if (fwrite (obuf, sizeof obuf, 1, f) != 1)
|
||||
{
|
||||
perror ("fwrite");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rewind (f);
|
||||
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
if (getline (&line, &linesz, f) != 5)
|
||||
{
|
||||
perror ("getline");
|
||||
return 1;
|
||||
}
|
||||
if (strcmp (line, "line\n"))
|
||||
{
|
||||
puts ("Lines differ. Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fread (ibuf, sizeof ibuf, 1, f) != 1)
|
||||
{
|
||||
perror ("fread");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp (ibuf, obuf, sizeof ibuf))
|
||||
{
|
||||
puts ("Buffers differ. Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
asprintf (&line, "\
|
||||
GDB is free software and you are welcome to distribute copies of it\n\
|
||||
under certain conditions; type \"show copying\" to see the conditions.\n\
|
||||
There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
|
||||
");
|
||||
|
||||
puts ("Test succeeded.");
|
||||
return 0;
|
||||
}
|
55
reactos/apps/tests/test_old/test-stdio.c
Normal file
55
reactos/apps/tests/test_old/test-stdio.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char msg1[] = "testing _write\n";
|
||||
char msg2[] = "testing putchar.";
|
||||
char msg3[] = "testing printf.";
|
||||
char tmpbuf[255];
|
||||
FILE* f1;
|
||||
|
||||
write(1, msg1, strlen(msg1));
|
||||
|
||||
write(1, msg2, strlen(msg2));
|
||||
putchar('o'); putchar('k'); putchar('\n');
|
||||
|
||||
write(1, msg3, strlen(msg3));
|
||||
printf("ok\n");
|
||||
|
||||
printf("Testing fopen\n");
|
||||
f1 = fopen("tmp.txt","w+b");
|
||||
if (f1 == NULL)
|
||||
{
|
||||
printf("fopen failed\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fwrite\n");
|
||||
if (fwrite(msg1, 1, strlen(msg1)+1, f1) != (strlen(msg1)+1))
|
||||
{
|
||||
printf("fwrite failed\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fread\n");
|
||||
fseek(f1, 0, SEEK_SET);
|
||||
if (fread(tmpbuf, 1, strlen(msg1)+1, f1) != (strlen(msg1)+1))
|
||||
{
|
||||
printf("fread failed\n");
|
||||
return(1);
|
||||
}
|
||||
if (strcmp(tmpbuf,msg1) != 0)
|
||||
{
|
||||
printf("fread failed, data corrupt\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fclose\n");
|
||||
if (fclose(f1) != 0)
|
||||
{
|
||||
printf("fclose failed\n");
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
129
reactos/apps/tests/test_old/test_rdwr.c
Normal file
129
reactos/apps/tests/test_old/test_rdwr.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* Copyright (C) 1991, 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
static const char hello[] = "Hello, world.\n";
|
||||
static const char replace[] = "Hewwo, world.\n";
|
||||
static const size_t replace_from = 2, replace_to = 4;
|
||||
char filename[FILENAME_MAX];
|
||||
char *name = strrchr (*argv, '/');
|
||||
char buf[BUFSIZ];
|
||||
FILE *f;
|
||||
int lose = 0;
|
||||
|
||||
if (name != NULL)
|
||||
++name;
|
||||
else
|
||||
name = *argv;
|
||||
|
||||
(void) sprintf (filename, "/tmp/%s.test", name);
|
||||
|
||||
f = fopen (filename, "w+");
|
||||
if (f == NULL)
|
||||
{
|
||||
perror (filename);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
(void) fputs (hello, f);
|
||||
rewind (f);
|
||||
(void) fgets (buf, sizeof (buf), f);
|
||||
rewind (f);
|
||||
(void) fputs (buf, f);
|
||||
rewind (f);
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < replace_from; ++i)
|
||||
{
|
||||
int c = getc (f);
|
||||
if (c == EOF)
|
||||
{
|
||||
printf ("EOF at %Zu.\n", i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
else if (c != hello[i])
|
||||
{
|
||||
printf ("Got '%c' instead of '%c' at %Zu.\n",
|
||||
(unsigned char) c, hello[i], i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
long int where = ftell (f);
|
||||
if (where == (long int) replace_from)
|
||||
{
|
||||
register size_t i;
|
||||
for (i = replace_from; i < replace_to; ++i)
|
||||
if (putc(replace[i], f) == EOF)
|
||||
{
|
||||
printf ("putc('%c') got %s at %Zu.\n",
|
||||
replace[i], strerror (errno), i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (where == -1L)
|
||||
{
|
||||
printf ("ftell got %s (should be at %Zu).\n",
|
||||
strerror (errno), replace_from);
|
||||
lose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("ftell returns %lu; should be %Zu.\n", where, replace_from);
|
||||
lose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lose)
|
||||
{
|
||||
rewind (f);
|
||||
if (fgets (buf, sizeof (buf), f) == NULL)
|
||||
{
|
||||
printf ("fgets got %s.\n", strerror(errno));
|
||||
lose = 1;
|
||||
}
|
||||
else if (strcmp (buf, replace))
|
||||
{
|
||||
printf ("Read \"%s\" instead of \"%s\".\n", buf, replace);
|
||||
lose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lose)
|
||||
printf ("Test FAILED! Losing file is \"%s\".\n", filename);
|
||||
else
|
||||
{
|
||||
(void) remove (filename);
|
||||
puts ("Test succeeded.");
|
||||
}
|
||||
|
||||
exit (lose ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
311
reactos/apps/tests/test_old/tst-printf.c
Normal file
311
reactos/apps/tests/test_old/tst-printf.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef BSD
|
||||
#include </usr/include/stdio.h>
|
||||
#define EXIT_SUCCESS 0
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
|
||||
void rfg1 (void);
|
||||
void rfg2 (void);
|
||||
|
||||
|
||||
void
|
||||
fmtchk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
void
|
||||
fmtst1chk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 4, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
void
|
||||
fmtst2chk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 4, 4, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
/* This page is covered by the following copyright: */
|
||||
|
||||
/* (C) Copyright C E Chew
|
||||
*
|
||||
* Feel free to copy, use and distribute this software provided:
|
||||
*
|
||||
* 1. you do not pretend that you wrote it
|
||||
* 2. you leave this copyright notice intact.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
|
||||
*/
|
||||
|
||||
#define DEC -123
|
||||
#define INT 255
|
||||
#define UNS (~0)
|
||||
|
||||
/* Formatted Output Test
|
||||
*
|
||||
* This exercises the output formatting code.
|
||||
*/
|
||||
|
||||
void
|
||||
fp_test (void)
|
||||
{
|
||||
int i, j, k, l;
|
||||
char buf[7];
|
||||
char *prefix = buf;
|
||||
char tp[20];
|
||||
|
||||
puts("\nFormatted output test");
|
||||
printf("prefix 6d 6o 6x 6X 6u\n");
|
||||
strcpy(prefix, "%");
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (l = 0; l < 2; l++) {
|
||||
strcpy(prefix, "%");
|
||||
if (i == 0) strcat(prefix, "-");
|
||||
if (j == 0) strcat(prefix, "+");
|
||||
if (k == 0) strcat(prefix, "#");
|
||||
if (l == 0) strcat(prefix, "0");
|
||||
printf("%5s |", prefix);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6d |");
|
||||
printf(tp, DEC);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6o |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6x |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6X |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6u |");
|
||||
printf(tp, UNS);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%10s\n", (char *) NULL);
|
||||
printf("%-10s\n", (char *) NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
static char shortstr[] = "Hi, Z.";
|
||||
static char longstr[] = "Good morning, Doctor Chandra. This is Hal. \
|
||||
I am ready for my first lesson today.";
|
||||
|
||||
fmtchk("%.4x");
|
||||
fmtchk("%04x");
|
||||
fmtchk("%4.4x");
|
||||
fmtchk("%04.4x");
|
||||
fmtchk("%4.3x");
|
||||
fmtchk("%04.3x");
|
||||
|
||||
fmtst1chk("%.*x");
|
||||
fmtst1chk("%0*x");
|
||||
fmtst2chk("%*.*x");
|
||||
fmtst2chk("%0*.*x");
|
||||
|
||||
#ifndef BSD
|
||||
printf("bad format:\t\"%b\"\n");
|
||||
printf("nil pointer (padded):\t\"%10p\"\n", (void *) NULL);
|
||||
#endif
|
||||
|
||||
printf("decimal negative:\t\"%d\"\n", -2345);
|
||||
printf("octal negative:\t\"%o\"\n", -2345);
|
||||
printf("hex negative:\t\"%x\"\n", -2345);
|
||||
printf("long decimal number:\t\"%ld\"\n", -123456L);
|
||||
printf("long octal negative:\t\"%lo\"\n", -2345L);
|
||||
printf("long unsigned decimal number:\t\"%lu\"\n", -123456L);
|
||||
printf("zero-padded LDN:\t\"%010ld\"\n", -123456L);
|
||||
printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456);
|
||||
printf("space-padded LDN:\t\"%10ld\"\n", -123456L);
|
||||
printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L);
|
||||
|
||||
printf("zero-padded string:\t\"%010s\"\n", shortstr);
|
||||
printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr);
|
||||
printf("space-padded string:\t\"%10s\"\n", shortstr);
|
||||
printf("left-adjusted S string:\t\"%-10s\"\n", shortstr);
|
||||
printf("null string:\t\"%s\"\n", (char *)NULL);
|
||||
printf("limited string:\t\"%.22s\"\n", longstr);
|
||||
|
||||
printf("e-style >= 1:\t\"%e\"\n", 12.34);
|
||||
printf("e-style >= .1:\t\"%e\"\n", 0.1234);
|
||||
printf("e-style < .1:\t\"%e\"\n", 0.001234);
|
||||
printf("e-style big:\t\"%.60e\"\n", 1e20);
|
||||
printf ("e-style == .1:\t\"%e\"\n", 0.1);
|
||||
printf("f-style >= 1:\t\"%f\"\n", 12.34);
|
||||
printf("f-style >= .1:\t\"%f\"\n", 0.1234);
|
||||
printf("f-style < .1:\t\"%f\"\n", 0.001234);
|
||||
printf("g-style >= 1:\t\"%g\"\n", 12.34);
|
||||
printf("g-style >= .1:\t\"%g\"\n", 0.1234);
|
||||
printf("g-style < .1:\t\"%g\"\n", 0.001234);
|
||||
printf("g-style big:\t\"%.60g\"\n", 1e20);
|
||||
|
||||
printf (" %6.5f\n", .099999999860301614);
|
||||
printf (" %6.5f\n", .1);
|
||||
printf ("x%5.4fx\n", .5);
|
||||
|
||||
printf ("%#03x\n", 1);
|
||||
|
||||
{
|
||||
double d = FLT_MIN;
|
||||
int niter = 17;
|
||||
|
||||
while (niter-- != 0)
|
||||
printf ("%.17e\n", d / 2);
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
printf ("%15.5e\n", 4.9406564584124654e-324);
|
||||
|
||||
#define FORMAT "|%12.4f|%12.4e|%12.4g|\n"
|
||||
printf (FORMAT, 0.0, 0.0, 0.0);
|
||||
printf (FORMAT, 1.0, 1.0, 1.0);
|
||||
printf (FORMAT, -1.0, -1.0, -1.0);
|
||||
printf (FORMAT, 100.0, 100.0, 100.0);
|
||||
printf (FORMAT, 1000.0, 1000.0, 1000.0);
|
||||
printf (FORMAT, 10000.0, 10000.0, 10000.0);
|
||||
printf (FORMAT, 12345.0, 12345.0, 12345.0);
|
||||
printf (FORMAT, 100000.0, 100000.0, 100000.0);
|
||||
printf (FORMAT, 123456.0, 123456.0, 123456.0);
|
||||
#undef FORMAT
|
||||
|
||||
{
|
||||
char buf[20];
|
||||
printf ("sprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
|
||||
sprintf (buf, "%30s", "foo"), sizeof (buf), buf);
|
||||
}
|
||||
|
||||
fp_test ();
|
||||
|
||||
printf ("%e should be 1.234568e+06\n", 1234567.8);
|
||||
printf ("%f should be 1234567.800000\n", 1234567.8);
|
||||
printf ("%g should be 1.23457e+06\n", 1234567.8);
|
||||
printf ("%g should be 123.456\n", 123.456);
|
||||
printf ("%g should be 1e+06\n", 1000000.0);
|
||||
printf ("%g should be 10\n", 10.0);
|
||||
printf ("%g should be 0.02\n", 0.02);
|
||||
|
||||
{
|
||||
double x=1.0;
|
||||
printf("%.17f\n",(1.0/x/10.0+1.0)*x-x);
|
||||
}
|
||||
|
||||
puts ("--- Should be no further output. ---");
|
||||
rfg1 ();
|
||||
rfg2 ();
|
||||
|
||||
{
|
||||
char buf[200];
|
||||
int result;
|
||||
|
||||
sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
|
||||
|
||||
result = strcmp (buf,
|
||||
"onetwo three ");
|
||||
|
||||
puts (result != 0 ? "Test failed!" : "Test ok.");
|
||||
return result != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rfg1 (void)
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
sprintf (buf, "%5.s", "xyz");
|
||||
if (strcmp (buf, " ") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " ");
|
||||
sprintf (buf, "%5.f", 33.3);
|
||||
if (strcmp (buf, " 33") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 33");
|
||||
sprintf (buf, "%8.e", 33.3e7);
|
||||
if (strcmp (buf, " 3e+08") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3e+08");
|
||||
sprintf (buf, "%8.E", 33.3e7);
|
||||
if (strcmp (buf, " 3E+08") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3E+08");
|
||||
sprintf (buf, "%.g", 33.3);
|
||||
if (strcmp (buf, "3e+01") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3e+01");
|
||||
sprintf (buf, "%.G", 33.3);
|
||||
if (strcmp (buf, "3E+01") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3E+01");
|
||||
}
|
||||
|
||||
void
|
||||
rfg2 (void)
|
||||
{
|
||||
int prec;
|
||||
char buf[100];
|
||||
|
||||
prec = 0;
|
||||
sprintf (buf, "%.*g", prec, 3.3);
|
||||
if (strcmp (buf, "3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3");
|
||||
prec = 0;
|
||||
sprintf (buf, "%.*G", prec, 3.3);
|
||||
if (strcmp (buf, "3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3");
|
||||
prec = 0;
|
||||
sprintf (buf, "%7.*G", prec, 3.33);
|
||||
if (strcmp (buf, " 3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*o", prec, 33);
|
||||
if (strcmp (buf, " 041") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 041");
|
||||
prec = 7;
|
||||
sprintf (buf, "%09.*u", prec, 33);
|
||||
if (strcmp (buf, " 0000033") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 0000033");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*x", prec, 33);
|
||||
if (strcmp (buf, " 021") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 021");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*X", prec, 33);
|
||||
if (strcmp (buf, " 021") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 021");
|
||||
}
|
56
reactos/apps/tests/test_old/tstdiomisc.c
Normal file
56
reactos/apps/tests/test_old/tstdiomisc.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
t1 (void)
|
||||
{
|
||||
int n = -1;
|
||||
sscanf ("abc ", "abc %n", &n);
|
||||
printf ("t1: count=%d\n", n);
|
||||
|
||||
return n != 5;
|
||||
}
|
||||
|
||||
int
|
||||
t2 (void)
|
||||
{
|
||||
int result = 0;
|
||||
int n;
|
||||
long N;
|
||||
int retval;
|
||||
#define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \
|
||||
VAR = -1; \
|
||||
retval = sscanf (INPUT, FORMAT, &VAR); \
|
||||
printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \
|
||||
INPUT, FORMAT, retval, (long int) VAR); \
|
||||
result |= retval != EXP_RES || VAR != EXP_VAL
|
||||
|
||||
SCAN ("12345", "%ld", N, 1, 12345);
|
||||
SCAN ("12345", "%llllld", N, 0, -1);
|
||||
SCAN ("12345", "%LLLLLd", N, 0, -1);
|
||||
SCAN ("test ", "%*s%n", n, 0, 4);
|
||||
SCAN ("test ", "%2*s%n", n, 0, -1);
|
||||
SCAN ("12 ", "%l2d", n, 0, -1);
|
||||
SCAN ("12 ", "%2ld", N, 1, 12);
|
||||
|
||||
n = -1;
|
||||
N = -1;
|
||||
retval = sscanf ("1 1", "%d %Z", &n, &N);
|
||||
printf ("sscanf (\"1 1\", \"%%d %%Z\", &n, &N) => %d, n = %d, N = %ld\n", \
|
||||
retval, n, N); \
|
||||
result |= retval != 1 || n != 1 || N != -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result |= t1 ();
|
||||
result |= t2 ();
|
||||
|
||||
result |= fflush (stdout) == EOF;
|
||||
|
||||
return result;
|
||||
}
|
41
reactos/apps/tests/thread/makefile
Normal file
41
reactos/apps/tests/thread/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = thread
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
thread.exe: thread.c
|
||||
$(CC) $(CFLAGS) thread.c -lkernel32 -o thread.exe
|
||||
$(NM) --numeric-sort thread.exe > thread.sym
|
||||
|
||||
include ../../rules.mak
|
46
reactos/apps/tests/thread/thread.c
Normal file
46
reactos/apps/tests/thread/thread.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NR_THREADS (10)
|
||||
|
||||
ULONG nr;
|
||||
|
||||
DWORD WINAPI thread_main1(LPVOID param)
|
||||
{
|
||||
ULONG s;
|
||||
|
||||
printf("Thread %d running\n", (DWORD)param);
|
||||
s = nr = ((nr * 1103515245) + 12345) & 0x7fffffff;
|
||||
s = s % 10;
|
||||
printf("s %d\n", s);
|
||||
Sleep(s);
|
||||
printf("Thread %d finished\n", (DWORD)param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD i=0;
|
||||
DWORD id;
|
||||
ULONG nr;
|
||||
|
||||
nr = atoi(argv[1]);
|
||||
printf("Seed %d\n", nr);
|
||||
|
||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
}
|
||||
|
||||
printf("All threads created...\n");
|
||||
for(;;);
|
||||
return 0;
|
||||
}
|
2
reactos/apps/utils/buildno/.cvsignore
Normal file
2
reactos/apps/utils/buildno/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
buildno
|
||||
buildno.exe
|
26
reactos/apps/utils/buildno/Makefile
Normal file
26
reactos/apps/utils/buildno/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# $Id: Makefile,v 1.3 1999/11/12 12:01:09 dwelch Exp $
|
||||
#
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
TARGETNAME=buildno
|
||||
CLEAN_FILES= $(TARGETNAME).o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).sym
|
||||
|
||||
all: $(TARGETNAME)$(EXE_POSTFIX)
|
||||
$(EXE_PREFIX)$(TARGETNAME)$(EXE_POSTFIX) -q
|
||||
|
||||
|
||||
$(TARGETNAME)$(EXE_POSTFIX): $(TARGETNAME).c ../../include/reactos/version.h
|
||||
$(NATIVE_CC) -I../../include -o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).c
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
$(RM) $(TARGETNAME).o
|
||||
$(RM) $(TARGETNAME).sym
|
||||
$(RM) $(TARGETNAME)$(EXE_POSTFIX)
|
||||
|
||||
.phony: clean
|
||||
|
||||
include ../../rules.mak
|
||||
|
||||
# EOF
|
262
reactos/apps/utils/buildno/buildno.c
Normal file
262
reactos/apps/utils/buildno/buildno.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/* $Id: buildno.c,v 1.2 1999/12/26 20:21:02 ea Exp $
|
||||
*
|
||||
* buildno - Generate the build number for ReactOS
|
||||
*
|
||||
* Copyright (c) 1999 Emanuele Aliberti
|
||||
*
|
||||
*
|
||||
* It assumes the last release date is defined in
|
||||
* <reactos/version.h> as a macro named
|
||||
*
|
||||
* KERNEL_RELEASE_DATE
|
||||
*
|
||||
* as a 32-bit unsigned long YYYYMMDD (UTC).
|
||||
*
|
||||
* The build number is the number of full days
|
||||
* elapsed since the last release date (UTC).
|
||||
*
|
||||
* The build number is stored in the file
|
||||
* <reactos/buildno.h> as a set of macros:
|
||||
*
|
||||
* KERNEL_VERSION_BUILD
|
||||
* KERNEL_VERSION_BUILD_STR
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <reactos/version.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* File to (over)write */
|
||||
#define BUILDNO_INCLUDE_FILE "../../include/reactos/buildno.h"
|
||||
|
||||
static char * argv0 = "";
|
||||
|
||||
|
||||
int
|
||||
elapsed_days (
|
||||
time_t t_today,
|
||||
time_t t_release_day
|
||||
)
|
||||
{
|
||||
double seconds = difftime (t_today, t_release_day);
|
||||
double days = seconds / (double) 86400.0;
|
||||
char buf [32];
|
||||
char * dot = buf;
|
||||
|
||||
sprintf (buf, "%f", days );
|
||||
|
||||
while ( *dot && *dot != '.') ++dot;
|
||||
*dot = '\0';
|
||||
|
||||
return atol (buf);
|
||||
}
|
||||
|
||||
void
|
||||
write_h (int build)
|
||||
{
|
||||
FILE *h = NULL;
|
||||
|
||||
h = fopen ( BUILDNO_INCLUDE_FILE, "w");
|
||||
if (!h)
|
||||
{
|
||||
fprintf (
|
||||
stderr,
|
||||
"%s: can not create file \"%s\"!\n",
|
||||
argv0,
|
||||
BUILDNO_INCLUDE_FILE
|
||||
);
|
||||
return;
|
||||
}
|
||||
fprintf (
|
||||
h,
|
||||
"/* Do not edit - Machine generated */\n"
|
||||
);
|
||||
|
||||
fprintf (h, "#ifndef _INC_REACTOS_BUILDNO\n" );
|
||||
fprintf (h, "#define _INC_REACTOS_BUILDNO\n" );
|
||||
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_BUILD\t%d\n",
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_BUILD_STR\t\"%d\"\n",
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_RELEASE_RC\t\"%d.%d.%d.%d\\0\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_RELEASE_STR\t\"%d.%d.%d.%d\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_RC\t\"%d.%d.%d\\0\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_STR\t\"%d.%d.%d\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#endif\n/* EOF */\n"
|
||||
);
|
||||
|
||||
fclose (h);
|
||||
}
|
||||
|
||||
void
|
||||
usage (void)
|
||||
{
|
||||
fprintf (
|
||||
stderr,
|
||||
"Usage: %s [-q]\n",
|
||||
argv0
|
||||
);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char * argv [])
|
||||
{
|
||||
int quiet = FALSE;
|
||||
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int day = 0;
|
||||
int build = 0;
|
||||
|
||||
time_t t0 = 0;
|
||||
struct tm t0_tm = {0};
|
||||
time_t t1 = 0;
|
||||
struct tm * t1_tm = NULL;
|
||||
|
||||
argv0 = argv[0];
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (argv[1][0] == '-')
|
||||
{
|
||||
if (argv[1][1] == 'q')
|
||||
{
|
||||
quiet = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
/*
|
||||
* We are building TODAY!
|
||||
*/
|
||||
time (& t0);
|
||||
/*
|
||||
* "Parse" the release date.
|
||||
*/
|
||||
day = KERNEL_RELEASE_DATE % 100;
|
||||
month = ( ( KERNEL_RELEASE_DATE
|
||||
% 10000
|
||||
)
|
||||
- day
|
||||
)
|
||||
/ 100;
|
||||
year =
|
||||
( KERNEL_RELEASE_DATE
|
||||
- (month * 100)
|
||||
- day
|
||||
)
|
||||
/ 10000;
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf ( "\n\
|
||||
ReactOS Build Number Generator\n\n\
|
||||
Last release: %4d-%02d-%02d\n",
|
||||
year,
|
||||
month,
|
||||
day
|
||||
);
|
||||
}
|
||||
t0_tm.tm_year = year - ((year > 1999) ? 2000 : 1900);
|
||||
t0_tm.tm_mon = month;
|
||||
t0_tm.tm_mday = day;
|
||||
|
||||
t0 = mktime (& t0_tm);
|
||||
|
||||
time (& t1); /* current build time */
|
||||
t1_tm = gmtime (& t1);
|
||||
|
||||
t1_tm->tm_year +=
|
||||
(t1_tm->tm_year < 70)
|
||||
? 2000
|
||||
: 1900;
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf (
|
||||
"Current date: %4d-%02d-%02d\n\n",
|
||||
t1_tm->tm_year,
|
||||
t1_tm->tm_mon,
|
||||
t1_tm->tm_mday
|
||||
);
|
||||
}
|
||||
/*
|
||||
* Compute delta days.
|
||||
*/
|
||||
build = elapsed_days (t1, t0);
|
||||
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf (
|
||||
"Build number: %d (elapsed days since last release)\n",
|
||||
build
|
||||
);
|
||||
printf (
|
||||
"ROS Version : %d.%d.%d.%d\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
}
|
||||
/*
|
||||
* (Over)write the include file.
|
||||
*/
|
||||
write_h (build);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
26
reactos/apps/utils/cat/cat.c
Normal file
26
reactos/apps/utils/cat/cat.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
FILE* in;
|
||||
char ch;
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
in = fopen(argv[i],"r");
|
||||
if (in == NULL)
|
||||
{
|
||||
printf("Failed to open file %s\n", argv[i]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while ((ch = fgetc(in)) != EOF)
|
||||
{
|
||||
putchar(ch);
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
return 0;
|
||||
}
|
42
reactos/apps/utils/cat/makefile
Normal file
42
reactos/apps/utils/cat/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= cat.o
|
||||
PROGS= cat.exe
|
||||
|
||||
all: cat.exe
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) cat.o
|
||||
- $(RM) cat.exe
|
||||
- $(RM) cat.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
.PHONY: floppy dist
|
||||
|
||||
cat.exe: $(OBJECTS) $(LIBS)
|
||||
$(CC) $(OBJECTS) -o cat.exe
|
||||
$(NM) --numeric-sort cat.exe > cat.sym
|
||||
|
||||
include ../../rules.mak
|
42
reactos/apps/utils/shell/makefile
Normal file
42
reactos/apps/utils/shell/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= ../common/crt0.o shell.o
|
||||
PROGS= shell.exe
|
||||
LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
|
||||
CLEAN_FILES= shell.o shell.exe shell.sym
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
all: shell.exe
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
shell.exe: $(OBJECTS) $(LIBS)
|
||||
$(CC) -specs=../../specs $(OBJECTS) $(LIBS) -lgcc -o shell.exe
|
||||
$(NM) --numeric-sort shell.exe > shell.sym
|
||||
|
||||
include ../../rules.mak
|
389
reactos/apps/utils/shell/shell.c
Normal file
389
reactos/apps/utils/shell/shell.c
Normal file
@@ -0,0 +1,389 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <windows.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
HANDLE InputHandle, OutputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ExecuteVer(void)
|
||||
{
|
||||
debug_printf(
|
||||
"Reactos Simple Shell\n(compiled on %s, at %s)\n",
|
||||
__DATE__,
|
||||
__TIME__
|
||||
);
|
||||
}
|
||||
|
||||
void ExecuteCd(char* cmdline)
|
||||
{
|
||||
if (!SetCurrentDirectoryA(cmdline))
|
||||
{
|
||||
debug_printf("Invalid directory\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteDir(char* cmdline)
|
||||
{
|
||||
HANDLE shandle;
|
||||
WIN32_FIND_DATA FindData;
|
||||
int nFile=0, nRep=0;
|
||||
FILETIME fTime;
|
||||
SYSTEMTIME sTime;
|
||||
|
||||
shandle = FindFirstFile("*",&FindData);
|
||||
|
||||
if (shandle==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
debug_printf("Invalid directory\n");
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
debug_printf("%-15.15s",FindData.cAlternateFileName);
|
||||
if(FindData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
|
||||
debug_printf("<DIR> "),nRep++;
|
||||
else
|
||||
debug_printf(" %10d ",FindData.nFileSizeLow),nFile++;
|
||||
|
||||
FileTimeToLocalFileTime(&FindData.ftLastWriteTime ,&fTime);
|
||||
FileTimeToSystemTime(&fTime, &sTime);
|
||||
debug_printf("%02d/%02d/%04d %02d:%02d:%02d "
|
||||
,sTime.wMonth,sTime.wDay,sTime.wYear
|
||||
,sTime.wHour,sTime.wMinute,sTime.wSecond);
|
||||
|
||||
debug_printf("%s\n",FindData.cFileName);
|
||||
} while(FindNextFile(shandle,&FindData));
|
||||
debug_printf("\n %d files\n %d directories\n\n",nFile,nRep);
|
||||
FindClose(shandle);
|
||||
}
|
||||
|
||||
|
||||
void ExecuteReboot(char* cmdline)
|
||||
{
|
||||
NtShutdownSystem (ShutdownReboot);
|
||||
}
|
||||
|
||||
|
||||
void ExecuteType(char* cmdline)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
char c;
|
||||
DWORD Result;
|
||||
|
||||
FileHandle = CreateFile(cmdline,
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (FileHandle == NULL)
|
||||
{
|
||||
debug_printf("Unknown file\n");
|
||||
return;
|
||||
}
|
||||
while (ReadFile(FileHandle,
|
||||
&c,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("%c",c);
|
||||
c = 0;
|
||||
}
|
||||
CloseHandle(FileHandle);
|
||||
}
|
||||
|
||||
int ExecuteProcess(char* name, char* cmdline, BOOL detached)
|
||||
{
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFO StartupInfo;
|
||||
// char arguments;
|
||||
BOOL ret;
|
||||
|
||||
memset(&StartupInfo, 0, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof (STARTUPINFO);
|
||||
StartupInfo.lpTitle = name;
|
||||
|
||||
ret = CreateProcessA(name,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
((TRUE == detached)
|
||||
? DETACHED_PROCESS
|
||||
: CREATE_NEW_CONSOLE
|
||||
),
|
||||
NULL,
|
||||
NULL,
|
||||
& StartupInfo,
|
||||
& ProcessInformation
|
||||
);
|
||||
if (TRUE == detached)
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
debug_printf("%s detached:\n"
|
||||
"\thProcess = %08X\n"
|
||||
"\thThread = %08X\n"
|
||||
"\tPID = %d\n"
|
||||
"\tTID = %d\n\n",
|
||||
name,
|
||||
ProcessInformation.hProcess,
|
||||
ProcessInformation.hThread,
|
||||
ProcessInformation.dwProcessId,
|
||||
ProcessInformation.dwThreadId);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf("Could not detach %s\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
debug_printf("ProcessInformation.hThread %x\n",
|
||||
ProcessInformation.hThread);
|
||||
// CloseHandle(ProcessInformation.hThread);
|
||||
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
debug_printf("Thandle %x\n", ProcessInformation.hThread);
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void ExecuteStart(char* CommandLine)
|
||||
{
|
||||
char *ImageName = CommandLine;
|
||||
|
||||
for ( ;
|
||||
( (*CommandLine)
|
||||
&& (*CommandLine != ' ')
|
||||
&& (*CommandLine != '\t')
|
||||
);
|
||||
CommandLine++
|
||||
);
|
||||
*CommandLine++ = '\0';
|
||||
while ( (*CommandLine)
|
||||
&& ( (*CommandLine == ' ')
|
||||
|| (*CommandLine == '\t')
|
||||
)
|
||||
);
|
||||
ExecuteProcess(
|
||||
ImageName,
|
||||
CommandLine,
|
||||
TRUE
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ExecuteKill(char * lpPid)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
DWORD dwProcessId;
|
||||
|
||||
dwProcessId = (DWORD) atol(lpPid);
|
||||
debug_printf("dwProcessId %d\n",dwProcessId);
|
||||
hProcess = OpenProcess(
|
||||
PROCESS_TERMINATE,
|
||||
FALSE,
|
||||
dwProcessId
|
||||
);
|
||||
if (NULL == hProcess)
|
||||
{
|
||||
debug_printf(
|
||||
"Could not open the process with PID = %d\n",
|
||||
dwProcessId
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (FALSE == TerminateProcess(
|
||||
hProcess,
|
||||
0
|
||||
)
|
||||
) {
|
||||
debug_printf(
|
||||
"Could not terminate the process with PID = %d\n",
|
||||
dwProcessId
|
||||
);
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
void ExecuteCommand(char* line)
|
||||
{
|
||||
char* cmd;
|
||||
char* tail;
|
||||
|
||||
if (isalpha(line[0]) && line[1] == ':' && line[2] == 0)
|
||||
{
|
||||
line[2] = '\\';
|
||||
line[3] = 0;
|
||||
SetCurrentDirectoryA(line);
|
||||
return;
|
||||
}
|
||||
|
||||
tail = line;
|
||||
while ((*tail)!=' ' && (*tail)!=0)
|
||||
{
|
||||
tail++;
|
||||
}
|
||||
if ((*tail)==' ')
|
||||
{
|
||||
*tail = 0;
|
||||
tail++;
|
||||
}
|
||||
cmd = line;
|
||||
|
||||
|
||||
if (cmd==NULL || *cmd == '\0' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"cd")==0)
|
||||
{
|
||||
ExecuteCd(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"dir")==0)
|
||||
{
|
||||
ExecuteDir(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"kill")==0)
|
||||
{
|
||||
ExecuteKill(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"reboot")==0)
|
||||
{
|
||||
ExecuteReboot(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"type")==0)
|
||||
{
|
||||
ExecuteType(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"ver")==0)
|
||||
{
|
||||
ExecuteVer();
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"validate")==0)
|
||||
{
|
||||
debug_printf("Validating heap...");
|
||||
if (HeapValidate(GetProcessHeap(),0,NULL))
|
||||
{
|
||||
debug_printf("succeeded\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf("failed\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"start") == 0)
|
||||
{
|
||||
ExecuteStart(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"exit")==0)
|
||||
{
|
||||
ExitProcess(0);
|
||||
return;
|
||||
}
|
||||
if (ExecuteProcess(cmd,tail,FALSE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
debug_printf("Unknown command\n");
|
||||
}
|
||||
|
||||
void ReadLine(char* line)
|
||||
{
|
||||
// KEY_EVENT_RECORD KeyEvent;
|
||||
DWORD Result;
|
||||
UCHAR CurrentDir[255];
|
||||
char ch;
|
||||
int length = 0;
|
||||
|
||||
GetCurrentDirectoryA(255,CurrentDir);
|
||||
debug_printf("%s>", CurrentDir);
|
||||
|
||||
do
|
||||
{
|
||||
if (!ReadConsoleA(InputHandle,
|
||||
&ch,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("Failed to read from console\n");
|
||||
for(;;);
|
||||
}
|
||||
switch (ch)
|
||||
{
|
||||
case '\b':
|
||||
if (length > 0)
|
||||
{
|
||||
debug_printf("\b \b");
|
||||
line--;
|
||||
length--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_printf("%c", ch);
|
||||
*line = ch;
|
||||
line++;
|
||||
length++;
|
||||
}
|
||||
} while (ch != '\n');
|
||||
line--;
|
||||
*line = 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static char line[255];
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
debug_printf("Shell Starting...\n");
|
||||
|
||||
SetCurrentDirectoryA("C:\\");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ReadLine(line);
|
||||
ExecuteCommand(line);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
loaders\dos\loadros kernel\kimage.bin %1 %2 %3 %4
|
||||
loadros ntoskrnl.exe ide.sys vfatfs.sys
|
||||
|
32
reactos/bootflop.bat
Normal file
32
reactos/bootflop.bat
Normal file
@@ -0,0 +1,32 @@
|
||||
@ECHO OFF
|
||||
|
||||
:
|
||||
: copy files to HD...
|
||||
:
|
||||
COPY /Y A:\DRIVERS\*.SYS C:\reactos\system32\drivers > NUL:
|
||||
COPY /Y A:\DLLS\*.DLL C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\APPS\*.EXE C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\SUBSYS\*.EXE C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\SUBSYS\*.DLL C:\reactos\system32 > NUL:
|
||||
:
|
||||
: present a menu to the booter...
|
||||
:
|
||||
: ECHO 1) IDE,VFatFSD
|
||||
: ECHO 2) No Drivers
|
||||
: CHOICE /C:123 /T:1,3 "Select kernel boot config"
|
||||
: IF ERRORLEVEL 2 GOTO :L2
|
||||
|
||||
:L1
|
||||
CLS
|
||||
LOADROS NTOSKRNL.EXE DRIVERS\IDE.SYS DRIVERS\VFATFSD.SYS
|
||||
GOTO :END
|
||||
|
||||
:L2
|
||||
CLS
|
||||
LOADROS NTOSKRNL.EXE
|
||||
GOTO :END
|
||||
|
||||
:END
|
||||
EXIT
|
||||
|
||||
|
@@ -1,20 +1,22 @@
|
||||
DIRECTORIES
|
||||
|
||||
system : compiled versions of the various system components and
|
||||
libraries
|
||||
mkernel : microkernel source
|
||||
mkernel/hal : hardware abstraction layer source
|
||||
mkernel/mm : memory managment subsystem source
|
||||
mkernel/iomgr : IO manager subsystem source
|
||||
include : win32 headers
|
||||
include/internal : kernel private header files
|
||||
include/ntdll : system library private header files
|
||||
include/kernel32 : system library private header files
|
||||
include/user32 : user interface private header files
|
||||
include/gdi32 : graphics interface private header files
|
||||
include/ddk : header files for modules
|
||||
lib/ntdll : NT dll source
|
||||
lib/kernel32 : kernel32 source
|
||||
doc : documentation
|
||||
loaders/dos : DOS based loader
|
||||
loaders/boot : boot loader
|
||||
DIRECTORIES
|
||||
|
||||
system : compiled versions of the various system components and
|
||||
libraries
|
||||
ntoskrnl : kernel source
|
||||
ntoskrnl/hal : hardware abstraction layer source
|
||||
ntoskrnl/mm : memory managment subsystem source
|
||||
ntoskrnl/io : IO manager subsystem source
|
||||
ntoskrnl/ke : kernel source
|
||||
include : win32 headers
|
||||
include/internal : kernel private header files
|
||||
include/ntdll : system library private header files
|
||||
include/kernel32 : system library private header files
|
||||
include/ddk : header files for modules
|
||||
lib/ntdll : NT dll source
|
||||
lib/kernel32 : kernel32 source
|
||||
doc : documentation
|
||||
loaders/dos : DOS based loader
|
||||
loaders/boot : boot loader
|
||||
services : various services (device drivers, filesystems etc)
|
||||
services/dd : device drivers
|
||||
services/fs : file systems
|
130
reactos/doc/HACKING
Normal file
130
reactos/doc/HACKING
Normal file
@@ -0,0 +1,130 @@
|
||||
* Introduction
|
||||
|
||||
Having successfully built ReactOS and been amazed by what it does, you're
|
||||
now desperate to fill in some of the omissions, this document shows you how.
|
||||
|
||||
* Prerequisites
|
||||
|
||||
A working knowledge of NT driver development is useful for understanding the
|
||||
kernel and some of its abstractions. The NT4 ddk is available for free
|
||||
download from http://www.microsoft.com/hwdev/. The Windows 98 and Windows
|
||||
2000 DDKs are also available but the NT4 one is the most useful. See
|
||||
Legal Stuff below however.
|
||||
|
||||
There are a number of books on NT driver development, I would recommend
|
||||
'Windows NT Device Driver Development' (http://www.osr.com/book/) since OSR
|
||||
seem to know their stuff. There is only one book on NT filesystem
|
||||
development 'Windows NT File System Internals'. Please don't buy any of
|
||||
these books unless you need to, and can afford it.
|
||||
|
||||
These mailing lists and newsgroups are useful for NT internals related
|
||||
questions,
|
||||
ntfsd@atria.com, ntdev@atria.com
|
||||
(subscribe by email to majordomo@atria.com)
|
||||
comp.os.????
|
||||
microsoft.public.????
|
||||
|
||||
* Style
|
||||
|
||||
There is no coding style used for ReactOS, however the following guidelines
|
||||
make things easier
|
||||
|
||||
Include information at the top of a module about its purpose, contact
|
||||
information for its programmer and any useful notes.
|
||||
|
||||
Include a comment by each non-trival function describing its arguments,
|
||||
purpose and any other notes.
|
||||
|
||||
Update the documentation in this directory
|
||||
|
||||
These guidelines are an ideal, no one manages to implement them all the
|
||||
time, straightforward working code is probably just as good.
|
||||
|
||||
* Debugging
|
||||
|
||||
Debugging kernel-mode code is tricky, these are some snippets
|
||||
|
||||
DbgPrint writes a message to the console using a printf style format
|
||||
string. The DPRINT macro (defined in internal/debug.h) expands to
|
||||
DbgPrint unless NDEBUG is defined, this is useful for having copious
|
||||
output from a module only when a problem is being debugging. DPRINT
|
||||
also prefixes the message with the file and line number to make it
|
||||
easier to see where output is coming from. DbgPrint can be used at any
|
||||
point including in interrupt handlers.
|
||||
|
||||
There are options in ntoskrnl/kd/kdebug.c for copying DbgPrint output
|
||||
to a serial device or bochs logging port (parallel support should also
|
||||
be added). This can be useful if a lot of output is being generated.
|
||||
|
||||
It should be possible to include support for debugging the kernel with
|
||||
gdb over a serial line. Bochs (a shareware CPU emulator) is also useful
|
||||
for debugging the kernel, I wrote some patches to allow capture of console
|
||||
output from within bochs to file and for debugging a kernel running
|
||||
under bochs with gdb. Contact me (welch@cwcom.net) if you're are
|
||||
interested.
|
||||
|
||||
If CPU reports an exception not handled by the kernel (any page fault
|
||||
not part of virtual memory support or any other exception) the kernel
|
||||
will display output like this and halt
|
||||
|
||||
General Protection Fault Exception: 13(0)
|
||||
CS:EIP xxxxxxxx:xxxxxxx
|
||||
DS xxxx ES xxxx FS xxxx GS xxxxx
|
||||
EAX: xxxx EBX: xxxx
|
||||
....
|
||||
EDI: xxxx EFLAGS: xxxx ESP: xxxx
|
||||
cr2: xxxx
|
||||
Stack: xxxx xxxx xxxx ...
|
||||
....
|
||||
Frames: xxxx xxxx xxxx ...
|
||||
....
|
||||
|
||||
The fault type will usually be either 'General Protection' or
|
||||
'Page Fault', see your Intel manual for the more exotic types. The
|
||||
'EIP' number is the address of the faulting instruction. If the 'CS'
|
||||
number is 0x20 then the exception occured in kernel mode, if it is 0x11
|
||||
then the exception occurred in user mode. 'cr2' is the address that the
|
||||
faulting instruction was trying to access, if the exception was a page
|
||||
fault. The number printed after 'Frames' are any addresses on the stack
|
||||
that look like function addresses.
|
||||
|
||||
|
||||
If the kernel detects a serious problem that it will bug check, displaying
|
||||
output like this
|
||||
|
||||
Bug detected (code x, param x x x x)
|
||||
Frames: xxx xxxx xxxx
|
||||
....
|
||||
|
||||
Again the numbers printed after 'Frames' are any addresses on the stack
|
||||
that look like function addresss. Usually the kernel will also print a
|
||||
message describing the problem in more detail, the bug check code isn't
|
||||
very useful at the moment.
|
||||
|
||||
* Contacts
|
||||
|
||||
There is a mailing list for kernel development,
|
||||
|
||||
ros-kernel@reactos.com
|
||||
|
||||
The main developers use a cvs account to coordinate changes, ask
|
||||
rex (rex@lvcablemodem.com) for an account if you are going to be adding
|
||||
a lot of code. Smaller patches can go to the mailing list or to the
|
||||
relevant developer (usually the comment at the top of a module will have
|
||||
an email address). Regular snapshots are made available for download,
|
||||
see the mailing list for announcements.
|
||||
|
||||
* Legal stuff
|
||||
|
||||
The ReactOS project is GPL'ed, please make sure any code submitted is
|
||||
compatible with this.
|
||||
|
||||
The NT4 ddk license agreement allows its usage for developing nt drivers
|
||||
only. Legally therefore it can not be used to develop ReactOS, neither the
|
||||
documentation or the sample code. I'm not a lawyer, but I doubt the
|
||||
effiacy of 'shrinkwrap licenses' particularly on freely downloadable
|
||||
software. The only precendent I know of, in a Scottish court, didn't
|
||||
upload this type of license.
|
||||
|
||||
Also the 'fair use' section of copyright law allows the 'quoting' of small
|
||||
sections from copyrighted documents, e.g. Windows API or DDK documentation
|
6
reactos/doc/INDEX
Normal file
6
reactos/doc/INDEX
Normal file
@@ -0,0 +1,6 @@
|
||||
HACKING: Some notes for adding code to ReactOS
|
||||
DIRS: Explanation of directory layout
|
||||
INTERNALS: Some notes on kernel internals
|
||||
TODO: Bugs and omissions, big and little things that need to be done
|
||||
NOTES: Unsorted material, some of it is redundant
|
||||
BUGLIST: Known bugs, please update when you find one
|
43
reactos/doc/INTERNALS
Normal file
43
reactos/doc/INTERNALS
Normal file
@@ -0,0 +1,43 @@
|
||||
A collection of articles on kernel internals, please add to this
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
IRQ level
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
IRQ level (IRQL) is a per-processor state in ReactOS used to coordinate
|
||||
execution between ISRs and between threads. There are several levels
|
||||
|
||||
PASSIVE_LEVEL, APC_LEVEL: The normal level for user mode and most
|
||||
kernel mode code. At the moment APC_LEVEL is unused.
|
||||
|
||||
DISPATCH_LEVEL: At this level all irqs are still allowed but thread
|
||||
rescheduling on the current processor is disabled. This is used by
|
||||
the spinlock synchronization primitive to implement its uniprocessor
|
||||
semantics (multiprocessor is more complex). It is also used for some
|
||||
other forms of synchronization, DPCs for example. Many APIs are
|
||||
unavailable at this IRQL, usually those that might have to wait. It
|
||||
is recommended that you don't spend too much time at this IRQL
|
||||
otherwise system responsiveness will be reduced.
|
||||
|
||||
> DISPATCH_LEVEL: Each irq is assigned a priority (which will be
|
||||
greater than DISPATCH_LEVEL). At an irq's priority level that irq,
|
||||
lower priority irqs and thread rescheduling are disabled. Higher
|
||||
priority irqs can still run. Very few APIs are available at IRQLs
|
||||
greater than DISPATCH_LEVEL.
|
||||
|
||||
HIGH_LEVEL: All irqs are disabled.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DPCs
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
It is a design goal not to spend too much time in ISRs, for this reason
|
||||
ISRs should postpone most processing till it can run at a lower IRQL. The
|
||||
mechanism for this is a Delayed Procedure Call (DPC). When a DPC object is
|
||||
created, it is associated with a function. The DPC object can then be inserted
|
||||
in the DPC queue from an ISR. If the IRQL on return from the ISR is less than
|
||||
DISPATCH_LEVEL the DPC queue will be drained, otherwise this will happen when
|
||||
the IRQL level drops below DISPATCH_LEVEL or the processor becomes idle. When
|
||||
the DPC queue is drained each DPC object is removed and the associated
|
||||
function is called at DISPATCH_LEVEL. A DPC object can only be inserted once,
|
||||
further insertions before it is removed will have no effect.
|
36
reactos/doc/apc
Normal file
36
reactos/doc/apc
Normal file
@@ -0,0 +1,36 @@
|
||||
APC
|
||||
|
||||
Asynchronous procedure call
|
||||
|
||||
An APC is a Kernel-defined control object representing a procedure
|
||||
that is called asynchronously. APCs are thread-context dependent; that
|
||||
is, they are queued to a particular thread for execution.
|
||||
|
||||
There are three different kinds of APCs in NT:
|
||||
|
||||
User APCs are used by certain asynchronous NT system services to allow
|
||||
user-mode applications or protected subsystems to synchronize the
|
||||
execution of a thread with the completion of an operation or the
|
||||
occurrence of an event such as a timers expiration. User APCs are, by
|
||||
default, disabled. That is, they are queued to the user-mode thread,
|
||||
but they are not executed except at well-defined points in the
|
||||
program. Specifically, they can only be executed when an application
|
||||
or protected subsystem has called a wait service and has enabled
|
||||
alerts to occur, or if it has called the test-alert service.
|
||||
|
||||
Kernel APCs are normal kernel-mode APCs. They are much like a normal
|
||||
user APC except that they are executable by default. That is, they are
|
||||
enabled except when the thread is already executing a Kernel APC.
|
||||
(Note that a special Kernel APC always preempts these.)
|
||||
|
||||
Special Kernel APCs cannot be blocked except by running at a raised
|
||||
IRQL. They are executed at APC_LEVEL IRQL (see IDT), in kernel mode.
|
||||
These types of APCs are used by the system to force a thread to
|
||||
execute a procedure in the threads context. An example of this is I/O
|
||||
completion: the I/O Manager needs to get back into the context of the
|
||||
original requestor of the I/O operation so that it can copy buffers,
|
||||
and so forth. In order to do this, the I/O Manager must be able to
|
||||
access the virtual address space of the thread/process, and the most
|
||||
efficient way to complete the operation is to be in the calling
|
||||
threads context.
|
||||
|
@@ -1,140 +0,0 @@
|
||||
This file attempts to document the functions made publically available by
|
||||
the various subsystems.
|
||||
|
||||
* Formatted I/O operations *
|
||||
|
||||
NAME: int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
NAME: int sprintf(char* buf, const char* fmt, ...)
|
||||
WHERE: internal/kernel.h
|
||||
FUNCTION: The same as the standard c library versions
|
||||
|
||||
* PIO operations *
|
||||
|
||||
NAME: in[b/w/l](port)
|
||||
WHERE: internal/io.h
|
||||
FUNCTION: Read an IO port of the specified size (byte/word or long)
|
||||
RETURNS: The value read
|
||||
|
||||
NAME: out[b/w/l](port,val)
|
||||
WHERE: internal/io.h
|
||||
FUNCTION: Write an IO port of the specified size (byte/word or long)
|
||||
|
||||
NAME: in_p[b/w/l](port)
|
||||
WHERE: internal/io.h
|
||||
FUNCTION: Read an IO port of the specified size (byte/word or long) with
|
||||
a pause
|
||||
RETURNS: The value read
|
||||
|
||||
NAME: out_p[b/w/l](port,val)
|
||||
WHERE: internal/io.h
|
||||
FUNCTION: Write an IO port of the specified size (byte/word or long) with
|
||||
a pause
|
||||
|
||||
* Bit operations *
|
||||
|
||||
NAME: int set_bit(int nr, void* addr)
|
||||
NAME: int clear_bit(int nr, void* addr)
|
||||
NAME: int change_bit(int nr, void* addr)
|
||||
WHERE: internal/bitops.h>
|
||||
FUNCTION: Operate on a bit in the word pointed to by addr
|
||||
RETURN: 0 if the bit was cleared before the operations
|
||||
non-zero otherwise
|
||||
|
||||
* Debugging functions *
|
||||
|
||||
NAME: DPRINT(fmt,....)
|
||||
WHERE: internal/debug.h
|
||||
FUNCTION: Outputs a string to the console if NDEBUG isn't defined before
|
||||
including internal/debug.h, a NOP otherwise
|
||||
ARGUMENTS: The same as printf
|
||||
|
||||
NAME: printk
|
||||
WHERE: internal/kernel.h
|
||||
FUNCTION: Outputs a string to the console
|
||||
ARGUMENTS: The same as printf
|
||||
|
||||
* Memory managment functions *
|
||||
|
||||
NAME: unsigned int physical_to_linear(unsigned int paddr)
|
||||
WHERE: hal/page.h
|
||||
FUNCTION: Converts a physical address to a linear one
|
||||
RECEIVES:
|
||||
paddr = the physical address to convert
|
||||
RETURNS: A virtual address where the memory at that physical address can be
|
||||
accessed
|
||||
|
||||
NAME: void* ExAllocatePool(unsigned int size, unsigned int type = 0);
|
||||
WHERE: internal/pool.h
|
||||
FUNCTION: Allocates a block of memory
|
||||
RECEIVES:
|
||||
size = the size of the block to allocate
|
||||
type = will be whether to allocate pagable memory
|
||||
RETURNS: The address of the block
|
||||
NOTE: This isn't interrupt safe
|
||||
|
||||
NAME: void ExFreePool(void* block)
|
||||
WHERE: internal/pool.h
|
||||
FUNCTION: Frees a block of memory
|
||||
|
||||
NAME: void free_page(unsigned int physical_base, unsigned int nr = 1)
|
||||
WHERE: internal/mm.h
|
||||
FUNCTION: Adds a continuous range of physical memory to the free list
|
||||
|
||||
NAME: unsigned int get_free_page(void)
|
||||
WHERE: internal/mm.h
|
||||
FUNCTION: Gets a free page
|
||||
RETURNS: Its physical address
|
||||
|
||||
NAME: unsigned int get_page_physical_address(unsigned int vaddr)
|
||||
WHERE: internal/mm.h
|
||||
FUNCTION: Gets the physical address of a page
|
||||
|
||||
NAME: void mark_page_not_writable(unsigned int vaddr)
|
||||
WHERE: internal/mm.h
|
||||
FUNCTION: Prevent writing the page
|
||||
|
||||
* DMA functions *
|
||||
|
||||
NAME: unsigned int get_dma_page(unsigned int max_address)
|
||||
WHERE: internal/mm.h
|
||||
FUNCTION: Gets a page with a restricted physical address i.e. suitable for
|
||||
dma
|
||||
RETURNS: The physical address of the page
|
||||
|
||||
NAME: void disable_dma(unsigned int dmanr)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Disables the specified dma channel
|
||||
|
||||
NAME: void enable_dma(unsigned int dmanr)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Enables the specified dma channel
|
||||
|
||||
NAME: void clear_dma_ff(unsigned int dmanr)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Clear the dma flip-flop
|
||||
|
||||
NAME: void set_dma_mode(unsigned int dmanr, char mode)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Sets the type of dma transfer
|
||||
|
||||
NAME: void set_dma_page(unsigned int dmanr, char pagenr)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Set only the page register bits of the transfer address
|
||||
|
||||
NAME: void set_dma_addr(unsigned int dmanr, unsigned int a)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Set the transfer address for dma
|
||||
NOTE: Assumes flip-flop is clear
|
||||
|
||||
NAME: void set_dma_count(unsigned int dmanr, unsigned int count)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Sets the size of the transfer
|
||||
ARGUMENTS:
|
||||
count = the number of bytes to transfer
|
||||
NOTE: Count must be even for channels 5-7
|
||||
|
||||
NAME: int get_dma_residue(unsigned int dmanr)
|
||||
WHERE: internal/dma.h
|
||||
FUNCTION: Gets the residue remaining after a dma transfer on the channel
|
||||
|
||||
|
@@ -1,2 +0,0 @@
|
||||
* Kernel bugs not fixed
|
||||
|
@@ -1,27 +0,0 @@
|
||||
This is a list of the functions documented in the ddk that have been
|
||||
implemented
|
||||
|
||||
IoAllocateController
|
||||
IoFreeController
|
||||
IoCreateController
|
||||
IoDeleteController
|
||||
IoStartNextPacket
|
||||
IoStartNextPacketByKey
|
||||
IoStartPacket
|
||||
IoSizeOfIrp
|
||||
IoMarkIrpPending
|
||||
IoFreeIrp
|
||||
IoConnectInterrupt
|
||||
IoDisconnectInterrupt
|
||||
IoGetCurrentIrpStackLocation
|
||||
IoGetNextIrpStackLocation
|
||||
IoRequestDpc
|
||||
IoInitializeDpc
|
||||
IoInitializeTimer
|
||||
IoStartTimer
|
||||
IoStopTimer
|
||||
|
||||
Partially implemented
|
||||
|
||||
IoCreateDevice
|
||||
IoCallDriver
|
@@ -1,19 +0,0 @@
|
||||
Some notes on debugging the ReactOS kernel
|
||||
------------------------------------------
|
||||
|
||||
* Interpreting crashes
|
||||
|
||||
If the kernel causes a fatal cpu fault then it will print out a message and
|
||||
halt. This message contains important information for debugging the problem,
|
||||
look for these lines
|
||||
|
||||
Exception: xx(yy)
|
||||
CS:EIP 20:zzzzzzzzzzzz
|
||||
|
||||
Here xx is the type of error, usually either 14 or 13 and yy is the error
|
||||
code. Generally error codes 13 and 14 both mean the kernel tried to access
|
||||
some memory in an invalid way. zzzzzzzzz is the address of the erronous
|
||||
instruction.
|
||||
|
||||
* Debugging with bochs
|
||||
|
@@ -1,114 +0,0 @@
|
||||
Kernel Development FAQ (for v0.0.7)
|
||||
|
||||
This attempts to answer some of the common questions people developing for
|
||||
the kernel might want to ask (or at least what I think they should ask).
|
||||
Obviously I can only detail those parts which I have written so other
|
||||
developers please fill in the gaps.
|
||||
|
||||
Q: What is this, what are you people, what's going on
|
||||
A: This is the ReactOS, an operating system intended as a clone of windows
|
||||
NT. See the project website (http://www.sid-dis.com/reactos/) for more details.
|
||||
|
||||
Q: Why ReactOS
|
||||
A: To condemn Bill Gates to penury.
|
||||
|
||||
Q: What do I need to compile the kernel
|
||||
A: DJGPP, get it from http://www.delorie.com/djgpp
|
||||
|
||||
Q: How do I compile the kernel
|
||||
A: Unpack the zip. It is important not to install the kernel in the same
|
||||
directory as a previous version, this has caused a bit of confusion in the
|
||||
past. Edit the makefile in the top level directory, in particular select the
|
||||
correct host to build from. Then run make in the top directory
|
||||
|
||||
Q: What files are created when I make the kernel
|
||||
A: The following files are created in the kernel directory
|
||||
kimage = the kernel as a coff executable
|
||||
kimage.bin = the kernel as a raw binary image
|
||||
kernel.sym = a list of the kernel symbols
|
||||
|
||||
Q: How do I load the kernel
|
||||
A: Run the boot.bat batch file.
|
||||
|
||||
Q: Does it boot from disk
|
||||
A: Not at the moment.
|
||||
|
||||
Q: When I run the kernel it crashes
|
||||
A: The kernel (at the moment) can only be loaded from a clean system. That
|
||||
is one without EMM386 or any version of windows loaded. A quick way to
|
||||
ensure this (if you have windows 95) is to set the program to run in msdos
|
||||
mode and specify an empty config.sys and autoexec.bat. See the windows help
|
||||
for more information.
|
||||
|
||||
If you do that and the problem persists then contact the kernel team
|
||||
(ros-kernel@sid-dis.com) as it is probably a bug in the kernel
|
||||
|
||||
Q6: How do I load a module with the kernel
|
||||
A: Add the names of any modules to be loaded to the command line of boot.bat.
|
||||
|
||||
Q7: I want to add code to the kernel, how do I get it to be compiled
|
||||
A: You will need to edit the Makefile in kernel directory. There should be
|
||||
a statement like this
|
||||
|
||||
OBJECTS = hal/head.o hal/exp.o kernel/vsprintf.o \
|
||||
....
|
||||
kernel/irqhand.o hal/page.o mm/virtual.o kernel/error.o \
|
||||
kernel/exports.o kernel/module.o
|
||||
|
||||
Add the name of the object file (the file produced when your code is
|
||||
compiled) to the end of the statement (in this case after kernel/module.o).
|
||||
If you need to go onto a new line then add a slash to the end of the
|
||||
previous line. It is also very important to use an editor which preserves
|
||||
tabs.
|
||||
|
||||
Q8: I want to add code to the kernel, how do I make it official
|
||||
A: Contact the kernel mailing list ros-kernel@sid-dis.com or our coordinator
|
||||
dwinkley@whitworth.edu. If it is for a specific section then the kernel
|
||||
website (http://www.geocities.com/SiliconValley/Peaks/1957) has a list of
|
||||
those working on individual areas, you might what to contact one of them
|
||||
instead.
|
||||
|
||||
Q9: What header files should I use
|
||||
A: Don't include the usual DJGPP headers like stdio.h unless you are using
|
||||
something compiler based like stdargs.h. To use the DJGPP headers requires
|
||||
linking with libc which is useless in kernel mode.
|
||||
|
||||
All the header files are in the top-level include directory which is laid
|
||||
out like this
|
||||
include = general win32 api declarations
|
||||
include/internal = private kernel headers
|
||||
include/internal/hal = HAL headers
|
||||
include/ddk = header files with declarations for modules
|
||||
|
||||
There should be a file called api.txt which documents all of the functions
|
||||
(and which header files they need).
|
||||
|
||||
Q11: I want to export my function for modules to use, how do I do that
|
||||
A: Add the function to the list in kernel/exports.lst, then remake the
|
||||
kernel. Note the function must be declared as extern "C".
|
||||
|
||||
Q12: I want to make my functions part of the kernel interface to user mode,
|
||||
A: That section isn't finished yet, though it will probably mean adding a
|
||||
pointer to the function and the size of its parameters to a internal table
|
||||
somewhere.
|
||||
|
||||
Q14: I want to write a module, what are the guidelines
|
||||
A: See modules.txt in this directory
|
||||
|
||||
Q15: I want to write an ISR (interrupt service routine)
|
||||
A: See irq.txt in this directory
|
||||
|
||||
Q16: I want to use DMA
|
||||
A: Firstly this answer covers only DMA via the dma chips *not*
|
||||
busmaster DMA.
|
||||
|
||||
To program the dma chip use the functions in internal/dma.h (look in api.txt
|
||||
for details). PC DMA can only go to memory with a physical address below
|
||||
1mb (or 16mb on some systems), use the get_dma_page to allocate this kind
|
||||
of memory.
|
||||
|
||||
Q17: You haven't answered my question
|
||||
A: Send your questions to ros-kernel@sid-dis.com
|
||||
|
||||
|
||||
- David Welch (welch@mcmail.com)
|
@@ -1,10 +0,0 @@
|
||||
This document describes the implementation of the memory managment
|
||||
|
||||
|
||||
* ReactOS memory map
|
||||
|
||||
0x00000000 - 0xc0000000 = User memory
|
||||
0xc0000000 - 0xd0000000 = Kernel memory
|
||||
0xd0000000 - 0xffffffff = Identify map of physical memory
|
||||
|
||||
*
|
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
This contains documentation describing the internals of the various kernel
|
||||
subsystems and a few other useful bits of information.
|
@@ -1,135 +0,0 @@
|
||||
** Introduction
|
||||
|
||||
This attempts to document the ReactOS irq handling. As of v0.0.8 this has
|
||||
changed to be more nt like, I will attempt to summarize the new
|
||||
implementation for those unavailable with nt device driver writing. Note,
|
||||
ReactOS doesn't have an exact implementation but the omissions are, except
|
||||
where noted, not user visible.
|
||||
|
||||
** Steps in grabbing an irq vector
|
||||
|
||||
* Call HalConnectInterrupt
|
||||
|
||||
PROTOTYPE:
|
||||
|
||||
ULONG HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
OUT PKIRQL Irql,
|
||||
OUT PKAFFINITY Affinity)
|
||||
|
||||
PURPOSE:
|
||||
|
||||
Translates a bus dependant interrupt vector to a system vector
|
||||
|
||||
ARGUMENTS:
|
||||
|
||||
InterfaceType = Type of bus to which the device to receive interrupts
|
||||
from is connected to. Currently only 'Internal' is
|
||||
recognized
|
||||
BusNumber = Number of the bus the device is connected to
|
||||
(currently ignored)
|
||||
BusInterruptLevel = Bus specific interrupt level (currently ignored)
|
||||
BusInterruptVector = Bus specific vector. Currently this is the same
|
||||
as the normal vector (09 is the keyboard vector
|
||||
for example)
|
||||
Irql = On return contains the DIRQL for the vector
|
||||
Affinity = On return contains the affinity mask for the vector
|
||||
(currently unimplemented)
|
||||
|
||||
RETURNS:
|
||||
The system mapped vector
|
||||
|
||||
* Call IoConnectInterrupt
|
||||
|
||||
PROTOTYPE:
|
||||
|
||||
NTSTATUS IoConnectInterrupt(OUT PKINTERRUPT* InterruptObject,
|
||||
PKSERVICE_ROUTINE ServiceRoutine,
|
||||
PVOID ServiceContext,
|
||||
PKSPIN_LOCK SpinLock,
|
||||
ULONG Vector,
|
||||
KIRQL Irql,
|
||||
KIRQL SynchronizeIrql,
|
||||
KINTERRUPT_MODE InterruptMode,
|
||||
BOOLEAN ShareVector,
|
||||
KAFFINITY ProcessorEnableMask,
|
||||
BOOLEAN FloatingSave)
|
||||
|
||||
PURPOSE:
|
||||
|
||||
Connect a service routine to an interrupt vector
|
||||
|
||||
ARGUMENTS:
|
||||
|
||||
InterruptObject = Points to an object describes the interrupt on
|
||||
return
|
||||
ServiceRoutine = Function to be called when the device interrupts
|
||||
ServiceContext = Parameters to be passed to the service routine
|
||||
SpinLock = Should be NULL
|
||||
Vector = System mapped vector returned from HalGetInterruptVector
|
||||
Irql = DIRQL returned from HalGetInterruptVector
|
||||
SynchronizeIrql = Should be the same as Irql
|
||||
InterruptMode = Device interrupt type (currently ignored)
|
||||
ShareVector = True if the interrupt vector can shared
|
||||
ProcessorEnableMask = Currently ignored
|
||||
FloatingSave = Should be false
|
||||
|
||||
RETURNS: Status
|
||||
|
||||
* Sample code for snarfing an interrupt vector
|
||||
|
||||
|
||||
void grab_my_irq()
|
||||
{
|
||||
ULONG MappedIrq;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity;
|
||||
PKINTERRUPT IrqObject;
|
||||
|
||||
MappedIrq = HalGetInterruptVector(Internal,
|
||||
0,
|
||||
0,
|
||||
MY_VECTOR,
|
||||
&Dirql,
|
||||
&Affinity);
|
||||
IoConnectInterrupt(&IrqObject,
|
||||
my_irq_service_routine,
|
||||
my_context,
|
||||
NULL,
|
||||
MappedIrq,
|
||||
Dirql,
|
||||
Dirql,
|
||||
0,
|
||||
FALSE, // Not sharable
|
||||
Affinity,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
** Designing an interrupt service routine
|
||||
|
||||
An interrupt service routine should have the following prototype
|
||||
|
||||
BOOLEAN my_irq_service_routine(PKINTERRUPT Interrupt,
|
||||
PVOID ServiceContext);
|
||||
|
||||
ARGUMENTS:
|
||||
|
||||
Interrupt = The same as the object returned from the
|
||||
IoConnectInterrupt
|
||||
ServiceContext = A user defined parameters
|
||||
(passed to IoConnectInterrupt)
|
||||
|
||||
RETURNS:
|
||||
|
||||
True if it handled the interrupt, false if it should be passed onto
|
||||
other devices sharing the same vector
|
||||
|
||||
NOTES:
|
||||
|
||||
While an isr is executing all devices of a lower or equal priority
|
||||
can't interrupt. For this reason it is important that an isr
|
||||
should complete in a short an interval as possible. The set of
|
||||
routines an isr can call is also restricted.
|
||||
|
@@ -1,21 +0,0 @@
|
||||
This document describes the state of a uniprocessor PC at each of the IRQ
|
||||
levels supported by the ReactOS kernel
|
||||
|
||||
PASSIVE_LEVEL: IF bit clear in the processor flags
|
||||
All irqs umasked at the PIC
|
||||
|
||||
APC_LEVEL: Unknown
|
||||
WAKE_LEVEL: Unknown
|
||||
|
||||
DISPATCH_LEVEL: IF bit clear in the processor flags
|
||||
All irqs umasked at the PIC
|
||||
Thread dispatching disabled
|
||||
|
||||
DIRQL (Device specific IRQ level):
|
||||
IF bit clear in the processor flags
|
||||
Device's irq and all lower priority irqs masked at the PIC
|
||||
Thread dispatching disabled
|
||||
|
||||
HIGH_LEVEL: IF bit set in the processor flags
|
||||
All irqs masked at the PIC
|
||||
Thread dispatching disabled
|
@@ -1,33 +0,0 @@
|
||||
** Introduction
|
||||
|
||||
This is (an incomplete) guide to writing device drivers (and other kernel
|
||||
extensions) for ReactOS.
|
||||
|
||||
** Setting up the build environment
|
||||
|
||||
Create a new subdirectory in the modules directory and copy one of the
|
||||
existing module makefiles into it. Customize the makefile to compile the
|
||||
source files for the module. Note: generally it is not necessary to specify
|
||||
the compiler or compiler flags to use.
|
||||
|
||||
** Initializing a module
|
||||
|
||||
On loading the kernel will call the module function
|
||||
|
||||
PROTOTYPE:
|
||||
|
||||
NTSTATUS ModuleEntry(PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
|
||||
PURPOSE:
|
||||
|
||||
Initializing the module
|
||||
|
||||
ARGUMENTS:
|
||||
|
||||
DriverObject = Pointer to an object describing the driver
|
||||
RegistryPath = Currently NULL
|
||||
|
||||
RETURNS:
|
||||
|
||||
STATUS_SUCCESS = If the module initialized successfully
|
696
reactos/doc/notes
Normal file
696
reactos/doc/notes
Normal file
@@ -0,0 +1,696 @@
|
||||
*** This file contains messages I've culled off the net as well
|
||||
as previous discussions all of which have useful info on fixes
|
||||
that need to be added to ReactOS. messages are between five
|
||||
dashes on a line by themselves. If you implement the fix
|
||||
reffered to in a message, feel free to delete it from the file.
|
||||
Rex ***
|
||||
-----
|
||||
Subject: [ros-kernel] Inside the Boot Process
|
||||
Date: Mon, 22 Mar 1999 22:05:47 +0100
|
||||
From: Emanuele Aliberti <ea@iol.it>
|
||||
|
||||
For those working on the boot loader: in WinNt Magazine november 1998
|
||||
issue (http://www.winntmag.com/) there is a detailed description, by
|
||||
Mark Russinovich, of the r<>le the MBR, NTLDR, boot.ini, ntdetect.com...
|
||||
play in the boot process ("Inside the Boot Process, Part 1").
|
||||
-----
|
||||
Yes with DPCs, KeDrainDpcQueue should go to HIGH_LEVEL because
|
||||
it needs to synchronize with KeInsertDpcQueue. Also the idle thread
|
||||
should run at DISPATCH_LEVEL and regularly drain the dpc queue, that
|
||||
way if an irq happens and the dpc can't be executed immediately it
|
||||
will be executed as soon as the processor is idle rather than
|
||||
waiting for the next timer tick
|
||||
-----
|
||||
About the console driver, I think it might be quite useful to have a simple
|
||||
way for apps to print to the screen for debugging. But when the kernel is more
|
||||
stable, console handling should be moved to user level because console printing
|
||||
needs to know about windows and so on which can only be done at user level.
|
||||
-----
|
||||
Subject: Re: IMSAMP-how to avoid rebooting?
|
||||
Date: 9 Nov 1998 00:40:32 -0000
|
||||
From: Charles Bryant <n51190709.ch@chch.demon.co.uk>
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1, 2 , 3 , 4
|
||||
|
||||
In article <un264wzle.fsf@xxx.yyy.zzz>, David C. <qqqq@xxx.yyy.zzz> wrote:
|
||||
>The reason it won't unload when something is bound to it is the same
|
||||
>reason you can't unload any other driver that has an open client. If
|
||||
>you install any driver, and have a user program (or another driver) open
|
||||
>a handle to it, and then give the "net stop" command to unload it,
|
||||
>you'll find that the unload will be delayed until the user program
|
||||
>closes its handle.
|
||||
|
||||
When developing a driver I found this to be a considerable nuisance.
|
||||
Frequently a bug would leave an IRP stuck in the driver and I
|
||||
couldn't unload and reload a fixed version. While reading NTDDK.H I
|
||||
found a suspicious constant and discovered that the Flags field in
|
||||
the device (the one which you OR in DO_BUFFERED_IO or DO_DIRECT_IO)
|
||||
has a bit called DO_UNLOAD_PENDING. By experiment I confirmed that
|
||||
this bit is set when you do 'net stop', so a driver can check it
|
||||
periodically (e.g. from a timer DPC every ten seconds) and cancel all
|
||||
queued IRPs if it is found to be set.
|
||||
|
||||
Since this is not documented anywhere that I can find, it might be
|
||||
unwise to rely on it for production code, but it is very useful for
|
||||
debugging. Maybe someone with internals knowledge can comment on the
|
||||
reliability of it.
|
||||
-----
|
||||
Subject: Re: Kernel bugs
|
||||
Date: Fri, 23 Oct 1998 12:08:36 -0700
|
||||
From: rex <rex@lvcablemodem.com>
|
||||
To: Jason Filby <jasonfilby@yahoo.com>
|
||||
References: 1
|
||||
|
||||
Jason Filby wrote:
|
||||
|
||||
> Hi,
|
||||
>
|
||||
> Ok -- here's most of what I get when I press a key:
|
||||
>
|
||||
> Page fault detected at address 1fd4 with eip c042f794
|
||||
> Recursive page fault detected
|
||||
> Exception 14(2)
|
||||
> CS:EIP 20:c042f794
|
||||
>
|
||||
> Rex -- do you know of anyway to find out which function in what file
|
||||
> is causing the exception? I know that for problems in the kernel, you
|
||||
> just look in the ntoskrnl\kernel.sym file and find the EIP value which
|
||||
> matches the one given in the exception debug text. But what about
|
||||
> modules? How can we track exceptions that occur in functions in modules?
|
||||
>
|
||||
|
||||
I know this is a little belated, but I thought I'd take astab at answering
|
||||
this anyway. add an option to the
|
||||
makefile for the module to generate a listing file with
|
||||
symbol information. Then, on a boot test, note the
|
||||
address that the module is loaded at, and subtract
|
||||
this from the EIP value. add any offset used in the
|
||||
module link specification (I dont think there currently
|
||||
is one), and look for the last symbol with a lower
|
||||
address offset.
|
||||
|
||||
Brian, I have an idea on how to make this exception
|
||||
dump information a little more useful. We should
|
||||
have the load information for the load modules
|
||||
in memory somewhere. Perhaps the exception
|
||||
dump could check offending addresses to see if
|
||||
they lie in the kernel or in a module, and if they
|
||||
lie in a module the proper offset could be subtracted
|
||||
and this number could be displayed seperately. If
|
||||
I get a chance today, I'll make this change and send
|
||||
it to ya.
|
||||
|
||||
Rex.
|
||||
-----
|
||||
Subject: [ros-kernel] Pet peeve of the week
|
||||
Resent-Date: Sun, 25 Oct 1998 11:57:40 -0600
|
||||
Resent-From: ros-kernel@sid-dis.com
|
||||
Date: Sun, 25 Oct 1998 09:53:48 -0800
|
||||
From: rex <rex@lvcablemodem.com>
|
||||
Reply-To: <ros-kernel@sid-dis.com>
|
||||
To: ReactOS Kernel Forum <ros-kernel@sid-dis.com>
|
||||
|
||||
Hi all,
|
||||
|
||||
I guess it's about time to start another mailstorm
|
||||
on the list. :)
|
||||
|
||||
I have a suggestion for a change to the kernel.
|
||||
It not a very big change, and I hope everyone
|
||||
will agree that it makes sense.
|
||||
|
||||
There is a structure used in many places in the
|
||||
kernel called LARGE_INTEGER. the is also
|
||||
a version called ULARGE_INTEGER, but it
|
||||
is not used at all as far as I can tell. this structure
|
||||
is equivalent to a long long int. You can literally
|
||||
cast a pointer to a LARGE_INTEGER to a
|
||||
long long int and all manipulation will work
|
||||
seemlessly. My suggestion is that we replace the
|
||||
use of this structure with long long ints. Even
|
||||
microsoft, in their infinite wisdom, has made this
|
||||
suggestion in the DDK documentation. If you're
|
||||
wondering where, look at the RTL functions
|
||||
that manipulate LARGE_INTEGER structs.
|
||||
|
||||
Replacing LI's with long long ints will work
|
||||
because they are binary compatable. All software
|
||||
compiled to use LI's will manipulate long long ints
|
||||
correctly and vice versa. There is one problem
|
||||
with this suggestion: the LARGE_INTEGER type
|
||||
is a structure containing 2 members. Any code
|
||||
that accesses the structure by members will break.
|
||||
I think the kernel side impact is minimal, and is
|
||||
worth the change. However, the structure is used
|
||||
in several of the Win32 API functions, and needs
|
||||
to remain there. I think we build a conditionally
|
||||
compiled version of the LARGE_INTEGER type.
|
||||
In kernel mode code (the kernel proper and drivers)
|
||||
the LARGE INTEGER will be the following:
|
||||
|
||||
typedef long long int LARGE_INTEGER,
|
||||
*PLARGE_INTEGER;
|
||||
typedef unsigned long long int ULARGE_INTEGER,
|
||||
*PULARGE_INTEGER;
|
||||
|
||||
and in user mode code it will expand out to the
|
||||
current definition (which by the way, is not
|
||||
strictly correct, but can't be because it uses a
|
||||
MS compiler extension).
|
||||
|
||||
Brian, I would be willing to make the conversion
|
||||
to those kernel modules that needed it, and of
|
||||
course to the IDE driver if we want to go forward
|
||||
with the change.
|
||||
|
||||
Lastly, I'll mention what made me consider this.
|
||||
I was fixing the timer routines, and two of the
|
||||
three problems turned out to be related to LI
|
||||
conversion problems.
|
||||
|
||||
Rex.
|
||||
-----
|
||||
Subject: Re: [ros-kernel] Pet peeve of the week
|
||||
Date: Thu, 29 Oct 1998 19:10:37 +0100
|
||||
From: Boudewijn <ariadne@xs4all.nl>
|
||||
To: rex@lvcablemodem.com
|
||||
References: 1
|
||||
|
||||
Hai Rex
|
||||
|
||||
I think it is a good idea to wrap a makro around the member access
|
||||
to large integers.
|
||||
I haven't tested this, but do you think this is a good sugestion ?
|
||||
|
||||
#ifdef COMPILER_LARGE_INTEGERS
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >>
|
||||
32) )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger &
|
||||
0xFFFFFFFF) )
|
||||
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
|
||||
LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
|
||||
LargeInteger |= Unsigned_Long )
|
||||
#else
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (
|
||||
LargeInteger.HighPart) )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) (
|
||||
(LargeInteger.LowPart) )
|
||||
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
|
||||
LargeInteger.HighPart= Signed_Long )
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
|
||||
LargeInteger.LowPart = Unsigned_Long )
|
||||
#endif
|
||||
|
||||
Boudewijn
|
||||
-----
|
||||
Subject: Re: Question on "Sending buffers on the stack to asynchronous DeviceIoControl with buffered I/O"
|
||||
Date: Mon, 16 Nov 1998 11:24:57 -0800
|
||||
From: "-Paul" <paulsan@microsoftSPAM.com>
|
||||
Organization: Microsoft Corp.
|
||||
Newsgroups: microsoft.public.win32.programmer.kernel, comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
Radu, I post the following information occassionally for questions such as
|
||||
yours. I hope it helps.
|
||||
|
||||
-Paul
|
||||
|
||||
Here is an explanation of buffers and DeviceIoControl.
|
||||
|
||||
First, here are the parameters,
|
||||
|
||||
BOOL DeviceIoControl(
|
||||
HANDLE hDevice, // handle to device of interest
|
||||
DWORD dwIoControlCode, // control code of operation to perform
|
||||
LPVOID lpInBuffer, // pointer to buffer to supply input data
|
||||
DWORD nInBufferSize, // size of input buffer
|
||||
LPVOID lpOutBuffer, // pointer to buffer to receive output data
|
||||
DWORD nOutBufferSize, // size of output buffer
|
||||
LPDWORD lpBytesReturned, // pointer to variable to receive output byte
|
||||
count
|
||||
LPOVERLAPPED lpOverlapped // pointer to overlapped structure for
|
||||
asynchronous operation
|
||||
);
|
||||
|
||||
METHOD_BUFFERED
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver
|
||||
lpOutBuffer - optional, contains data that is read from the driver after
|
||||
the call has completed
|
||||
|
||||
lpInBuffer and lpOutBuffer can be two buffers or a single shared buffer.
|
||||
If a shared buffer, lpInBuffer is overwritten by lpOutBuffer.
|
||||
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
examines nInBufferSize and nOutBufferSize. Allocates memory from non-paged
|
||||
pool and puts the address of this pool in Irp->AssociatedIrp.SystemBuffer.
|
||||
The size of this buffer is equal to the size of the larger of the two
|
||||
bufferes. This buffer is accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
calls your driver
|
||||
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
you have one buffer, Irp->AssociatedIrp.SystemBuffer. You read input data
|
||||
from this buffer and you write output data to the same buffer, overwriting
|
||||
the input data.
|
||||
|
||||
Before calling IoCompleteRequest, you must
|
||||
- set IoStatus.Status to an approriate NtStatus
|
||||
- if IoStatus.Status == STATUS_SUCCESS
|
||||
set IoStatus.Information to the
|
||||
number of bytes you want copied
|
||||
from the SystemBuffer back into
|
||||
lpOutBuffer.
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
looks at IoStatus block, if IoStatus.Status = STATUS_SUCCESS, copies the
|
||||
number of bytes specified by IoStatus.Information from
|
||||
Irp->AssociatedIrp.SystemBuffer into lpOutBuffer
|
||||
completes the request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_IN_DIRECT
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver. This
|
||||
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
|
||||
confusion, mentally rename this buffer to lpControlBuffer. This is
|
||||
typically a small, optional buffer that might contain a control structure
|
||||
with useful information for the device driver. This buffer is smal and is
|
||||
double buffered.
|
||||
|
||||
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is read by
|
||||
the driver. To avoid confusion, mentally rename this buffer to
|
||||
lpDataTransferBuffer. This is physically the same buffer that the device
|
||||
driver will read from. There is no double buffering. Technically, this
|
||||
buffer is still optional, but since you are using this buffering method,
|
||||
what would be the point???
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
If lpInBuffer exists, allocates memory from non-paged pool and puts the
|
||||
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
|
||||
accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
So far this is completely identical to METHOD_BUFFERED. Most likely
|
||||
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
|
||||
|
||||
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
|
||||
allocated. lpOutBuffer is probed and locked into memory. Then, the user
|
||||
buffer virtual addresses are checked to be sure they are readable in the
|
||||
caller's access mode.
|
||||
|
||||
The MDL is address is stored in Irp->MdlAddress.
|
||||
Your driver is called.
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
The device driver can read the copy of lpOutBuffer via
|
||||
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
|
||||
this buffer is lost. The I/O Manager does not copy any data back to the
|
||||
user-mode buffers as it did in the completion routine for METHOD_BUFFERED.
|
||||
Art Baker's book is wrong in this respect (page 168, "data going from the
|
||||
driver back to the caller is passed through an intermediate system-space
|
||||
buffer" and page 177, "When the IOCTL IRP is completed, the contents of the
|
||||
system buffer will be copied back into the callers original output buffer".
|
||||
|
||||
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
|
||||
The driver uses whatever Mdl API's to read the buffer. Usually, this
|
||||
buffer is to be written to some mass storage media or some similar
|
||||
operation. Since this is a large data transfer, assume a completion
|
||||
routine is required.
|
||||
|
||||
mark the Irp pending
|
||||
queue it
|
||||
return status pending
|
||||
|
||||
|
||||
|
||||
|
||||
Device Driver Completion Routine perspective
|
||||
|
||||
standard completion routine operations
|
||||
set IoStatus.Status to an approriate NtStatus
|
||||
IoStatus.Information is not needed
|
||||
completete the request
|
||||
|
||||
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
standard I/O Manager completion routine operations
|
||||
unmap the pages
|
||||
deallocate the Mdl
|
||||
complete the request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_OUT_DIRECT
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver. This
|
||||
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
|
||||
confusion, mentally rename this buffer to lpControlBuffer. This is
|
||||
typically a small, optional buffer that might contain a control structure
|
||||
with useful information for the device driver. This buffer is smal and is
|
||||
double buffered.
|
||||
|
||||
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is written
|
||||
by the driver and read by the wer-mode application when the request is
|
||||
completed. To avoid confusion, mentally rename this buffer to
|
||||
lpDataTransferBuffer. This is physically the same buffer that the device
|
||||
driver will write to. There is no double buffering. Technically, this
|
||||
buffer is still optional, but since you are using this buffering method,
|
||||
what would be the point???
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
If lpInBuffer exists, allocates memory from non-paged pool and puts the
|
||||
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
|
||||
accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
So far this is completely identical to METHOD_BUFFERED. Most likely
|
||||
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
|
||||
|
||||
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
|
||||
allocated. lpOutBuffer is probed and locked into memory. Then the user
|
||||
buffer's addresses are checked to make sure the caller could write to them
|
||||
in the caller's access mode.
|
||||
|
||||
The MDL is address is stored in Irp->MdlAddress.
|
||||
Your driver is called.
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
The device driver can read the copy of lpOutBuffer via
|
||||
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
|
||||
this buffer is lost.
|
||||
|
||||
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
|
||||
The driver uses whatever Mdl API's to write data to the buffer. Usually,
|
||||
this buffer is to be read from some mass storage media or some similar
|
||||
operation. Since this is a large data transfer, assume a completion
|
||||
routine is required.
|
||||
|
||||
mark the Irp pending
|
||||
queue it
|
||||
return status pending
|
||||
|
||||
|
||||
|
||||
|
||||
Device Driver Completion Routine perspective
|
||||
|
||||
standard completion routine operations
|
||||
set IoStatus.Status to an approriate NtStatus
|
||||
IoStatus.Information is not needed
|
||||
completete the request
|
||||
|
||||
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
standard I/O Manager completion routine operations
|
||||
unmap the pages
|
||||
deallocate the Mdl
|
||||
complete the request
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_NEITHER
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
Irp->UserBuffer = lpOutputBuffer;
|
||||
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = lpInputBuffer;
|
||||
|
||||
No comments here. Don't use METHOD_DIRECT unless you know what you are
|
||||
doing. Simple rule.
|
||||
|
||||
If your IOCtl involves no data transfer buffers, then METHOD_NEITHER is the
|
||||
fastest path through the I/O Manager that involves an Irp.
|
||||
|
||||
|
||||
|
||||
|
||||
Final Comment
|
||||
|
||||
Don't touch Irp->UserBuffer. This is a bookmark for the I/O Manager. Two
|
||||
major problems can occur. 1 - page fault at high IRQL, or 2 - you write
|
||||
something to Irp->UserBuffer and the I/O Manager overwrites you in its
|
||||
completion routine. File systems access Irp->UserBuffer, but FSD writers
|
||||
know all of the above and know when it is safe to touch Irp->UserBuffer.
|
||||
|
||||
|
||||
|
||||
Radu Woinaroski wrote in message <364F8F6E.2434B010@scitec.com.au>...
|
||||
>Hello,
|
||||
>
|
||||
>I have a kernel-mode device driver that accepts a number of IoControl
|
||||
>commands that use buffered data transfer (METHOD_BUFFERED).
|
||||
>
|
||||
>A user mode API provides a higher level access then the DeviceIoControl
|
||||
>function.
|
||||
>
|
||||
>The function is implemented like that
|
||||
>
|
||||
>BOOL
|
||||
Something(
|
||||
> HANDLE hDevice ,
|
||||
> int param1,
|
||||
> int param2,
|
||||
> DWORD * pReturn,
|
||||
> LPOVERLAPPED pOverlapped)
|
||||
>{
|
||||
> // here a data buffer on the stack sent to asynchronous DeviceIoControl
|
||||
>call
|
||||
> int aDataIn[2];
|
||||
> aDataIn[0] = param1;
|
||||
> aDataIn[1] = param2;
|
||||
>
|
||||
> return DeviceIoControl(
|
||||
> hDevice,
|
||||
> DO_SOMETHING_IO,
|
||||
> aDataIn,
|
||||
> sizeof(int)*2,
|
||||
> pReturn,
|
||||
> sizeof(DWORD),
|
||||
> pOverlapped);
|
||||
>}
|
||||
>
|
||||
>The aDataIn buffer will not exist after DeviceIoControl returns (and
|
||||
>when the I/O operation terminates). I know that for buffered IO the
|
||||
>input data buffer is copyed by de IOManager to a nonpaged-pool area
|
||||
>before passing the request to driver dispatch routine (DeviceControl).
|
||||
>At the point of calling the dispatch routine (DeviceControl) the driver
|
||||
>runs in the context of the calling thread so DeviceIoControl hasn't
|
||||
>returned yet (?? or so I think) so aDataI
|
||||
n will still be valid at the
|
||||
>time IOManager copyes it to its buffer. So, this apears to work ok (at
|
||||
>least in my opinion).
|
||||
>
|
||||
>Does I/O Manager use the Input buffer from the call to the Win32
|
||||
>DeviceIoControl any where else after the first copy ?
|
||||
>
|
||||
>Is there any reason why this approach (passing a buffer on the stack to
|
||||
>a asynchronous DeviceIoControl that uses buffered I/O) wouldn't work ?
|
||||
>
|
||||
>Allocating buffers from heap and deleting them on IO completion while
|
||||
>managing asynchronous IO seems too much work ;-) .
|
||||
>
|
||||
>Thanks in advance for your opinions
|
||||
>Radu W.
|
||||
>
|
||||
>--
|
||||
>Radu Woinaroski
|
||||
>Scitec
|
||||
>Sydney, Australia
|
||||
>Radu.Woinaroski@scitec.com.au
|
||||
-----
|
||||
Subject: Re: PCI ISR problem
|
||||
Date: Fri, 20 Nov 1998 18:04:48 GMT
|
||||
From: jeh@cmkrnl.com (Jamie Hanrahan)
|
||||
Organization: Kernel Mode Systems, San Diego, CA
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
On Thu, 19 Nov 1998 15:46:13 -0600, Eric Gardiner
|
||||
<eric.gardiner@natinst.com> wrote:
|
||||
|
||||
>I'm having problems with NT4 not hooking the interrupt line indicated by
|
||||
>a PCI device. Here's what I'm doing:
|
||||
>
|
||||
>1) Enumerating the PCI buses on the system (using HalGetBusData) until
|
||||
>I find my device.
|
||||
>2) Once my device is found, I read the "Interrupt Line Register" in the
|
||||
>device's PCI config space to determine what interrupt level to pass to
|
||||
>HalGetInterruptVector.
|
||||
|
||||
Whups! No. Call HalAssignSlotResources and look at the returned
|
||||
CM_RESOURCE_LIST to find the vector, level, port addresses, etc., for
|
||||
your device. (Then pass the returned CM_RESOURCE_LIST to ExFreePool.)
|
||||
|
||||
|
||||
See Knowledge Base article Q152044.
|
||||
|
||||
--- Jamie Hanrahan, Kernel Mode Systems, San Diego CA (jeh@cmkrnl.com)
|
||||
Drivers, internals, networks, applications, and training for VMS and Windows NT
|
||||
NT kernel driver FAQ, links, and other information: http://www.cmkrnl.com/
|
||||
|
||||
Please post replies, followups, questions, etc., in news, not via e-mail.
|
||||
-----
|
||||
Subject: Re: IRP canceling
|
||||
Date: Mon, 23 Nov 1998 09:05:47 -0500
|
||||
From: Walter Oney <waltoney@oneysoft.com>
|
||||
Organization: Walter Oney Software
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
Seol,Keun Seok wrote:
|
||||
> But, if the IRP was the CurrentIrp of the Device Object,
|
||||
> the Driver's Start I/O routine will try to process the IRP.
|
||||
> In the DDK help, the Start I/O routine MUST check the current IRP's
|
||||
> Cancel bit.
|
||||
> If set, Start I/O routine must just return.
|
||||
>
|
||||
> But I think that the IRP already completed should not be accessed.
|
||||
|
||||
You're absolutely right. I recommend the following code in a standard
|
||||
StartIo routine to avoid the problem you point out:
|
||||
|
||||
VOID StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
KIRQL oldirql;
|
||||
IoAcquireCancelSpinLock(&oldirql);
|
||||
if (Irp != DeviceObject->CurrentIrp || Irp->Cancel)
|
||||
{
|
||||
IoReleaseCancelSpinLock(oldirql);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
IoSetCancelRoutine(Irp, NULL);
|
||||
IoReleaseCancelSpinLock(oldirql);
|
||||
}
|
||||
. . .
|
||||
}
|
||||
|
||||
This dovetails with a standard cancel routine:
|
||||
|
||||
VOID CancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
if (DeviceObject->CurrentIrp == Irp)
|
||||
{
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
IoStartNextPacket(DeviceObject, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,
|
||||
&Irp->Tail.Overlay.DeviceQueueEntry);
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
}
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
You need to remember that the C language specification requires that
|
||||
evaluation of boolean operators short circuit when the result is known.
|
||||
So, if StartIo discovers that the Irp it got as an argument is not the
|
||||
same as CurrentIrp, it will not attempt to evaulate Irp->Cancel.
|
||||
|
||||
Now, as to why this works: StartIo gets called either by IoStartPacket
|
||||
or IoStartNextPacket. Each of them will grab the cancel spin lock and
|
||||
set CurrentIrp, then release the spin lock and call StartIo. If someone
|
||||
should sneak in on another CPU and cancel this very same IRP, your
|
||||
cancel routine will immediately release the spin lock and call
|
||||
IoStartNextPacket. One of two things will then happen. IoStartNextPacket
|
||||
may succeed in getting the cancel spin lock, whereupon it will nullify
|
||||
the CurrentIrp pointer. If another IRP is on the queue, it will remove
|
||||
it from the queue, set CurrentIrp to point to this *new* IRP, release
|
||||
the spin lock, and call StartIo. [You now have two instances of StartIo
|
||||
running on two different CPUs for two different IRPs, but it's not a
|
||||
problem because they won't be able to interfere with each other.]
|
||||
Meanwhile, your original instance of StartIo gets the cancel spin lock
|
||||
and sees that CurrentIrp is not equal to the IRP pointer it got as an
|
||||
argument, so it gives up.
|
||||
|
||||
The second way this could play out is that StartIo gets the cancel lock
|
||||
before IoStartNextPacket does. In this case, CurrentIrp is still
|
||||
pointing to the IRP that's in the process of being cancelled and that
|
||||
StartIo got as an argument. But this IRP hasn't been completed yet (the
|
||||
CPU that's running your cancel routine is spinning inside
|
||||
IoStartNextPacket and therefore hasn't gotten to calling
|
||||
IoCompleteRequest yet), so no-one will have been able to call IoFreeIrp
|
||||
to make your pointer invalid.
|
||||
|
||||
People may tell you that you should be using your own queues for IRPs so
|
||||
you can avoid bottlenecking the system on the global cancel spin lock.
|
||||
That's true enough, but doing it correctly with Plug and Play and Power
|
||||
management things in the way is gigantically complicated. There's a
|
||||
sample in the NT 5 beta-2 DDK called CANCEL that shows how to manage
|
||||
your own queue if you don't worry about PNP and POWER. I hear tell of an
|
||||
upcoming MSJ article by a Microsoft developer that may solve the
|
||||
complete problem.
|
||||
-----
|
||||
Subject: ANNOUNCE: ALINK v1.5
|
||||
Date: 16 Nov 1998 16:36:05 GMT
|
||||
From: anthony_w@my-dejanews.com
|
||||
Organization: Deja News - The Leader in Internet Discussion
|
||||
Newsgroups: comp.os.ms-windows.programmer.win32, comp.lang.asm.x86, comp.os.msdos.programmer
|
||||
|
||||
ALINK is a freeware linker, creating MSDOS COM and EXE files and Win32 PE EXE
|
||||
and DLL files from OMF format OBJ and LIB files, win32-COFF format OBJ files,
|
||||
and win32 RES files.
|
||||
|
||||
NEW for version 1.5:
|
||||
|
||||
Win32 COFF object file support.
|
||||
|
||||
Download it now from my home page.
|
||||
|
||||
Anthony
|
||||
--
|
||||
anthony_w@geocities.com
|
||||
http://www.geocities.com/SiliconValley/Network/4311/index.html
|
||||
|
||||
-----------== Posted via Deja News, The Discussion Network ==----------
|
||||
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
|
||||
-----
|
||||
|
@@ -1,31 +1,59 @@
|
||||
* Kernel things implemented [exceptions in brackets]
|
||||
|
||||
Spinlocks [Uniprocessor only]
|
||||
IRQ levels [Not APC_LEVEL or WAKE_LEVEL, uniprocessor only]
|
||||
ISRs [Partial, uniprocessor only]
|
||||
Timers [Untested]
|
||||
DPCs [Untested]
|
||||
Objects [Partial]
|
||||
Namespace [Partial]
|
||||
Handle tables [One process only]
|
||||
Threads [Some initial work]
|
||||
RTL list functions [All except sequenced lists]
|
||||
Zones [Untested]
|
||||
Memory pool [Working but semantics partially incompatiable]
|
||||
Device objects [Some but no support for layering]
|
||||
IRP [Partial]
|
||||
Memory sections [Partial, no file mappings]
|
||||
PCI interface [Probes but no support]
|
||||
CreateFile API [Device only]
|
||||
ReadFile/WriteFile API [Device only]
|
||||
MDL functions [Untested]
|
||||
* Critical path tasks
|
||||
Test and debug Registry routines
|
||||
Finish multiple system service table support (HalRegisterServiceTable)
|
||||
Modify GENNTDLL to generate all needed system service tables
|
||||
|
||||
* Kernel things unimplemented (partial)
|
||||
* These tasks would be nice
|
||||
Separate HAL into KM DLL
|
||||
|
||||
Add support for source level debugging to Bochs
|
||||
Support for remote debugging
|
||||
Process managment
|
||||
Dispatcher objects (Mutex, Semaphore etc)
|
||||
Investigate user and kernel mode APCs
|
||||
Asynchronous I/O
|
||||
Optimization
|
||||
* Function groups totally or partially unimplemented
|
||||
|
||||
Dma functions (see hal/x86/dma.c)
|
||||
PCI interface functions (see hal/x86/bios32.c, hal/x86/pci.c)
|
||||
HalExamineMbr
|
||||
Locale support (see ex/locale.c)
|
||||
Shutdown support (see ex/power.c)
|
||||
Zw(Set/Get)SystemInformation (see ex/sysinfo.c)
|
||||
Adapter functions (see io/adapter.c)
|
||||
Io cancelation support (see io/cancel, et al)
|
||||
Directory change notification (see io/dir.c)
|
||||
Error logging (see io/errlog.c)
|
||||
Buffer flushing (see io/flush.c)
|
||||
Io completion ports (see io/iocomp.c)
|
||||
File locking (see io/lock.c)
|
||||
Mailslots (see io/mailslot.c)
|
||||
Named pipes (see io/npipe.c)
|
||||
Hardware resource management (see io/resource.c)
|
||||
File access checking (see io/share.c)
|
||||
APCs to user-mode (see ke/apc.c, ke/apchelp.asm)
|
||||
Exception support (see ke/catch.c)
|
||||
Mutex support (see ke/mutex.c)
|
||||
Semaphore support (see ke/sem.c)
|
||||
Timer support (see ke/timer.c)
|
||||
Properly calibrate delay loop (see ke/timer.c)
|
||||
Waiting for multiple objects (see ke/wait.c)
|
||||
Single linked lists (see rtl/slist.c)
|
||||
Sequenced lists (see rtl/seqlist.c)
|
||||
|
||||
* Verify implementation
|
||||
|
||||
Fast mutexes (see ex/fmutex.c)
|
||||
|
||||
* Major areas
|
||||
|
||||
Security support (see se/*.c)
|
||||
Registry support (see cm/*.c)
|
||||
Paging support
|
||||
File system cache support
|
||||
SCSI miniport driver
|
||||
Network support
|
||||
Video drivers
|
||||
USER and GDI modules
|
||||
|
||||
* Drivers
|
||||
NTFS, EXT2 filesystems
|
||||
Many others (use oem's where possible)
|
||||
|
||||
* For the future
|
||||
DOS, Win16, POSIX subsystems
|
||||
|
@@ -1,16 +0,0 @@
|
||||
subject wstring.zip
|
||||
author Boudewijn Dekker
|
||||
date 06-06-98
|
||||
|
||||
|
||||
I wrote some inline wide character string functions. It are modified version
|
||||
of the ones in string.h. I added four more function nl stricmp, strnicmp,
|
||||
wcsicmp, and wcsnicmp. These are the case insensitive variants of
|
||||
strcmp, strncmp and wcscmp, wcsncmp. I tested all the functions but I
|
||||
would urge anyone to tested again. I removed an extern specifier
|
||||
__wcstok and strtok cause I it caused an compilation error when
|
||||
using strtok or wcstok. Please could someone see if this correct.
|
||||
I also used these string functions in lstring api functions.
|
||||
|
||||
|
||||
Boudewijn Dekker
|
4
reactos/drivers/dd/beep/.cvsignore
Normal file
4
reactos/drivers/dd/beep/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
290
reactos/drivers/dd/beep/beep.c
Normal file
290
reactos/drivers/dd/beep/beep.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/* $Id: beep.c,v 1.4 1999/10/16 12:41:42 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/beep/beep.c
|
||||
* PURPOSE: BEEP device driver
|
||||
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
* UPDATE HISTORY:
|
||||
* 30/01/99 Created
|
||||
* 16/10/99 Minor fixes
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddbeep.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* TYEPEDEFS ***************************************************************/
|
||||
|
||||
typedef struct tagBEEP_DEVICE_EXTENSION
|
||||
{
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
KEVENT Event;
|
||||
BOOL BeepOn;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
|
||||
VOID BeepDPC (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeferredContext;
|
||||
|
||||
DPRINT ("BeepDPC() called!\n");
|
||||
HalMakeBeep (0);
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
KeSetEvent (&(DeviceExtension->Event), 0, TRUE);
|
||||
|
||||
DPRINT ("BeepDPC() finished!\n");
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
if (Stack->MajorFunction == IRP_MJ_CREATE)
|
||||
{
|
||||
DPRINT ("BeepCreate() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp,IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
switch (Stack->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CLOSE:
|
||||
DPRINT ("BeepClose() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
if (Stack->MajorFunction == IRP_MJ_CLEANUP)
|
||||
{
|
||||
DPRINT ("BeepCleanup() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
PBEEP_SET_PARAMETERS pbsp;
|
||||
NTSTATUS status;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT ("BeepDeviceControl() called!\n");
|
||||
if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_BEEP_SET)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (Stack->Parameters.DeviceIoControl.InputBufferLength == sizeof(BEEP_SET_PARAMETERS))
|
||||
{
|
||||
pbsp = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if (pbsp->Frequency >= BEEP_FREQUENCY_MINIMUM &&
|
||||
pbsp->Frequency <= BEEP_FREQUENCY_MAXIMUM)
|
||||
{
|
||||
LARGE_INTEGER DueTime;
|
||||
|
||||
DueTime.QuadPart = 0;
|
||||
|
||||
/* do the beep!! */
|
||||
DPRINT ("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
|
||||
pbsp->Frequency, pbsp->Duration);
|
||||
|
||||
if (pbsp->Duration >= 0)
|
||||
{
|
||||
DueTime.QuadPart = (LONGLONG)pbsp->Duration * -10000;
|
||||
|
||||
KeSetTimer (&DeviceExtension->Timer,
|
||||
DueTime,
|
||||
&DeviceExtension->Dpc);
|
||||
|
||||
HalMakeBeep (pbsp->Frequency);
|
||||
DeviceExtension->BeepOn = TRUE;
|
||||
KeWaitForSingleObject (&(DeviceExtension->Event),
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
else if (pbsp->Duration == (DWORD)-1)
|
||||
{
|
||||
if (DeviceExtension->BeepOn)
|
||||
{
|
||||
HalMakeBeep (0);
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
HalMakeBeep (pbsp->Frequency);
|
||||
DeviceExtension->BeepOn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT ("Did the beep!\n");
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepUnload(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
DPRINT ("BeepUnload() called!\n");
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
STDCALL NTSTATUS
|
||||
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initalize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS ret;
|
||||
ANSI_STRING ansi_device_name;
|
||||
UNICODE_STRING device_name;
|
||||
ANSI_STRING asymlink_name;
|
||||
UNICODE_STRING symlink_name;
|
||||
|
||||
DbgPrint ("Beep Device Driver 0.0.2\n");
|
||||
|
||||
RtlInitAnsiString (&ansi_device_name, "\\Device\\Beep");
|
||||
RtlAnsiStringToUnicodeString (&device_name, &ansi_device_name, TRUE);
|
||||
ret = IoCreateDevice (DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&device_name,
|
||||
FILE_DEVICE_BEEP,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (ret!=STATUS_SUCCESS)
|
||||
{
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* prelininary */
|
||||
RtlInitAnsiString (&asymlink_name, "\\??\\Beep");
|
||||
RtlAnsiStringToUnicodeString (&symlink_name, &asymlink_name, TRUE);
|
||||
IoCreateSymbolicLink (&symlink_name, &device_name);
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
|
||||
DriverObject->DriverUnload = BeepUnload;
|
||||
|
||||
/* set up device extension */
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
|
||||
KeInitializeDpc (&(DeviceExtension->Dpc),
|
||||
BeepDPC,
|
||||
DeviceExtension);
|
||||
KeInitializeTimer (&(DeviceExtension->Timer));
|
||||
KeInitializeEvent (&(DeviceExtension->Event),
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
39
reactos/drivers/dd/beep/beep.rc
Normal file
39
reactos/drivers/dd/beep/beep.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "PC Speaker Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.2\0"
|
||||
VALUE "InternalName", "beep\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "beep.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
71
reactos/drivers/dd/beep/makefile
Normal file
71
reactos/drivers/dd/beep/makefile
Normal file
@@ -0,0 +1,71 @@
|
||||
# $Id: makefile,v 1.6 1999/12/04 20:58:35 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET = beep
|
||||
OBJECTS = beep.o beep.coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
all: beep.sys
|
||||
|
||||
.PHONY: all
|
||||
|
||||
clean:
|
||||
- $(RM) beep.o
|
||||
- $(RM) beep.coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) beep.sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
|
||||
beep.sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp \
|
||||
$(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname beep.sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
include ../../../rules.mak
|
||||
|
4
reactos/drivers/dd/blue/.cvsignore
Normal file
4
reactos/drivers/dd/blue/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
634
reactos/drivers/dd/blue/blue.c
Normal file
634
reactos/drivers/dd/blue/blue.c
Normal file
@@ -0,0 +1,634 @@
|
||||
/* $Id: blue.c,v 1.19 2000/01/11 17:33:44 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/blue/blue.c
|
||||
* PURPOSE: Console (blue screen) device driver
|
||||
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
* UPDATE HISTORY:
|
||||
* ??? Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddblue.h>
|
||||
#include <string.h>
|
||||
#include <defines.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* DEFINITIONS ***************************************************************/
|
||||
|
||||
#define IDMAP_BASE 0xd0000000
|
||||
#define VIDMEM_BASE 0xb8000
|
||||
|
||||
#define CRTC_COMMAND ((PUCHAR)0x3d4)
|
||||
#define CRTC_DATA ((PUCHAR)0x3d5)
|
||||
|
||||
#define CRTC_COLUMNS 0x01
|
||||
#define CRTC_OVERFLOW 0x07
|
||||
#define CRTC_ROWS 0x12
|
||||
#define CRTC_SCANLINES 0x09
|
||||
#define CRTC_CURSORSTART 0x0a
|
||||
#define CRTC_CURSOREND 0x0b
|
||||
#define CRTC_CURSORPOSHI 0x0e
|
||||
#define CRTC_CURSORPOSLO 0x0f
|
||||
|
||||
#define ATTRC_WRITEREG ((PUCHAR)0x3c0)
|
||||
#define ATTRC_READREG ((PUCHAR)0x3c1)
|
||||
#define ATTRC_INPST1 ((PUCHAR)0x3da)
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
|
||||
/* NOTES ******************************************************************/
|
||||
/*
|
||||
* [[character][attribute]][[character][attribute]]....
|
||||
*/
|
||||
|
||||
|
||||
/* TYPEDEFS ***************************************************************/
|
||||
|
||||
typedef struct _DEVICE_EXTENSION
|
||||
{
|
||||
PBYTE VideoMemory; /* Pointer to video memory */
|
||||
DWORD CursorSize;
|
||||
BOOL CursorVisible;
|
||||
WORD CharAttribute;
|
||||
DWORD Mode;
|
||||
BYTE ScanLines; /* Height of a text line */
|
||||
WORD Rows; /* Number of rows */
|
||||
WORD Columns; /* Number of columns */
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
ScrCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
unsigned int offset;
|
||||
BYTE data, value;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
/* initialize device extension */
|
||||
|
||||
/* get pointer to video memory */
|
||||
/* FIXME : use MmMapIoSpace() */
|
||||
DeviceExtension->VideoMemory = (PBYTE)(IDMAP_BASE + VIDMEM_BASE);
|
||||
|
||||
/* disable interrupts */
|
||||
__asm__("cli\n\t");
|
||||
|
||||
/* get current output position */
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
|
||||
|
||||
/* switch blinking characters off */
|
||||
READ_PORT_UCHAR (ATTRC_INPST1);
|
||||
value = READ_PORT_UCHAR (ATTRC_WRITEREG);
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, 0x10);
|
||||
data = READ_PORT_UCHAR (ATTRC_READREG);
|
||||
data = data & ~0x08;
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, data);
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, value);
|
||||
READ_PORT_UCHAR (ATTRC_INPST1);
|
||||
|
||||
/* read screen information from crt controller */
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_COLUMNS);
|
||||
DeviceExtension->Columns = READ_PORT_UCHAR (CRTC_DATA) + 1;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_ROWS);
|
||||
DeviceExtension->Rows = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_OVERFLOW);
|
||||
data = READ_PORT_UCHAR (CRTC_DATA);
|
||||
DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3));
|
||||
DeviceExtension->Rows++;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES);
|
||||
DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1;
|
||||
|
||||
/* enable interrupts */
|
||||
__asm__("sti\n\t");
|
||||
|
||||
/* calculate number of text rows */
|
||||
DeviceExtension->Rows =
|
||||
DeviceExtension->Rows / DeviceExtension->ScanLines;
|
||||
|
||||
DPRINT ("%d Columns %d Rows %d Scanlines\n",
|
||||
DeviceExtension->Columns,
|
||||
DeviceExtension->Rows,
|
||||
DeviceExtension->ScanLines);
|
||||
|
||||
DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
|
||||
DeviceExtension->CursorVisible = TRUE;
|
||||
|
||||
/* more initialization */
|
||||
DeviceExtension->CharAttribute = 0x17; /* light grey on blue */
|
||||
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
|
||||
ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
|
||||
/* show blinking cursor */
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
|
||||
data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA,
|
||||
data | ((DeviceExtension->ScanLines - 1) & 0x1F));
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
char *pch = Irp->UserBuffer;
|
||||
char *vidmem;
|
||||
int i, j, offset;
|
||||
int cursorx, cursory;
|
||||
int rows, columns;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
rows = DeviceExtension->Rows;
|
||||
columns = DeviceExtension->Columns;
|
||||
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA)<<8;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset += READ_PORT_UCHAR (CRTC_DATA);
|
||||
|
||||
cursory = offset / columns;
|
||||
cursorx = offset % columns;
|
||||
|
||||
for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
|
||||
{
|
||||
switch (*pch)
|
||||
{
|
||||
case '\b':
|
||||
if (cursorx > 0)
|
||||
{
|
||||
cursorx--;
|
||||
}
|
||||
else if (cursory > 0)
|
||||
{
|
||||
cursorx = columns - 1;
|
||||
cursory--;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
|
||||
for (j = 0; j < offset; j++)
|
||||
{
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
|
||||
cursorx++;
|
||||
|
||||
if (cursorx >= columns)
|
||||
{
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
|
||||
cursorx++;
|
||||
if (cursorx >= columns)
|
||||
{
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (cursory >= rows)
|
||||
{
|
||||
unsigned short *LinePtr;
|
||||
|
||||
memcpy (vidmem,
|
||||
&vidmem[columns * 2],
|
||||
columns * (rows - 1) * 2);
|
||||
|
||||
LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
LinePtr[j] = DeviceExtension->CharAttribute << 8;
|
||||
}
|
||||
cursory = rows - 1;
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
|
||||
vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the cursor position */
|
||||
offset = (cursory * columns) + cursorx;
|
||||
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset >>= 8;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
switch (stk->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
int rows = DeviceExtension->Rows;
|
||||
int columns = DeviceExtension->Columns;
|
||||
unsigned int offset;
|
||||
|
||||
/* read cursor position from crtc */
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
|
||||
__asm__("sti\n\t");
|
||||
|
||||
pcsbi->dwSize.X = rows;
|
||||
pcsbi->dwSize.Y = columns;
|
||||
|
||||
pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
|
||||
pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
|
||||
|
||||
pcsbi->wAttributes = DeviceExtension->CharAttribute;
|
||||
|
||||
pcsbi->srWindow.Left = 0;
|
||||
pcsbi->srWindow.Right = columns - 1;
|
||||
pcsbi->srWindow.Top = 0;
|
||||
pcsbi->srWindow.Bottom = rows - 1;
|
||||
|
||||
pcsbi->dwMaximumWindowSize.X = columns;
|
||||
pcsbi->dwMaximumWindowSize.Y = rows;
|
||||
|
||||
Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
unsigned int offset;
|
||||
|
||||
DeviceExtension->CharAttribute = pcsbi->wAttributes;
|
||||
|
||||
offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
|
||||
pcsbi->dwCursorPosition.X;
|
||||
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_GET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
pcci->dwSize = DeviceExtension->CursorSize;
|
||||
pcci->bVisible = DeviceExtension->CursorVisible;
|
||||
|
||||
Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
BYTE data, value;
|
||||
DWORD size, height;
|
||||
|
||||
DeviceExtension->CursorSize = pcci->dwSize;
|
||||
DeviceExtension->CursorVisible = pcci->bVisible;
|
||||
height = DeviceExtension->ScanLines;
|
||||
data = (pcci->bVisible) ? 0x40 : 0x20;
|
||||
|
||||
size = (pcci->dwSize * height) / 100;
|
||||
if (size < 1)
|
||||
size = 1;
|
||||
|
||||
data |= (BYTE)(height - size);
|
||||
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, data);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
|
||||
value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
|
||||
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_GET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
pcm->dwMode = DeviceExtension->Mode;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DeviceExtension->Mode = pcm->dwMode;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = Buf->nLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPWORD pAttr = (LPWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pAttr++)
|
||||
{
|
||||
(char) *pAttr = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPWORD pAttr = (LPWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pAttr++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) *pAttr;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
|
||||
DeviceExtension->CharAttribute = (WORD)*(LPWORD)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2);
|
||||
|
||||
CHECKPOINT
|
||||
|
||||
for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = Buf->nLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2);
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pChar++)
|
||||
{
|
||||
*pChar = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pChar++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) *pChar;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS Status;
|
||||
|
||||
switch (stk->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module entry point
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
ANSI_STRING adevice_name;
|
||||
UNICODE_STRING device_name;
|
||||
ANSI_STRING asymlink_name;
|
||||
UNICODE_STRING symlink_name;
|
||||
|
||||
DbgPrint ("Screen Driver 0.0.6\n");
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
|
||||
|
||||
RtlInitAnsiString (&adevice_name, "\\Device\\BlueScreen");
|
||||
RtlAnsiStringToUnicodeString (&device_name, &adevice_name, TRUE);
|
||||
IoCreateDevice (DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&device_name,
|
||||
FILE_DEVICE_SCREEN,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
|
||||
RtlInitAnsiString (&asymlink_name, "\\??\\BlueScreen");
|
||||
RtlAnsiStringToUnicodeString (&symlink_name, &asymlink_name, TRUE);
|
||||
IoCreateSymbolicLink (&symlink_name, &device_name);
|
||||
|
||||
RtlFreeUnicodeString (&device_name);
|
||||
RtlFreeUnicodeString (&symlink_name);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
39
reactos/drivers/dd/blue/blue.rc
Normal file
39
reactos/drivers/dd/blue/blue.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "HAL Console Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.6\0"
|
||||
VALUE "InternalName", "blue\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "blue.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
70
reactos/drivers/dd/blue/makefile
Normal file
70
reactos/drivers/dd/blue/makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
# $Id: makefile,v 1.10 1999/12/18 10:17:41 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET = blue
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET).o
|
||||
- $(RM) $(TARGET).coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) blue.sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
$(TARGET).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp $(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGET).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
|
||||
include ../../../rules.mak
|
2
reactos/drivers/dd/event/dirs
Normal file
2
reactos/drivers/dd/event/dirs
Normal file
@@ -0,0 +1,2 @@
|
||||
DIRS=exe \
|
||||
sys
|
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
EventTest.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Simple console test app demonstrating how a Win32 app can share
|
||||
an event object with a kernel-mode driver. For more information
|
||||
on using Event Objects at the application level see the Win32 SDK.
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
User Mode
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// INCLUDES
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <winioctl.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "event.h"
|
||||
|
||||
|
||||
//
|
||||
// MAIN
|
||||
//
|
||||
void __cdecl
|
||||
main(
|
||||
int argc,
|
||||
char ** argv
|
||||
)
|
||||
{
|
||||
BOOL bStatus;
|
||||
HANDLE hDevice;
|
||||
ULONG ulReturnedLength;
|
||||
|
||||
SET_EVENT setEvent;
|
||||
FLOAT fDelay;
|
||||
|
||||
|
||||
if ( (argc < 2) || (argv[1] == NULL) ) {
|
||||
printf("event <delay>\n");
|
||||
printf("\twhere <delay> = time to delay the event signal in seconds.\n");
|
||||
exit(0);
|
||||
}
|
||||
sscanf( argv[1], "%f", &fDelay );
|
||||
|
||||
//
|
||||
// open the device
|
||||
//
|
||||
hDevice = CreateFile(
|
||||
"\\\\.\\EVENT", // lpFileName
|
||||
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
|
||||
NULL, // lpSecurityAttributes
|
||||
OPEN_EXISTING, // dwCreationDistribution
|
||||
0, // dwFlagsAndAttributes
|
||||
NULL // hTemplateFile
|
||||
);
|
||||
|
||||
if (hDevice == INVALID_HANDLE_VALUE) {
|
||||
printf("CreateFile error = %d\n", GetLastError() );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// set the event signal delay
|
||||
//
|
||||
setEvent.DueTime.QuadPart = -((LONGLONG)(fDelay * 10.0E6));// use relative time for this sample
|
||||
|
||||
|
||||
//
|
||||
// test the driver for bad event handles
|
||||
//
|
||||
setEvent.hEvent = NULL;
|
||||
bStatus = DeviceIoControl(
|
||||
hDevice, // Handle to device
|
||||
IOCTL_SET_EVENT, // IO Control code
|
||||
&setEvent, // Input Buffer to driver.
|
||||
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||
NULL, // Output Buffer from driver.
|
||||
0, // Length of output buffer in bytes.
|
||||
&ulReturnedLength, // Bytes placed in buffer.
|
||||
NULL // synchronous call
|
||||
);
|
||||
if ( !bStatus ) {
|
||||
printf("Bad handle TEST returned code %d.\n\n", GetLastError() );
|
||||
} else {
|
||||
printf("we should never get here\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
setEvent.hEvent = CreateEvent(
|
||||
NULL, // lpEventAttributes
|
||||
TRUE, // bManualReset
|
||||
FALSE, // bInitialState
|
||||
NULL // lpName
|
||||
);
|
||||
|
||||
|
||||
if ( !setEvent.hEvent ) {
|
||||
printf("CreateEvent error = %d\n", GetLastError() );
|
||||
} else {
|
||||
|
||||
printf("Event HANDLE = 0x%x\n", setEvent.hEvent );
|
||||
printf("Press any key to exit.\n");
|
||||
while( !_kbhit() ) {
|
||||
bStatus = DeviceIoControl(
|
||||
hDevice, // Handle to device
|
||||
IOCTL_SET_EVENT, // IO Control code
|
||||
&setEvent, // Input Buffer to driver.
|
||||
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||
NULL, // Output Buffer from driver.
|
||||
0, // Length of output buffer in bytes.
|
||||
&ulReturnedLength, // Bytes placed in buffer.
|
||||
NULL // synchronous call
|
||||
);
|
||||
|
||||
if ( !bStatus ) {
|
||||
printf("Ioctl failed with code %d\n", GetLastError() );
|
||||
break;
|
||||
} else {
|
||||
printf("Waiting for Event...\n");
|
||||
|
||||
WaitForSingleObject(setEvent.hEvent,
|
||||
INFINITE );
|
||||
|
||||
printf("Event signalled.\n\n");
|
||||
|
||||
ResetEvent( setEvent.hEvent);
|
||||
//printf("Event reset.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// close the driver
|
||||
//
|
||||
if ( !CloseHandle(hDevice) ) {
|
||||
printf("Failed to close device.\n");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
7
reactos/drivers/dd/event/exe/makefile
Normal file
7
reactos/drivers/dd/event/exe/makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the driver components of the Windows NT DDK
|
||||
#
|
||||
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
10
reactos/drivers/dd/event/exe/sources
Normal file
10
reactos/drivers/dd/event/exe/sources
Normal file
@@ -0,0 +1,10 @@
|
||||
TARGETNAME=event
|
||||
TARGETPATH=$(BASEDIR)\lib
|
||||
TARGETTYPE=PROGRAM
|
||||
|
||||
INCLUDES=..\sys
|
||||
|
||||
SOURCES=eventtest.c
|
||||
|
||||
UMTYPE=console
|
||||
UMBASE=0x100000
|
50
reactos/drivers/dd/event/readme.txt
Normal file
50
reactos/drivers/dd/event/readme.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
This sample demonstrates one way that a Windows NT kernel-mode device driver
|
||||
can share and explicitly signal an Event Object with a Win32 application.
|
||||
It is composed of two parts, a Windows NT kernel-mode device driver and a Win32
|
||||
console test application. Both are built using the Windows NT DDK.
|
||||
|
||||
|
||||
Instructions:
|
||||
-------------
|
||||
|
||||
1) Build the driver and test application in either the FREE or CHECKED build environment:
|
||||
|
||||
BLD
|
||||
|
||||
Both the driver and application are put in %NTDDK%\LIB\*\FREE | CHECKED on your build machine.
|
||||
|
||||
|
||||
2) Copy the newly built driver to your Target machine's %SystemRoot%\system32\drivers
|
||||
directory. Copy the newly built application to your target machine.
|
||||
Also copy the EVENT.INI file to your Target machine.
|
||||
|
||||
|
||||
3) Update the Target machine's Registry by running REGINI.EXE on the EVENT.INI file, i.e.:
|
||||
|
||||
REGINI EVENT.INI
|
||||
|
||||
This adds a driver key under the
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services tree in the Registry.
|
||||
You can verify this by running REGEDIT32.EXE and looking at the \Event key.
|
||||
|
||||
|
||||
4) Reboot the Target machine for the Registry changes to take effect.
|
||||
Your driver will not load until you reboot.
|
||||
|
||||
|
||||
5) Load the driver from the command line:
|
||||
|
||||
NET START EVENT
|
||||
|
||||
|
||||
6) Run the test app from the command line:
|
||||
|
||||
EVENT <DELAY>
|
||||
|
||||
where DELAY = time to delay the Event signal in seconds.
|
||||
|
||||
|
||||
7) Unload the driver from the command line:
|
||||
|
||||
NET STOP EVENT
|
447
reactos/drivers/dd/event/sys/event.c
Normal file
447
reactos/drivers/dd/event/sys/event.c
Normal file
@@ -0,0 +1,447 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Event.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This sample demonstrates one way that a Windows NT kernel-mode driver
|
||||
can share and explicitly signal an Event Object with a Win32 application.
|
||||
|
||||
This sample uses the following method:
|
||||
The application creates an event object using CreateEvent().
|
||||
The app passes the event handle to the driver in a private IOCTL.
|
||||
The driver is running in the app's thread context during the IOCTL so
|
||||
there is a valid user-mode handle at that time.
|
||||
The driver dereferences the user-mode handle into system space & saves
|
||||
the new system handle for later use.
|
||||
The driver signals the event via KeSetEvent() at IRQL <= DISPATCH_LEVEL.
|
||||
The driver MUST delete any driver references to the event object at
|
||||
Unload time.
|
||||
|
||||
An alternative method would be to create a named event in the driver via
|
||||
IoCreateNotificationEvent and then open the event in user mode. This API
|
||||
however is new to Windows NT 4.0 so you can not use this method in your
|
||||
NT 3.5x drivers.
|
||||
|
||||
Note that this sample's event can be signalled (almost) at will from within
|
||||
the driver. A different event signal can be set when the driver is setup to
|
||||
do asynchronous I/O, and it is opened with FILE_FLAG_OVERLAPPED, and an
|
||||
event handle is passed down in an OVERLAPPED struct from the app's Read,
|
||||
Write, or DeviceIoControl. This different event signal is set by the I/O
|
||||
Manager when the driver calls IoCompleteRequest on a pending Irp. This type
|
||||
of Irp completion signal is not the purpose of this sample, hence the lack of
|
||||
Irp queing.
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
Kernel Mode Only
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// INCLUDES
|
||||
//
|
||||
#include "ntddk.h"
|
||||
#include "event.h"
|
||||
|
||||
//
|
||||
// DEFINES
|
||||
//
|
||||
#define USER_NAME L"\\DosDevices\\EVENT"
|
||||
#define SYSTEM_NAME L"\\Device\\EVENT"
|
||||
|
||||
//
|
||||
// DATA
|
||||
//
|
||||
typedef struct _DEVICE_EXTENSION {
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
HANDLE hEvent;
|
||||
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
//
|
||||
// PROTOS
|
||||
//
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Unload(
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Dispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
VOID
|
||||
CustomTimerDPC(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine gets called by the system to initialize the driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverObject - the system supplied driver object.
|
||||
RegistryPath - the system supplied registry path for this driver.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject;
|
||||
PDEVICE_EXTENSION pDeviceExtension;
|
||||
|
||||
UNICODE_STRING usSystemName;
|
||||
UNICODE_STRING usUserName;
|
||||
|
||||
NTSTATUS status;
|
||||
|
||||
|
||||
KdPrint(("Event!DriverEntry - IN\n"));
|
||||
|
||||
//
|
||||
// create the device object
|
||||
//
|
||||
RtlInitUnicodeString( &usSystemName, SYSTEM_NAME );
|
||||
|
||||
status = IoCreateDevice(
|
||||
DriverObject, // DriverObject
|
||||
sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
|
||||
&usSystemName, // DeviceName
|
||||
FILE_DEVICE_UNKNOWN, // DeviceType
|
||||
0, // DeviceCharacteristics
|
||||
TRUE, // Exclusive
|
||||
&pDeviceObject // DeviceObject
|
||||
);
|
||||
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
KdPrint(("\tIoCreateDevice returned 0x%x\n", status));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
//
|
||||
// Set up dispatch entry points for the driver.
|
||||
//
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] =
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
|
||||
DriverObject->DriverUnload = Unload;
|
||||
|
||||
//
|
||||
// Create a symbolic link into user mode for the driver.
|
||||
//
|
||||
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||
status = IoCreateSymbolicLink( &usUserName, &usSystemName );
|
||||
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
IoDeleteDevice( pDeviceObject );
|
||||
KdPrint(("\tIoCreateSymbolicLink returned 0x%x\n", status));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
//
|
||||
// establish user-buffer access method
|
||||
//
|
||||
pDeviceObject->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
|
||||
//
|
||||
// setup the device extension
|
||||
//
|
||||
pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
|
||||
KeInitializeDpc(
|
||||
&pDeviceExtension->Dpc, // Dpc
|
||||
CustomTimerDPC, // DeferredRoutine
|
||||
pDeviceObject // DeferredContext
|
||||
);
|
||||
|
||||
KeInitializeTimer(
|
||||
&pDeviceExtension->Timer // Timer
|
||||
);
|
||||
|
||||
pDeviceExtension->hEvent = NULL;
|
||||
|
||||
KdPrint(("Event!DriverEntry - OUT\n"));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Unload(
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine gets called to remove the driver from the system.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverObject - the system supplied driver object.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject = DriverObject->DeviceObject;
|
||||
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
UNICODE_STRING usUserName;
|
||||
|
||||
|
||||
KdPrint(("Event!Unload\n"));
|
||||
|
||||
//
|
||||
// dereference the event object or it will NEVER go away until reboot
|
||||
//
|
||||
if ( pDeviceExtension->hEvent )
|
||||
ObDereferenceObject( pDeviceExtension->hEvent );
|
||||
|
||||
// Delete the user-mode symbolic link.
|
||||
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||
IoDeleteSymbolicLink( &usUserName );
|
||||
|
||||
// Delete the DeviceObject
|
||||
IoDeleteDevice( pDeviceObject );
|
||||
|
||||
return( STATUS_SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Dispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This device control dispatcher handles IOCTLs.
|
||||
|
||||
Arguments:
|
||||
|
||||
DeviceObject - Context for the activity.
|
||||
Irp - The device control argument block.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_EXTENSION pDeviceExtension;
|
||||
PIO_STACK_LOCATION pIrpStack;
|
||||
PSET_EVENT pSetEvent;
|
||||
|
||||
ULONG ulInformation = 0L;
|
||||
NTSTATUS status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
|
||||
KdPrint(("Event!Dispatch - IN\n"));
|
||||
|
||||
pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
|
||||
|
||||
switch( pIrpStack->MajorFunction )
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
case IRP_MJ_CLOSE:
|
||||
KdPrint(("\t%s\n", (IRP_MJ_CREATE == pIrpStack->MajorFunction) ? "IRP_MJ_CREATE" : "IRP_MJ_CLOSE"));
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
switch( pIrpStack->Parameters.DeviceIoControl.IoControlCode )
|
||||
{
|
||||
case IOCTL_SET_EVENT:
|
||||
KdPrint(("\tIOCTL_SET_EVENT\n"));
|
||||
|
||||
if ( pIrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_SETEVENT ) {
|
||||
// Parameters are invalid
|
||||
KdPrint(("\tSTATUS_INVALID_PARAMETER\n"));
|
||||
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
} else {
|
||||
pSetEvent = (PSET_EVENT)Irp->AssociatedIrp.SystemBuffer;
|
||||
KdPrint(("\tuser-mode HANDLE = 0x%x\n", pSetEvent->hEvent ));
|
||||
|
||||
status = ObReferenceObjectByHandle( pSetEvent->hEvent,
|
||||
SYNCHRONIZE,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&pDeviceExtension->hEvent,
|
||||
NULL
|
||||
);
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
|
||||
KdPrint(("\tUnable to reference User-Mode Event object, Error = 0x%x\n", status));
|
||||
|
||||
} else {
|
||||
|
||||
KdPrint(("\tkernel-mode HANDLE = 0x%x\n", pDeviceExtension->hEvent ));
|
||||
|
||||
//
|
||||
// Start the timer to run the CustomTimerDPC in DueTime seconds to
|
||||
// simulate an interrupt (which would queue a DPC).
|
||||
// The user's event object is signaled in the DPC.
|
||||
//
|
||||
|
||||
// ensure relative time for this sample
|
||||
if ( pSetEvent->DueTime.QuadPart > 0 )
|
||||
pSetEvent->DueTime.QuadPart = -(pSetEvent->DueTime.QuadPart);
|
||||
KdPrint(("\tDueTime = %d\n", pSetEvent->DueTime.QuadPart ));
|
||||
|
||||
KeSetTimer(
|
||||
&pDeviceExtension->Timer, // Timer
|
||||
pSetEvent->DueTime, // DueTime
|
||||
&pDeviceExtension->Dpc // Dpc
|
||||
);
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// should never hit this
|
||||
ASSERT(0);
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
} // switch IoControlCode
|
||||
break;
|
||||
|
||||
default:
|
||||
// should never hit this
|
||||
ASSERT(0);
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
} // switch MajorFunction
|
||||
|
||||
|
||||
//
|
||||
// complete the Irp
|
||||
//
|
||||
Irp->IoStatus.Status = status;
|
||||
Irp->IoStatus.Information = ulInformation;
|
||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
||||
|
||||
KdPrint(("Event!Dispatch - OUT\n"));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
CustomTimerDPC(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This is the DPC associated with this drivers Timer object setup in DriverEntry.
|
||||
|
||||
Arguments:
|
||||
|
||||
Dpc - our DPC object associated with our Timer
|
||||
DeferredContext - Context for the DPC that we setup in DriverEntry
|
||||
SystemArgument1 -
|
||||
SystemArgument2 -
|
||||
|
||||
Return Value:
|
||||
|
||||
Nothing.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject = DeferredContext;
|
||||
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
KdPrint(("Event!CustomTimerDPC - IN\n"));
|
||||
|
||||
//
|
||||
// Signal the Event created user-mode
|
||||
//
|
||||
// Note:
|
||||
// Do not call KeSetEvent from your ISR;
|
||||
// you must call it at IRQL <= DISPATCH_LEVEL.
|
||||
// Your ISR should queue a DPC and the DPC can
|
||||
// then call KeSetEvent on the ISR's behalf.
|
||||
//
|
||||
KeSetEvent((PKEVENT)pDeviceExtension->hEvent,// Event
|
||||
0, // Increment
|
||||
FALSE // Wait
|
||||
);
|
||||
|
||||
// there is no Irp to complete here
|
||||
|
||||
KdPrint(("Event!CustomTimerDPC - OUT\n"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
43
reactos/drivers/dd/event/sys/event.h
Normal file
43
reactos/drivers/dd/event/sys/event.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Event.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __EVENT__
|
||||
#define __EVENT__
|
||||
|
||||
|
||||
#include "devioctl.h"
|
||||
|
||||
typedef struct _SET_EVENT
|
||||
{
|
||||
HANDLE hEvent;
|
||||
LARGE_INTEGER DueTime; // requested DueTime in 100-nanosecond units
|
||||
|
||||
} SET_EVENT, *PSET_EVENT;
|
||||
|
||||
#define SIZEOF_SETEVENT sizeof(SET_EVENT)
|
||||
|
||||
|
||||
#define IOCTL_SET_EVENT \
|
||||
CTL_CODE( FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
||||
|
||||
|
||||
#endif // __EVENT__
|
7
reactos/drivers/dd/event/sys/event.ini
Normal file
7
reactos/drivers/dd/event/sys/event.ini
Normal file
@@ -0,0 +1,7 @@
|
||||
; note - the service name matches the driver's file (.sys) name
|
||||
|
||||
\Registry\Machine\System\CurrentControlSet\Services\Event
|
||||
Type = REG_DWORD 0x00000001
|
||||
Start = REG_DWORD 0x00000003
|
||||
Group = Extended Base
|
||||
ErrorControl = REG_DWORD 0x00000001
|
11
reactos/drivers/dd/event/sys/event.rc
Normal file
11
reactos/drivers/dd/event/sys/event.rc
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||
#define VER_FILEDESCRIPTION_STR "Sample Event Driver"
|
||||
#define VER_INTERNALNAME_STR "event.sys"
|
||||
|
||||
#include "common.ver"
|
||||
|
7
reactos/drivers/dd/event/sys/makefile
Normal file
7
reactos/drivers/dd/event/sys/makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the driver components of the Windows NT DDK
|
||||
#
|
||||
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
6
reactos/drivers/dd/event/sys/sources
Normal file
6
reactos/drivers/dd/event/sys/sources
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGETNAME=event
|
||||
TARGETPATH=$(BASEDIR)\lib
|
||||
TARGETTYPE=DRIVER
|
||||
|
||||
SOURCES=event.c \
|
||||
event.rc
|
444
reactos/drivers/dd/floppy/floppy.c
Normal file
444
reactos/drivers/dd/floppy/floppy.c
Normal file
@@ -0,0 +1,444 @@
|
||||
//
|
||||
// FLOPPY.C - NEC-765/8272A floppy device driver
|
||||
// written by Rex Jolliff
|
||||
// with help from various other sources, including but not limited to:
|
||||
// Art Baker's NT Device Driver Book, Linux Source, and the internet.
|
||||
//
|
||||
// Modification History:
|
||||
// 08/19/98 RJJ Created.
|
||||
//
|
||||
// To do:
|
||||
// FIXME: get it working
|
||||
// FIXME: add support for DMA hardware
|
||||
// FIXME: should add support for floppy tape/zip devices
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#include "floppy.h"
|
||||
|
||||
#define VERSION "V0.0.1"
|
||||
|
||||
// --------------------------------------------------- File Statics
|
||||
|
||||
typedef struct _FLOPPY_CONTROLLER_PARAMETERS
|
||||
{
|
||||
int PortBase;
|
||||
int Vector;
|
||||
int IrqL;
|
||||
int SynchronizeIrqL;
|
||||
KINTERRUPT_MODE InterruptMode;
|
||||
KAFFINITY Affinity;
|
||||
} FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
|
||||
|
||||
#define FLOPPY_MAX_CONTROLLERS 2
|
||||
FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] =
|
||||
{
|
||||
{0x03f0, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
{0x0370, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
};
|
||||
|
||||
FLOPPY_DEVICE_PARAMETERS DeviceTypes[] =
|
||||
{
|
||||
/* Unknown */
|
||||
{0, 500, 16, 16, 8000, 1000, 3000, 0, 20, 5, 80, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4, 8, 2, 1, 5, 3,10}, 1500, 0, "unknown"},
|
||||
/* 5 1/4 360 KB PC*/
|
||||
{1, 300, 16, 16, 8000, 1000, 3000, 0, 20, 5, 40, 3000, 17, {3,1,2,0,2}, 0, 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 1500, 1, "360K PC"},
|
||||
/* 5 1/4 HD AT*/
|
||||
{2, 500, 16, 16, 6000, 400, 3000, 14, 20, 6, 83, 3000, 17, {3,1,2,0,2}, 0, 0, { 2, 5, 6,23,10,20,11, 0}, 1500, 2, "1.2M"},
|
||||
/* 3 1/2 DD*/
|
||||
{3, 250, 16, 16, 3000, 1000, 3000, 0, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 1500, 4, "720k"},
|
||||
/* 3 1/2 HD*/
|
||||
{4, 500, 16, 16, 4000, 400, 3000, 10, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4,25,22,31,21,29,11}, 1500, 7, "1.44M"},
|
||||
/* 3 1/2 ED*/
|
||||
{5, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M AMI BIOS"},
|
||||
/* 3 1/2 ED*/
|
||||
{6, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M"}
|
||||
};
|
||||
|
||||
static BOOLEAN FloppyInitialized = FALSE;
|
||||
|
||||
// ------------------------------------------------------ Functions
|
||||
|
||||
// ModuleEntry
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This function initializes the driver, locates and claims
|
||||
// hardware resources, and creates various NT objects needed
|
||||
// to process I/O requests.
|
||||
//
|
||||
// RUN LEVEL:
|
||||
// PASSIVE_LEVEL
|
||||
//
|
||||
// ARGUMENTS:
|
||||
// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
|
||||
// for this driver
|
||||
// IN PUNICODE_STRING RegistryPath Name of registry driver service
|
||||
// key
|
||||
//
|
||||
// RETURNS:
|
||||
// NTSTATUS
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
NTSTATUS RC;
|
||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
// Export other driver entry points...
|
||||
DriverObject->DriverStartIo = FloppyStartIo;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
|
||||
|
||||
// Try to detect controller and abort if it fails
|
||||
if (!FloppyCreateController(DriverObject,
|
||||
&ControllerParameters[0],
|
||||
0))
|
||||
{
|
||||
DPRINT("Could not find floppy controller");
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FloppyCreateController(PDRIVER_OBJECT DriverObject,
|
||||
PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
int Index)
|
||||
{
|
||||
PFLOPPY_CONTROLLER_TYPE ControllerType;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
|
||||
|
||||
/* Detect controller and determine type */
|
||||
if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: Register port ranges and interrupts with HAL
|
||||
|
||||
/* Create controller object for FDC */
|
||||
ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
|
||||
if (ControllerObject == NULL)
|
||||
{
|
||||
DPRINT("Could not create controller object for controller %d\n",
|
||||
Index);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: fill out controller data
|
||||
ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
|
||||
ControllerObject->ControllerExtension;
|
||||
ControllerExtension->Number = Index;
|
||||
ControllerExtension->PortBase = ControllerParameters->PortBase;
|
||||
ControllerExtension->Vector = ControllerParameters->Vector;
|
||||
ControllerExtension->FDCType = ControllerType;
|
||||
|
||||
/* Initialize the spin lock in the controller extension */
|
||||
KeInitializeSpinLock(&ControllerExtension->SpinLock);
|
||||
|
||||
/* Register an interrupt handler for this controller */
|
||||
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
||||
FloppyIsr,
|
||||
ControllerExtension,
|
||||
&ControllerExtension->SpinLock,
|
||||
ControllerExtension->Vector,
|
||||
ControllerParameters->IrqL,
|
||||
ControllerParameters->SynchronizeIrqL,
|
||||
ControllerParameters->InterruptMode,
|
||||
FALSE,
|
||||
ControllerParameters->Affinity,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(RC))
|
||||
{
|
||||
DPRINT("Could not Connect Interrupt %d\n", ControllerExtension->Vector);
|
||||
IoDeleteController(ControllerObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: setup DMA stuff for controller
|
||||
|
||||
// Check for each possible drive and create devices for them
|
||||
for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
|
||||
{
|
||||
// FIXME: try to identify the drive
|
||||
// FIXME: create a device if it's there
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// FloppyGetControllerVersion
|
||||
//
|
||||
// DESCRIPTION
|
||||
// Get the type/version of the floppy controller
|
||||
//
|
||||
// RUN LEVEL:
|
||||
// PASSIVE_LEVEL
|
||||
//
|
||||
// ARGUMENTS:
|
||||
// IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
|
||||
//
|
||||
// RETURNS:
|
||||
// BOOL success or failure
|
||||
//
|
||||
// COMMENTS:
|
||||
// This routine (get_fdc_version) was originally written by David C. Niemi
|
||||
//
|
||||
static BOOLEAN
|
||||
FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
|
||||
{
|
||||
BYTE ResultReturned
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
int ResultLength;
|
||||
|
||||
/* 82072 and better know DUMPREGS */
|
||||
if (!FloppyWriteCommandByte(ControllerParameters->PortBase,
|
||||
FLOPPY_CMD_DUMP_FDC))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 8272a/765 don't know DUMPREGS */
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is an 8272A\n", PortBase);
|
||||
*ControllerType = FDC_8272A;
|
||||
return TRUE;
|
||||
}
|
||||
if (r != 10)
|
||||
{
|
||||
DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!FloppyConfigure(PortBase, FALSE, 0x0a))
|
||||
{
|
||||
DPRINT("FDC %d is an 82072\n", PortBase);
|
||||
*ControllerType = FDC_82072;
|
||||
return TRUE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PPND_RW);
|
||||
if (FloppyNeedsMoreOutput(PortBase, Result) == FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("FDC %d is an 82072A\n", PortBase);
|
||||
*ControllerType = FDC_82072A;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Pre-1991 82077, doesn't know LOCK/UNLOCK */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is a pre-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077_ORIG;
|
||||
return TRUE;
|
||||
}
|
||||
if ((ResultLength != 1) || (Result[0] != 0x00))
|
||||
{
|
||||
DPRINT("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Revised 82077AA passes all the tests */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength != 1)
|
||||
{
|
||||
DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
if (Result[0] == 0x80)
|
||||
{
|
||||
DPRINT("FDC %d is a post-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077;
|
||||
return TRUE;
|
||||
}
|
||||
switch (Result[0] >> 5)
|
||||
{
|
||||
case 0x0:
|
||||
/* Either a 82078-1 or a 82078SL running at 5Volt */
|
||||
DPRINT("FDC %d is an 82078.\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
case 0x1:
|
||||
DPRINT("FDC %d is a 44pin 82078\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
case 0x2:
|
||||
DPRINT("FDC %d is a S82078B\n", PortBase);
|
||||
*ControllerType = FDC_S82078B;
|
||||
return TRUE;
|
||||
|
||||
case 0x3:
|
||||
DPRINT("FDC %d is a National Semiconductor PC87306\n", PortBase);
|
||||
*ControllerType = FDC_87306;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
DPRINT("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
|
||||
PortBase,
|
||||
Result[0] >> 5);
|
||||
*ControllerType = FDC_82078_UNKN;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* sends a command byte to the fdc */
|
||||
static BOOLEAN
|
||||
FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if ((Status = FloppyWaitUntilReady()) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
FloppyWriteData(PortBase, Byte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
|
||||
Byte,
|
||||
PortBase,
|
||||
Status);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* gets the response from the fdc */
|
||||
static int
|
||||
FloppyReadResultCode(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Replies;
|
||||
int Status;
|
||||
|
||||
for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++)
|
||||
{
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
|
||||
if ((Status & ~STATUS_BUSY) == STATUS_READY)
|
||||
{
|
||||
return Replies;
|
||||
}
|
||||
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
|
||||
{
|
||||
Result[Replies] = fd_inb(FD_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
|
||||
PortBase,
|
||||
Status,
|
||||
Replies);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* waits until the fdc becomes ready */
|
||||
static int
|
||||
FloppyWaitUntilReady(WORD PortBase)
|
||||
{
|
||||
int Retries;
|
||||
int Status;
|
||||
|
||||
for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++)
|
||||
{
|
||||
status = FloppyReadSTAT(PortBase);
|
||||
if (Status & STATUS_READY)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Getstatus times out (%x) on fdc %d\n",
|
||||
Status,
|
||||
PortBase);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define MORE_OUTPUT -2
|
||||
/* does the fdc need more output? */
|
||||
static int
|
||||
FloppyNeedsMoreOutput(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
return -1;
|
||||
if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
return FLOPPY_NEEDS_OUTPUT;
|
||||
}
|
||||
|
||||
return FloppyReadResultCode(PortBase, Result);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
|
||||
{
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
|
||||
/* Turn on FIFO */
|
||||
FloppyWriteCommandByte(FLOPPY_CMD_CFG_FIFO);
|
||||
if (FloppyNeedsOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
FloppyWriteCommandByte(PortBase,
|
||||
0x10 |
|
||||
(DisableFIFO ? 0x20 : 0x00) |
|
||||
(FIFODepth & 0x0f));
|
||||
/* pre-compensation from track 0 upwards */
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
158
reactos/drivers/dd/floppy/floppy.h
Normal file
158
reactos/drivers/dd/floppy/floppy.h
Normal file
@@ -0,0 +1,158 @@
|
||||
|
||||
#define FLOPPY_MAX_STAT_RETRIES 10000
|
||||
|
||||
#define FLOPPY_NEEDS_OUTPUT -2
|
||||
//
|
||||
// Floppy register definitions
|
||||
//
|
||||
|
||||
#define FLOPPY_REG_DOR 0x0002
|
||||
#define FLOPPY_REG_MSTAT 0x0004
|
||||
#define FLOPPY_MS_DRV0BUSY 0x01
|
||||
#define FLOPPY_MS_DRV1BUSY 0x02
|
||||
#define FLOPPY_MS_DRV2BUSY 0x04
|
||||
#define FLOPPY_MS_DRV3BUSY 0x08
|
||||
#define FLOPPY_MS_FDCBUSY 0x10
|
||||
#define FLOPPY_MS_DMAMODE 0x20
|
||||
#define FLOPPY_MS_DATADIR 0x40
|
||||
#define FLOPPY_MS_DATARDY 0x80
|
||||
#define FLOPPY_REG_DATA 0x0005
|
||||
#define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
|
||||
#define FLOPPY_DI_DSKCHNG 0x80
|
||||
#define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
|
||||
|
||||
#define FLOPPY_CMD_RD_TRK 0x02
|
||||
#define FLOPPY_CMD_SPEC_CHARS 0x03
|
||||
#define FLOPPY_CSC_SRT_SHIFT 4
|
||||
#define FLOPPY_CSC_HUT_MASK 0x0f
|
||||
#define FLOPPY_CSC_HLT_SHIFT 1
|
||||
#define FLOPPY_CSC_NON_DMA 0x01
|
||||
#define FLOPPY_CMD_SNS_DRV 0x04
|
||||
#define FLOPPY_CMD_WRT_DATA 0x05
|
||||
#define FLOPPY_CMD_RD_DATA 0x06
|
||||
#define FLOPPY_CMD_RECAL 0x07
|
||||
#define FLOPPY_CMD_SNS_INTR 0x08
|
||||
#define FLOPPY_CSI_IC_MASK 0xe0
|
||||
#define FLOPPY_CSI_IC_RDYCH 0x60
|
||||
#define FLOPPY_CSI_IC_SEEKGD 0x80
|
||||
#define FLOPPY_CSI_IC_SEEKBD 0xc0
|
||||
#define FLOPPY_CMD_WRT_DEL 0x09
|
||||
#define FLOPPY_CMD_RD_ID 0x0a
|
||||
#define FLOPPY_CMD_RD_DEL 0x0c
|
||||
#define FLOPPY_CMD_FMT_TRK 0x0d
|
||||
#define FLOPPY_CMD_DUMP_FDC 0x0e
|
||||
#define FLOPPY_CMD_SEEK 0x0f
|
||||
#define FLOPPY_CMD_VERSION 0x10
|
||||
#define FLOPPY_CMD_SCN_EQ 0x11
|
||||
#define FLOPPY_CMD_PPND_RW 0x12
|
||||
#define FLOPPY_CMD_CFG_FIFO 0x13
|
||||
#define FLOPPY_CMD_LCK_FIFO 0x14
|
||||
#define FLOPPY_CMD_PARTID 0x18
|
||||
#define FLOPPY_CMD_SCN_LE 0x19
|
||||
#define FLOPPY_CMD_SCN_GE 0x1d
|
||||
#define FLOPPY_CMD_CFG_PWR 0x27
|
||||
#define FLOPPY_CMD_SAVE_FDC 0x2e
|
||||
#define FLOPPY_CMD_FMT_ISO 0x33
|
||||
#define FLOPPY_CMD_DMA_READ 0x46
|
||||
#define FLOPPY_CMD_DMA_WRT 0x4a
|
||||
#define FLOPPY_CMD_REST_FDC 0x4e
|
||||
#define FLOPPY_CMD_DRV_SPEC 0x8e
|
||||
#define FLOPPY_CMD_RSEEK_OUT 0x8f
|
||||
#define FLOPPY_CMD_ULK_FIFO 0x94
|
||||
#define FLOPPY_CMD_RSEEK_IN 0xcf
|
||||
#define FLOPPY_CMD_FMT_WRT 0xef
|
||||
|
||||
// Command Code modifiers
|
||||
#define FLOPPY_C0M_SK 0x20
|
||||
#define FLOPPY_C0M_MFM 0x40
|
||||
#define FLOPPY_C0M_MT 0x80
|
||||
#define FLOPPY_C1M_DRVMASK 0x03
|
||||
#define FLOPPY_C1M_HEAD1 0x04
|
||||
|
||||
// Status code values and masks
|
||||
#define FLOPPY_ST0_INVALID 0x80
|
||||
|
||||
// useful command defines
|
||||
#define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
|
||||
#define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
|
||||
#define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)
|
||||
|
||||
//
|
||||
// HAL floppy register access commands
|
||||
//
|
||||
#define FloppyWriteDOR(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DOR, (V)))
|
||||
#define FloppyReadMSTAT(A) (READ_BYTE((A) + FLOPPY_REG_MSTAT))
|
||||
#define FloppyReadDATA(A) (READ_BYTE((A) + FLOPPY_REG_DATA))
|
||||
#define FloppyWriteDATA(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DATA, (V)))
|
||||
#define FloppyReadDIR(A) (READ_BYTE((A) + FLOPPY_REG_DIR))
|
||||
#define FloppyWriteCCNTL(A, V) (WRITE_BYTE((A) + FLOPPY_REG_CCNTL, (V)))
|
||||
|
||||
//
|
||||
// Known Floppy controller types
|
||||
//
|
||||
typedef enum _FLOPPY_CONTROLLER_TYPE
|
||||
{
|
||||
FDC_NONE,
|
||||
FDC_UNKNOWN,
|
||||
FDC_8272A, /* Intel 8272a, NEC 765 */
|
||||
FDC_765ED, /* Non-Intel 1MB-compatible FDC, can't detect */
|
||||
FDC_82072, /* Intel 82072; 8272a + FIFO + DUMPREGS */
|
||||
FDC_82072A, /* 82072A (on Sparcs) */
|
||||
FDC_82077_ORIG, /* Original version of 82077AA, sans LOCK */
|
||||
FDC_82077, /* 82077AA-1 */
|
||||
FDC_82078_UNKN, /* Unknown 82078 variant */
|
||||
FDC_82078, /* 44pin 82078 or 64pin 82078SL */
|
||||
FDC_82078_1, /* 82078-1 (2Mbps fdc) */
|
||||
FDC_S82078B, /* S82078B (first seen on Adaptec AVA-2825 VLB SCSI/EIDE/Floppy controller) */
|
||||
FDC_87306 /* National Semiconductor PC 87306 */
|
||||
} FLOPPY_CONTROLLER_TYPE, *PFLOPPY_CONTROLLER_TYPE;
|
||||
|
||||
typedef struct _FLOPPY_ERROR_THRESHOLDS
|
||||
{
|
||||
/* number of errors to be reached before aborting */
|
||||
unsigned int Abort;
|
||||
/* maximal number of errors permitted to read an entire track at once */
|
||||
unsigned int ReadTrack;
|
||||
/* maximal number of errors before a reset is tried */
|
||||
unsigned int Reset;
|
||||
/* maximal number of errors before a recalibrate is tried */
|
||||
unsigned int Recal;
|
||||
/*
|
||||
* Threshold for reporting FDC errors to the console.
|
||||
* Setting this to zero may flood your screen when using
|
||||
* ultra cheap floppies ;-)
|
||||
*/
|
||||
unsigned int Reporting;
|
||||
} FLOPPY_ERROR_THRESHOLDS;
|
||||
|
||||
#define FDP_DEBUG 0x02
|
||||
#define FDP_SILENT_DCL_CLEAR 0x04
|
||||
#define FDP_MSG 0x10
|
||||
#define FDP_BROKEN_DCL 0x20
|
||||
#define FDP_INVERTED_DCL 0x80
|
||||
|
||||
typedef struct _FLOPPY_DEVICE_PARAMETERS
|
||||
{
|
||||
char CMOSType;
|
||||
unsigned long MaxDTR; /* Step rate, usec */
|
||||
unsigned long HLT; /* Head load/settle time, msec */
|
||||
unsigned long HUT; /* Head unload time (remnant of 8" drives) */
|
||||
unsigned long SRT; /* Step rate, usec */
|
||||
unsigned long Spinup; /* time needed for spinup */
|
||||
unsigned long Spindown; /* timeout needed for spindown */
|
||||
unsigned char SpindownOffset; /* decides in which position the disk will stop */
|
||||
unsigned char SelectDelay; /* delay to wait after select */
|
||||
unsigned char RPS; /* rotations per second */
|
||||
unsigned char Tracks; /* maximum number of tracks */
|
||||
unsigned long Timeout; /* timeout for interrupt requests */
|
||||
unsigned char InterleaveSect; /* if there are more sectors, use interleave */
|
||||
FLOPPY_ERROR_THRESHOLDS MaxErrors;
|
||||
char Flags; /* various flags, including ftd_msg */
|
||||
BOOLEAN ReadTrack; /* use readtrack during probing? */
|
||||
short Autodetect[8]; /* autodetected formats */
|
||||
int CheckFreq; /* how often should the drive be checked for disk changes */
|
||||
int NativeFormat; /* native format of this drive */
|
||||
char *DriveName; /* name of the drive for reporting */
|
||||
} FLOPPY_DEVICE_PARAMETERS, *PFLOPPY_DEVICE_PARAMETERS;
|
||||
|
||||
|
3
reactos/drivers/dd/ide/.cvsignore
Normal file
3
reactos/drivers/dd/ide/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
2058
reactos/drivers/dd/ide/ide.c
Normal file
2058
reactos/drivers/dd/ide/ide.c
Normal file
File diff suppressed because it is too large
Load Diff
235
reactos/drivers/dd/ide/ide.h
Normal file
235
reactos/drivers/dd/ide/ide.h
Normal file
@@ -0,0 +1,235 @@
|
||||
//
|
||||
// IDE.H - defines and typedefs for the IDE Driver module.
|
||||
//
|
||||
|
||||
#ifndef __IDE_H
|
||||
#define __IDE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IDE_MAXIMUM_DEVICES 8
|
||||
|
||||
#define IDE_MAX_NAME_LENGTH 50
|
||||
#define IDE_NT_ROOTDIR_NAME "\\Device"
|
||||
#define IDE_NT_DEVICE_NAME "\\Harddisk"
|
||||
#define IDE_NT_PARTITION_NAME "\\Partition"
|
||||
#define IDE_WIN32_DEVICE_NAME "\\DosDevices\\IDE"
|
||||
#define IDE_DRIVER_NAME "IDEDRIVER"
|
||||
|
||||
#define IDE_SECTOR_BUF_SZ 512
|
||||
#define IDE_MAX_SECTORS_PER_XFER 256
|
||||
#define IDE_MAX_RESET_RETRIES 10000
|
||||
#define IDE_MAX_POLL_RETRIES 100000
|
||||
#define IDE_MAX_WRITE_RETRIES 1000
|
||||
#define IDE_MAX_BUSY_RETRIES 100
|
||||
//#define IDE_MAX_BUSY_RETRIES 100000
|
||||
#define IDE_MAX_DRQ_RETRIES 10000
|
||||
//#define IDE_MAX_CMD_RETRIES 1
|
||||
#define IDE_MAX_CMD_RETRIES 0
|
||||
#define IDE_CMD_TIMEOUT 5
|
||||
#define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */
|
||||
#define IDE_RESET_BUSY_TIMEOUT 31
|
||||
#define IDE_RESET_DRDY_TIMEOUT 120
|
||||
|
||||
// Control Block offsets and masks
|
||||
#define IDE_REG_ALT_STATUS 0x0000
|
||||
#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
|
||||
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
|
||||
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
|
||||
#define IDE_REG_DRV_ADDR 0x0001
|
||||
|
||||
// Command Block offsets and masks
|
||||
#define IDE_REG_DATA_PORT 0x0000
|
||||
#define IDE_REG_ERROR 0x0001 /* error register */
|
||||
#define IDE_ER_AMNF 0x01 /* addr mark not found */
|
||||
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
|
||||
#define IDE_ER_ABRT 0x04 /* command aborted */
|
||||
#define IDE_ER_MCR 0x08 /* media change requested */
|
||||
#define IDE_ER_IDNF 0x10 /* ID not found */
|
||||
#define IDE_ER_MC 0x20 /* Media changed */
|
||||
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
|
||||
#define IDE_REG_PRECOMP 0x0001
|
||||
#define IDE_REG_SECTOR_CNT 0x0002
|
||||
#define IDE_REG_SECTOR_NUM 0x0003
|
||||
#define IDE_REG_CYL_LOW 0x0004
|
||||
#define IDE_REG_CYL_HIGH 0x0005
|
||||
#define IDE_REG_DRV_HEAD 0x0006
|
||||
#define IDE_DH_FIXED 0xA0
|
||||
#define IDE_DH_LBA 0x40
|
||||
#define IDE_DH_HDMASK 0x0F
|
||||
#define IDE_DH_DRV0 0x00
|
||||
#define IDE_DH_DRV1 0x10
|
||||
#define IDE_REG_STATUS 0x0007
|
||||
#define IDE_SR_BUSY 0x80
|
||||
#define IDE_SR_DRDY 0x40
|
||||
#define IDE_SR_DRQ 0x08
|
||||
#define IDE_SR_ERR 0x01
|
||||
#define IDE_REG_COMMAND 0x0007
|
||||
#define IDE_CMD_READ 0x20
|
||||
#define IDE_CMD_READ_RETRY 0x21
|
||||
#define IDE_CMD_WRITE 0x30
|
||||
#define IDE_CMD_WRITE_RETRY 0x31
|
||||
#define IDE_CMD_IDENT_DRV 0xEC
|
||||
|
||||
//
|
||||
// Access macros for command registers
|
||||
// Each macro takes an address of the command port block, and data
|
||||
//
|
||||
#define IDEReadError(Address) (inb_p((Address) + IDE_REG_ERROR))
|
||||
#define IDEWritePrecomp(Address, Data) (outb_p((Address) + IDE_REG_PRECOMP, (Data)))
|
||||
#define IDEReadSectorCount(Address) (inb_p((Address) + IDE_REG_SECTOR_CNT))
|
||||
#define IDEWriteSectorCount(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_CNT, (Data)))
|
||||
#define IDEReadSectorNum(Address) (inb_p((Address) + IDE_REG_SECTOR_NUM))
|
||||
#define IDEWriteSectorNum(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_NUM, (Data)))
|
||||
#define IDEReadCylinderLow(Address) (inb_p((Address) + IDE_REG_CYL_LOW))
|
||||
#define IDEWriteCylinderLow(Address, Data) (outb_p((Address) + IDE_REG_CYL_LOW, (Data)))
|
||||
#define IDEReadCylinderHigh(Address) (inb_p((Address) + IDE_REG_CYL_HIGH))
|
||||
#define IDEWriteCylinderHigh(Address, Data) (outb_p((Address) + IDE_REG_CYL_HIGH, (Data)))
|
||||
#define IDEReadDriveHead(Address) (inb_p((Address) + IDE_REG_DRV_HEAD))
|
||||
#define IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
|
||||
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
||||
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
|
||||
|
||||
//
|
||||
// Data block read and write commands
|
||||
//
|
||||
#define IDEReadBlock(Address, Buffer, Count) \
|
||||
(insw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
#define IDEWriteBlock(Address, Buffer, Count) \
|
||||
(outsw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
|
||||
//
|
||||
// Access macros for control registers
|
||||
// Each macro takes an address of the control port blank and data
|
||||
//
|
||||
#define IDEWriteDriveControl(Address, Data) (outb_p((Address) + IDE_REG_DEV_CNTRL, (Data)))
|
||||
|
||||
// IDE_DEVICE_EXTENSION
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Extension to be placed in each device object
|
||||
//
|
||||
// ACCESS:
|
||||
// Allocated from NON-PAGED POOL
|
||||
// Available at any IRQL
|
||||
//
|
||||
|
||||
typedef struct _IDE_DEVICE_EXTENSION {
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
struct _IDE_DEVICE_EXTESION *DiskExtension;
|
||||
int UnitNumber;
|
||||
BOOLEAN LBASupported;
|
||||
BOOLEAN DMASupported;
|
||||
int BytesPerSector;
|
||||
int LogicalHeads;
|
||||
int SectorsPerLogCyl;
|
||||
int SectorsPerLogTrk;
|
||||
int Offset;
|
||||
int Size;
|
||||
|
||||
int Operation;
|
||||
ULONG BytesRequested;
|
||||
ULONG BytesToTransfer;
|
||||
ULONG BytesRemaining;
|
||||
ULONG StartingSector;
|
||||
int SectorsTransferred;
|
||||
BYTE *TargetAddress;
|
||||
|
||||
} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION;
|
||||
|
||||
// IDE_TIMER_STATES
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// An enumeration containing the states in the timer DFA
|
||||
//
|
||||
|
||||
typedef enum _IDE_TIMER_STATES {
|
||||
IDETimerIdle,
|
||||
IDETimerCmdWait,
|
||||
IDETimerResetWaitForBusyNegate,
|
||||
IDETimerResetWaitForDrdyAssert
|
||||
} IDE_TIMER_STATES;
|
||||
|
||||
// IDE_CONTROLLER_EXTENSION
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Driver-defined structure used to hold miscellaneous controller information.
|
||||
//
|
||||
// ACCESS:
|
||||
// Allocated from NON-PAGED POOL
|
||||
// Available at any IRQL
|
||||
//
|
||||
|
||||
typedef struct _IDE_CONTROLLER_EXTENSION {
|
||||
KSPIN_LOCK SpinLock;
|
||||
int Number;
|
||||
int Vector;
|
||||
int CommandPortBase;
|
||||
int ControlPortBase;
|
||||
BOOLEAN DMASupported;
|
||||
BOOLEAN ControllerInterruptBug;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
BOOLEAN OperationInProgress;
|
||||
BYTE DeviceStatus;
|
||||
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
||||
PIRP CurrentIrp;
|
||||
int Retries;
|
||||
|
||||
IDE_TIMER_STATES TimerState;
|
||||
LONG TimerCount;
|
||||
PDEVICE_OBJECT TimerDevice;
|
||||
|
||||
} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION;
|
||||
|
||||
// IDE_DRIVE_IDENTIFY
|
||||
|
||||
typedef struct _IDE_DRIVE_IDENTIFY {
|
||||
WORD ConfigBits; /*00*/
|
||||
WORD LogicalCyls; /*01*/
|
||||
WORD Reserved02; /*02*/
|
||||
WORD LogicalHeads; /*03*/
|
||||
WORD BytesPerTrack; /*04*/
|
||||
WORD BytesPerSector; /*05*/
|
||||
WORD SectorsPerTrack; /*06*/
|
||||
BYTE InterSectorGap; /*07*/
|
||||
BYTE InterSectorGapSize;
|
||||
BYTE Reserved08H; /*08*/
|
||||
BYTE BytesInPLO;
|
||||
WORD VendorUniqueCnt; /*09*/
|
||||
char SerialNumber[20]; /*10*/
|
||||
WORD ControllerType; /*20*/
|
||||
WORD BufferSize; /*21*/
|
||||
WORD ECCByteCnt; /*22*/
|
||||
char FirmwareRev[8]; /*23*/
|
||||
char ModelNumber[40]; /*27*/
|
||||
WORD RWMultImplemented; /*47*/
|
||||
WORD Reserved48; /*48*/
|
||||
WORD Capabilities; /*49*/
|
||||
#define IDE_DRID_STBY_SUPPORTED 0x2000
|
||||
#define IDE_DRID_IORDY_SUPPORTED 0x0800
|
||||
#define IDE_DRID_IORDY_DISABLE 0x0400
|
||||
#define IDE_DRID_LBA_SUPPORTED 0x0200
|
||||
#define IDE_DRID_DMA_SUPPORTED 0x0100
|
||||
WORD Reserved50; /*50*/
|
||||
WORD MinPIOTransTime; /*51*/
|
||||
WORD MinDMATransTime; /*52*/
|
||||
WORD TMFieldsValid; /*53*/
|
||||
WORD TMCylinders; /*54*/
|
||||
WORD TMHeads; /*55*/
|
||||
WORD TMSectorsPerTrk; /*56*/
|
||||
WORD TMCapacity; /*57*/
|
||||
WORD Reserved53[198]; /*58*/
|
||||
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IDE_H */
|
||||
|
||||
|
39
reactos/drivers/dd/ide/ide.rc
Normal file
39
reactos/drivers/dd/ide/ide.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "IDE Disk Device Driver\0"
|
||||
VALUE "FileVersion", "0.1.4\0"
|
||||
VALUE "InternalName", "ide\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "ide.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
20
reactos/drivers/dd/ide/idep.h
Normal file
20
reactos/drivers/dd/ide/idep.h
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
#define IOCTL_DISK_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_DISK, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_GET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 1, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DISK_SET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_GET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DISK_SET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_VERIFY CTL_CODE(FILE_DEVICE_DISK, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_FORMAT_TRACKS CTL_CODE(FILE_DEVICE_DISK, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_REASSIGN_BLOCKS CTL_CODE(FILE_DEVICE_DISK, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_PERFORMANCE CTL_CODE(FILE_DEVICE_DISK, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_IS_WRITABLE CTL_CODE(FILE_DEVICE_DISK, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_LOGGING CTL_CODE(FILE_DEVICE_DISK, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_FORMAT_TRACKS_EX CTL_CODE(FILE_DEVICE_DISK, 11, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_DATA CTL_CODE(FILE_DEVICE_DISK, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_RESET CTL_CODE(FILE_DEVICE_DISK, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_REQUEST_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_REQUEST_DATA CTL_CODE(FILE_DEVICE_DISK, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
69
reactos/drivers/dd/ide/makefile
Normal file
69
reactos/drivers/dd/ide/makefile
Normal file
@@ -0,0 +1,69 @@
|
||||
# $Id: makefile,v 1.10 1999/12/18 10:17:41 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET=ide
|
||||
|
||||
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET).o
|
||||
- $(RM) $(TARGET).coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) $(TARGET).sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
$(TARGET).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp $(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGET).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
include ../../../rules.mak
|
93
reactos/drivers/dd/ide/partitio.h
Normal file
93
reactos/drivers/dd/ide/partitio.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
*** Partition.h - defines and structs for harddrive partition info
|
||||
***
|
||||
*** 05/30/98 RJJ Created
|
||||
**/
|
||||
|
||||
#ifndef __PARTITION_H
|
||||
#define __PARTITION_H
|
||||
|
||||
#define PARTITION_MAGIC 0xaa55
|
||||
#define PART_MAGIC_OFFSET 0x01fe
|
||||
#define PARTITION_OFFSET 0x01be
|
||||
#define PARTITION_TBL_SIZE 4
|
||||
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
|
||||
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
|
||||
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
|
||||
(s) = (lba) % (scnt) + 1, \
|
||||
(lba) /= (scnt), \
|
||||
(h) = (lba) % (hcnt), \
|
||||
(lba) /= (heads), \
|
||||
(c) = (lba) & 0xff, \
|
||||
(s) |= ((lba) >> 2) & 0xc0)
|
||||
|
||||
/* taken from linux fdisk src */
|
||||
typedef enum PartitionTypes {
|
||||
PTEmpty = 0,
|
||||
PTDOS3xPrimary, /* 1 */
|
||||
PTXENIXRoot, /* 2 */
|
||||
PTXENIXUsr, /* 3 */
|
||||
PTOLDDOS16Bit, /* 4 */
|
||||
PTDosExtended, /* 5 */
|
||||
PTDos5xPrimary, /* 6 */
|
||||
PTOS2HPFS, /* 7 */
|
||||
PTAIX, /* 8 */
|
||||
PTAIXBootable, /* 9 */
|
||||
PTOS2BootMgr, /* 10 */
|
||||
PTWin95FAT32,
|
||||
PTWin95FAT32LBA,
|
||||
PTWin95FAT16LBA,
|
||||
PTWin95ExtendedLBA,
|
||||
PTVenix286 = 0x40,
|
||||
PTNovell = 0x51,
|
||||
PTMicroport = 0x52,
|
||||
PTGnuHurd = 0x63,
|
||||
PTNetware286 = 0x64,
|
||||
PTNetware386 = 0x65,
|
||||
PTPCIX = 0x75,
|
||||
PTOldMinix = 0x80,
|
||||
PTMinix = 0x81,
|
||||
PTLinuxSwap = 0x82,
|
||||
PTLinuxExt2 = 0x83,
|
||||
PTAmoeba = 0x93,
|
||||
PTAmoebaBBT = 0x94,
|
||||
PTBSD = 0xa5,
|
||||
PTBSDIFS = 0xb7,
|
||||
PTBSDISwap = 0xb8,
|
||||
PTSyrinx = 0xc7,
|
||||
PTCPM = 0xdb,
|
||||
PTDOSAccess = 0xe1,
|
||||
PTDOSRO = 0xe3,
|
||||
PTDOSSecondary = 0xf2,
|
||||
PTBBT = 0xff
|
||||
} PARTITIONTYPES;
|
||||
|
||||
#define PartitionIsSupported(P) \
|
||||
((P)->PartitionType == PTDOS3xPrimary || \
|
||||
(P)->PartitionType == PTOLDDOS16Bit || \
|
||||
(P)->PartitionType == PTDos5xPrimary || \
|
||||
(P)->PartitionType == PTWin95FAT32 || \
|
||||
(P)->PartitionType == PTWin95FAT32LBA || \
|
||||
(P)->PartitionType == PTWin95FAT16LBA || \
|
||||
(P)->PartitionType == PTLinuxExt2)
|
||||
|
||||
#define PartitionIsExtended(P) \
|
||||
((P)->PartitionType == PTDosExtended)
|
||||
|
||||
typedef struct Partition {
|
||||
unsigned char BootFlags;
|
||||
unsigned char StartingHead;
|
||||
unsigned char StartingSector;
|
||||
unsigned char StartingCylinder;
|
||||
unsigned char PartitionType;
|
||||
unsigned char EndingHead;
|
||||
unsigned char EndingSector;
|
||||
unsigned char EndingCylinder;
|
||||
unsigned int StartingBlock;
|
||||
unsigned int SectorCount;
|
||||
|
||||
} PARTITION;
|
||||
|
||||
#endif // PARTITION_H
|
||||
|
||||
|
4
reactos/drivers/dd/keyboard/.cvsignore
Normal file
4
reactos/drivers/dd/keyboard/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
732
reactos/drivers/dd/keyboard/keyboard.c
Normal file
732
reactos/drivers/dd/keyboard/keyboard.c
Normal file
@@ -0,0 +1,732 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/keyboard/keyboard.c
|
||||
* PURPOSE: Keyboard driver
|
||||
* PROGRAMMER: Victor Kirhenshtein (sauros@iname.com)
|
||||
* Jason Filby (jasonfilby@yahoo.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/mmhal.h>
|
||||
#include <internal/halio.h>
|
||||
#include <string.h>
|
||||
#include <internal/string.h>
|
||||
#include <defines.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/*
|
||||
* Driver data
|
||||
*/
|
||||
|
||||
static KEY_EVENT_RECORD kbdBuffer[KBD_BUFFER_SIZE];
|
||||
static int bufHead,bufTail;
|
||||
static int keysInBuffer;
|
||||
static int extKey;
|
||||
static BYTE ledStatus;
|
||||
static BYTE capsDown,numDown,scrollDown;
|
||||
static DWORD ctrlKeyState;
|
||||
static PKINTERRUPT KbdInterrupt;
|
||||
static KDPC KbdDpc;
|
||||
static BOOLEAN AlreadyOpened = FALSE;
|
||||
|
||||
/*
|
||||
* PURPOSE: Current irp being processed
|
||||
*/
|
||||
static PIRP CurrentIrp;
|
||||
|
||||
/*
|
||||
* PURPOSE: Number of keys that have been read into the current irp's buffer
|
||||
*/
|
||||
static ULONG KeysRead;
|
||||
static ULONG KeysRequired;
|
||||
|
||||
/*
|
||||
* Virtual key codes table
|
||||
*
|
||||
* Comments:
|
||||
* * PrtSc = VK_PRINT
|
||||
* * Alt+PrtSc (SysRq) = VK_EXECUTE
|
||||
* * Alt = VK_MENU
|
||||
*/
|
||||
|
||||
static const WORD vkTable[128]=
|
||||
{
|
||||
/* 00 - 07 */ 0, VK_ESCAPE, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6,
|
||||
/* 08 - 0F */ VK_7, VK_8, VK_9, VK_0, 189, 187, VK_BACK, VK_TAB,
|
||||
/* 10 - 17 */ VK_Q, VK_W, VK_E, VK_R, VK_T, VK_Y, VK_U, VK_I,
|
||||
/* 18 - 1F */ VK_O, VK_P, 219, 221, VK_RETURN, VK_CONTROL, VK_A, VK_S,
|
||||
/* 20 - 27 */ VK_D, VK_F, VK_G, VK_H, VK_J, VK_K, VK_L, 186,
|
||||
/* 28 - 2F */ 222, 192, VK_SHIFT, 220, VK_Z, VK_X, VK_C, VK_V,
|
||||
/* 30 - 37 */ VK_B, VK_N, VK_M, 188, 190, 191, VK_SHIFT, VK_MULTIPLY,
|
||||
/* 38 - 3F */ VK_MENU, VK_SPACE, VK_CAPITAL, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5,
|
||||
/* 40 - 47 */ VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_NUMLOCK, VK_SCROLL, VK_HOME,
|
||||
/* 48 - 4F */ VK_UP, VK_PRIOR, VK_SUBTRACT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_ADD, VK_END,
|
||||
/* 50 - 57 */ VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, VK_EXECUTE, 0, 0, VK_F11,
|
||||
/* 58 - 5F */ VK_F12, 0, 0, 91, 92, 93, 0, 0,
|
||||
/* 60 - 67 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 68 - 6F */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 70 - 77 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 78 - 7F */ 0, 0, 0, 0, 0, 0, 0, VK_PAUSE
|
||||
};
|
||||
static const WORD vkKeypadTable[13]= /* 47 - 53 */
|
||||
{
|
||||
VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_SUBTRACT,
|
||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_ADD,
|
||||
VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, VK_DECIMAL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ASCII translation tables
|
||||
*/
|
||||
|
||||
static const BYTE asciiTable1[10]=
|
||||
{
|
||||
')','!','@','#','$','%','^','&','*','('
|
||||
};
|
||||
static const BYTE asciiTable2[16]=
|
||||
{
|
||||
'0','1','2','3','4','5','6','7','8','9','*','+',0,'-','.','/'
|
||||
};
|
||||
static const BYTE asciiTable3[37]=
|
||||
{
|
||||
';','=',',','-','.','/','`', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'[', '\\', ']', '\''
|
||||
};
|
||||
static const BYTE asciiTable4[37]=
|
||||
{
|
||||
':','+','<','_','>','?','~', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'{', '|', '}', '"'
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static void KbdWrite(int addr,BYTE data)
|
||||
/*
|
||||
* FUNCTION: Write data to keyboard
|
||||
*/
|
||||
{
|
||||
BYTE status;
|
||||
|
||||
do
|
||||
{
|
||||
status=inb_p(KBD_CTRL_PORT); // Wait until input buffer empty
|
||||
} while(status & KBD_IBF);
|
||||
outb_p(addr,data);
|
||||
}
|
||||
|
||||
static int KbdReadData(void)
|
||||
/*
|
||||
* FUNCTION: Read data from port 0x60
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
BYTE status,data;
|
||||
|
||||
i=500000;
|
||||
do
|
||||
{
|
||||
status=inb_p(KBD_CTRL_PORT);
|
||||
if (!(status & KBD_OBF)) // Check if data available
|
||||
continue;
|
||||
data=inb_p(KBD_DATA_PORT);
|
||||
if (status & (KBD_GTO | KBD_PERR)) // Check for timeout error
|
||||
continue;
|
||||
return data;
|
||||
} while(--i);
|
||||
return -1; // Timed out
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set keyboard LED's
|
||||
*/
|
||||
|
||||
static void SetKeyboardLEDs(BYTE status)
|
||||
{
|
||||
KbdWrite(KBD_DATA_PORT,0xED);
|
||||
if (KbdReadData()!=KBD_ACK) // Error
|
||||
return;
|
||||
KbdWrite(KBD_DATA_PORT,status);
|
||||
KbdReadData();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process scan code
|
||||
*/
|
||||
|
||||
static void ProcessScanCode(BYTE scanCode,BOOL isDown)
|
||||
{
|
||||
switch(scanCode)
|
||||
{
|
||||
case 0x1D: // Ctrl
|
||||
if (extKey)
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=RIGHT_CTRL_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~RIGHT_CTRL_PRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=LEFT_CTRL_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~LEFT_CTRL_PRESSED;
|
||||
}
|
||||
break;
|
||||
case 0x2A: // Left shift
|
||||
case 0x36: // Right shift
|
||||
if (isDown)
|
||||
ctrlKeyState|=SHIFT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~SHIFT_PRESSED;
|
||||
break;
|
||||
case 0x38: // Alt
|
||||
if (extKey)
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=RIGHT_ALT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~RIGHT_ALT_PRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=LEFT_ALT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~LEFT_ALT_PRESSED;
|
||||
}
|
||||
break;
|
||||
case 0x3A: // CapsLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!capsDown)
|
||||
{
|
||||
capsDown=1;
|
||||
if (ctrlKeyState & CAPSLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_CAPS;
|
||||
ctrlKeyState&=~CAPSLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_CAPS;
|
||||
ctrlKeyState|=CAPSLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
capsDown=0;
|
||||
}
|
||||
break;
|
||||
case 0x45: // NumLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!numDown)
|
||||
{
|
||||
numDown=1;
|
||||
if (ctrlKeyState & NUMLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_NUM;
|
||||
ctrlKeyState&=~NUMLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_NUM;
|
||||
ctrlKeyState|=NUMLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numDown=0;
|
||||
}
|
||||
break;
|
||||
case 0x46: // ScrollLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!scrollDown)
|
||||
{
|
||||
scrollDown=1;
|
||||
if (ctrlKeyState & SCROLLLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_SCROLL;
|
||||
ctrlKeyState&=~SCROLLLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_SCROLL;
|
||||
ctrlKeyState|=SCROLLLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollDown=0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Translate virtual key code to ASCII
|
||||
*/
|
||||
|
||||
static BYTE VirtualToAscii(WORD keyCode,BOOL isDown)
|
||||
{
|
||||
if ((ctrlKeyState & ALT_PRESSED)&&(ctrlKeyState & CTRL_PRESSED))
|
||||
return 0; // Ctrl+Alt+char always 0
|
||||
if ((!isDown)&&(ctrlKeyState & ALT_PRESSED))
|
||||
return 0; // Alt+char is 0 when key is released
|
||||
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
{
|
||||
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||
return keyCode-VK_A+1;
|
||||
switch(keyCode)
|
||||
{
|
||||
case VK_SPACE:
|
||||
return ' ';
|
||||
case VK_BACK:
|
||||
return 127;
|
||||
case VK_RETURN:
|
||||
return 10;
|
||||
case 219: /* [ */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 27;
|
||||
case 220: /* \ */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 28;
|
||||
case 221: /* ] */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 29;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||
{
|
||||
if (ctrlKeyState & CAPSLOCK_ON)
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return keyCode-VK_A+'a';
|
||||
else
|
||||
return keyCode-VK_A+'A';
|
||||
else
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return keyCode-VK_A+'A';
|
||||
else
|
||||
return keyCode-VK_A+'a';
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_0)&&(keyCode<=VK_9))
|
||||
{
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return asciiTable1[keyCode-VK_0];
|
||||
else
|
||||
return keyCode-VK_0+'0';
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_NUMPAD0)&&(keyCode<=VK_DIVIDE))
|
||||
return asciiTable2[keyCode-VK_NUMPAD0];
|
||||
|
||||
if ((keyCode>=186)&&(keyCode<=222))
|
||||
{
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return asciiTable4[keyCode-186];
|
||||
else
|
||||
return asciiTable3[keyCode-186];
|
||||
}
|
||||
|
||||
switch(keyCode)
|
||||
{
|
||||
case VK_SPACE:
|
||||
return ' ';
|
||||
case VK_RETURN:
|
||||
return '\n';
|
||||
case VK_BACK:
|
||||
return 8;
|
||||
case VK_TAB:
|
||||
return 9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Translate scan code to virtual key code
|
||||
*/
|
||||
|
||||
static WORD ScanToVirtual(BYTE scanCode)
|
||||
{
|
||||
if ((scanCode>=0x47)&&(scanCode<=0x53)&&(ctrlKeyState & NUMLOCK_ON)&&
|
||||
(!extKey)&&(!(ctrlKeyState & SHIFT_PRESSED)))
|
||||
return vkKeypadTable[scanCode-0x47];
|
||||
if ((scanCode==0x35)&&(extKey)) // Gray divide
|
||||
return VK_DIVIDE;
|
||||
if ((scanCode==0x37)&&(extKey)) // Print screen
|
||||
return VK_PRINT;
|
||||
return vkTable[scanCode];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard IRQ handler
|
||||
*/
|
||||
|
||||
static VOID KbdDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PIRP Irp = (PIRP)SystemArgument2;
|
||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
|
||||
|
||||
CHECKPOINT;
|
||||
DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
|
||||
DeviceObject,Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
IoStartNextPacket(DeviceObject,FALSE);
|
||||
}
|
||||
|
||||
static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context)
|
||||
{
|
||||
BYTE thisKey;
|
||||
BOOL isDown;
|
||||
static BYTE lastKey;
|
||||
|
||||
CHECKPOINT;
|
||||
|
||||
// Read scan code
|
||||
thisKey=inb_p(KBD_DATA_PORT);
|
||||
if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key
|
||||
{
|
||||
extKey=1; // Wait for next byte
|
||||
lastKey=thisKey;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
isDown=!(thisKey & 0x80);
|
||||
thisKey&=0x7F;
|
||||
|
||||
// The keyboard maintains its own internal caps lock and num lock
|
||||
// statuses. In caps lock mode E0 AA precedes make code and
|
||||
// E0 2A follow break code. In num lock mode, E0 2A precedes
|
||||
// make code and E0 AA follow break code. We maintain our own caps lock
|
||||
// and num lock statuses, so we will just ignore these.
|
||||
// Some keyboards have L-Shift/R-Shift modes instead of caps lock
|
||||
// mode. If right shift pressed, E0 B6 / E0 36 pairs generated.
|
||||
if (extKey & ((thisKey==0x2A)||(thisKey==0x36)))
|
||||
{
|
||||
extKey=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check for PAUSE sequence
|
||||
if (extKey && (lastKey==0xE1))
|
||||
{
|
||||
if (thisKey==0x1D)
|
||||
lastKey=0xFF; // Sequence is OK
|
||||
else
|
||||
extKey=0;
|
||||
return FALSE;
|
||||
}
|
||||
if (extKey && (lastKey==0xFF))
|
||||
{
|
||||
if (thisKey!=0x45)
|
||||
{
|
||||
extKey=0; // Bad sequence
|
||||
return FALSE;
|
||||
}
|
||||
thisKey=0x7F; // Pseudo-code for PAUSE
|
||||
}
|
||||
|
||||
ProcessScanCode(thisKey,isDown);
|
||||
|
||||
// DbgPrint("Key: %c\n",VirtualToAscii(ScanToVirtual(thisKey),isDown));
|
||||
// DbgPrint("Key: %x\n",ScanToVirtual(thisKey));
|
||||
if (ScanToVirtual(thisKey)==0x2a)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
if (CurrentIrp!=NULL)
|
||||
{
|
||||
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
|
||||
CurrentIrp->AssociatedIrp.SystemBuffer;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(CurrentIrp);
|
||||
|
||||
CHECKPOINT;
|
||||
|
||||
rec[KeysRead].bKeyDown=isDown;
|
||||
rec[KeysRead].wRepeatCount=1;
|
||||
rec[KeysRead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||
rec[KeysRead].wVirtualScanCode=thisKey;
|
||||
rec[KeysRead].uChar.AsciiChar=VirtualToAscii(rec->wVirtualKeyCode,isDown);
|
||||
rec[KeysRead].dwControlKeyState=ctrlKeyState;
|
||||
if (extKey)
|
||||
{
|
||||
rec[KeysRead].dwControlKeyState|=ENHANCED_KEY;
|
||||
}
|
||||
KeysRead++;
|
||||
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
|
||||
if (KeysRead==KeysRequired)
|
||||
{
|
||||
KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp);
|
||||
CurrentIrp=NULL;
|
||||
}
|
||||
CHECKPOINT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Buffer is full ?
|
||||
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
|
||||
{
|
||||
extKey=0;
|
||||
return(TRUE);
|
||||
}
|
||||
kbdBuffer[bufHead].bKeyDown=isDown;
|
||||
kbdBuffer[bufHead].wRepeatCount=1;
|
||||
kbdBuffer[bufHead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||
kbdBuffer[bufHead].wVirtualScanCode=thisKey;
|
||||
kbdBuffer[bufHead].uChar.UnicodeChar=0;
|
||||
// kbdBuffer[bufHead].uChar.AsciiChar=TranslateScanCode(thisKey);
|
||||
kbdBuffer[bufHead].uChar.AsciiChar=VirtualToAscii(kbdBuffer[bufHead].wVirtualKeyCode,isDown);
|
||||
kbdBuffer[bufHead].dwControlKeyState=ctrlKeyState;
|
||||
if (extKey)
|
||||
kbdBuffer[bufHead].dwControlKeyState|=ENHANCED_KEY;
|
||||
bufHead++;
|
||||
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
|
||||
keysInBuffer++;
|
||||
extKey=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initialize keyboard
|
||||
//
|
||||
static void KeyboardConnectInterrupt(void)
|
||||
{
|
||||
ULONG MappedIrq;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity;
|
||||
NTSTATUS Status;
|
||||
|
||||
MappedIrq = HalGetInterruptVector(Internal,
|
||||
0,
|
||||
0,
|
||||
KEYBOARD_IRQ,
|
||||
&Dirql,
|
||||
&Affinity);
|
||||
Status = IoConnectInterrupt(&KbdInterrupt,
|
||||
KeyboardHandler,
|
||||
NULL,
|
||||
NULL,
|
||||
MappedIrq,
|
||||
Dirql,
|
||||
Dirql,
|
||||
0,
|
||||
FALSE,
|
||||
Affinity,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static int InitializeKeyboard(void)
|
||||
{
|
||||
// Initialize variables
|
||||
bufHead=0;
|
||||
bufTail=0;
|
||||
keysInBuffer=0;
|
||||
ledStatus=0;
|
||||
capsDown=0;
|
||||
numDown=0;
|
||||
scrollDown=0;
|
||||
ctrlKeyState=0;
|
||||
extKey=0;
|
||||
|
||||
KeyboardConnectInterrupt();
|
||||
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from keyboard buffer
|
||||
*/
|
||||
BOOLEAN KbdSynchronizeRoutine(PVOID Context)
|
||||
{
|
||||
PIRP Irp = (PIRP)Context;
|
||||
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)Irp->AssociatedIrp.SystemBuffer;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
ULONG NrToRead = stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||
int i;
|
||||
|
||||
DPRINT("NrToRead %d keysInBuffer %d\n",NrToRead,keysInBuffer);
|
||||
NrToRead = min(NrToRead,keysInBuffer);
|
||||
|
||||
DPRINT("NrToRead %d stk->Parameters.Read.Length %d\n",
|
||||
NrToRead,stk->Parameters.Read.Length);
|
||||
DPRINT("sizeof(KEY_EVENT_RECORD) %d\n",sizeof(KEY_EVENT_RECORD));
|
||||
for (i=0;i<NrToRead;i++)
|
||||
{
|
||||
memcpy(&rec[i],&kbdBuffer[bufTail],sizeof(KEY_EVENT_RECORD));
|
||||
bufTail++;
|
||||
bufTail&=KBD_WRAP_MASK;
|
||||
keysInBuffer--;
|
||||
}
|
||||
if ((stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD))==NrToRead)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
KeysRequired=stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||
KeysRead=NrToRead;
|
||||
CurrentIrp=Irp;
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
#endif
|
||||
|
||||
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
if (KeSynchronizeExecution(KbdInterrupt, KbdSynchronizeRoutine, Irp))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoStartNextPacket(DeviceObject, FALSE);
|
||||
}
|
||||
|
||||
DPRINT("stk->Parameters.Read.Length %d\n",stk->Parameters.Read.Length);
|
||||
DPRINT("KeysRequired %d\n",KeysRequired);
|
||||
}
|
||||
|
||||
NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("DeviceObject %x\n",DeviceObject);
|
||||
DPRINT("Irp %x\n",Irp);
|
||||
|
||||
DPRINT("IRP_MJ_CREATE %d stk->MajorFunction %d\n",
|
||||
IRP_MJ_CREATE, stk->MajorFunction);
|
||||
DPRINT("AlreadyOpened %d\n",AlreadyOpened);
|
||||
|
||||
switch (stk->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
if (AlreadyOpened == TRUE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
// Status = STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_SUCCESS;
|
||||
AlreadyOpened = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_READ:
|
||||
DPRINT("Handling Read request\n");
|
||||
DPRINT("Queueing packet\n");
|
||||
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
||||
Status = STATUS_PENDING;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status==STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Marking irp pending\n");
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
}
|
||||
DPRINT("Status %d\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Module entry point
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING SymlinkName;
|
||||
|
||||
DbgPrint("Keyboard Driver 0.0.4\n");
|
||||
InitializeKeyboard();
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
||||
DriverObject->DriverStartIo = KbdStartIo;
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard");
|
||||
IoCreateDevice(DriverObject,
|
||||
0,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard");
|
||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user