Compare commits
996 commits
Author | SHA1 | Date | |
---|---|---|---|
|
4f8958eb56 | ||
|
66bec19434 | ||
|
4d8ee6bb18 | ||
|
896b4f05ea | ||
|
7cd0f395ca | ||
|
f38a32e64c | ||
|
51b675ef7f | ||
|
43ce2bf5da | ||
|
aa2aa2033c | ||
|
593dcb1b5c | ||
|
43fb0ecd07 | ||
|
7f60584a90 | ||
|
b868d82391 | ||
|
29c0826e6d | ||
|
8568848ba8 | ||
|
87ebccc37d | ||
|
5a8bb41cad | ||
|
c9b72d2d2f | ||
|
437eb42ad2 | ||
|
b9d2885148 | ||
|
6f6ef6cd04 | ||
|
48d68e0c50 | ||
|
8bac669056 | ||
|
2d801c46c7 | ||
|
a2c20d0e93 | ||
|
6ea3bc56ec | ||
|
9b4e3718ed | ||
|
4e04b2d528 | ||
|
d7cf25dcd4 | ||
|
3668a46675 | ||
|
850660ada0 | ||
|
36a4e5c9bb | ||
|
69b049d1b6 | ||
|
a875c18552 | ||
|
c7da2450c9 | ||
|
5db24dbb32 | ||
|
e4e0ce2bc6 | ||
|
1194995050 | ||
|
c635a25f21 | ||
|
fecfb44240 | ||
|
00a0c97879 | ||
|
c6e328c2d0 | ||
|
2546468b4c | ||
|
dd68561c4a | ||
|
53bb4117ac | ||
|
7ff6c6316e | ||
|
e01cb2b915 | ||
|
351d36b0da | ||
|
ac49899e32 | ||
|
f2f453c454 | ||
|
617b29c402 | ||
|
abcbd85b7c | ||
|
d86627a27a | ||
|
7a529fc94f | ||
|
60059bf744 | ||
|
8f58b9e1e1 | ||
|
35cb600c43 | ||
|
5e1da85068 | ||
|
69849bd2ee | ||
|
4573910acc | ||
|
dc9229e6fa | ||
|
3686a04cdd | ||
|
3f5d18b3b6 | ||
|
eb38f7418a | ||
|
47e4907c0d | ||
|
568e90ad11 | ||
|
054a95a817 | ||
|
8b7ac24752 | ||
|
9d95bd5f4b | ||
|
6fe8e64c1a | ||
|
aa8487a4b3 | ||
|
9492a10f44 | ||
|
2e088045b5 | ||
|
4e81f66127 | ||
|
5a7ff3b45c | ||
|
b9eb9a7453 | ||
|
2799c95dd2 | ||
|
ce2ae79f9d | ||
|
1304bf7fb9 | ||
|
d950e1b61f | ||
|
ef58b8c770 | ||
|
37d71415ed | ||
|
58c680bace | ||
|
4e13c72f70 | ||
|
ddff863355 | ||
|
bb47eb9f72 | ||
|
29c73ee173 | ||
|
3dea242677 | ||
|
a9d77d0989 | ||
|
25e0a25807 | ||
|
6bc2c09232 | ||
|
a10da8a42a | ||
|
7ae23ad775 | ||
|
cf08bbaa0f | ||
|
24e9fcac08 | ||
|
47f94fcf5f | ||
|
8dec8cc96c | ||
|
de89f77727 | ||
|
283d4bab22 | ||
|
2bcc87b303 | ||
|
b1cca5b52a | ||
|
d304e58789 | ||
|
c5f0039223 | ||
|
1f589f6304 | ||
|
da2c20a2e6 | ||
|
624e87a725 | ||
|
df97793045 | ||
|
967f3a5074 | ||
|
5ce5dc1f1e | ||
|
7c5b9304a6 | ||
|
81e8513ef2 | ||
|
2745228b14 | ||
|
e1606d698f | ||
|
19b7f33a6e | ||
|
91f3d8b0be | ||
|
0b0259c476 | ||
|
26876b4a6e | ||
|
c11f9a8bc9 | ||
|
a75dde2c1f | ||
|
9ee2adba14 | ||
|
28873ce8c4 | ||
|
1ddaa1d385 | ||
|
737e4411d9 | ||
|
be62646098 | ||
|
a71223eed9 | ||
|
84d5614b11 | ||
|
117fefa274 | ||
|
567b31d7f3 | ||
|
d91f16a24a | ||
|
b053e924e8 | ||
|
a84517418e | ||
|
8405fe85d4 | ||
|
994021da99 | ||
|
1604d8a202 | ||
|
f1dca8914c | ||
|
5d8e8804d4 | ||
|
a63af560dd | ||
|
d0e37372cf | ||
|
c38df594f5 | ||
|
3b12583db0 | ||
|
6ce8a31b0b | ||
|
67153fa0c3 | ||
|
4b0b489f6f | ||
|
a7ad588ec5 | ||
|
70d11a59c6 | ||
|
97e584b695 | ||
|
2e46d81c64 | ||
|
8a65cdd13d | ||
|
5d91ab65fa | ||
|
b13477deb4 | ||
|
cc62cdc1fd | ||
|
98bd248778 | ||
|
cdc842f60d | ||
|
d7aaf51459 | ||
|
753875e80b | ||
|
d09501691e | ||
|
d2c0efe163 | ||
|
e317eafe8f | ||
|
f67b4f6bf4 | ||
|
552cec9477 | ||
|
1e053810f3 | ||
|
a4fb357c89 | ||
|
689868cd50 | ||
|
45d4aa9f60 | ||
|
9ee0720d98 | ||
|
3593ce002f | ||
|
2734b266de | ||
|
0bffa32226 | ||
|
85d029e3b0 | ||
|
1bc7db2e7d | ||
|
a1d0e21b0a | ||
|
f59947bc10 | ||
|
5426e597bb | ||
|
520b7c6d83 | ||
|
c6fa51a949 | ||
|
ae70b66dce | ||
|
7c7e55892e | ||
|
8ae8063743 | ||
|
a4ef56e1d9 | ||
|
0b472874af | ||
|
290dd95dd4 | ||
|
423ba9cb23 | ||
|
9f3f61283d | ||
|
a78cea20d1 | ||
|
25ffa32beb | ||
|
3719aed1f9 | ||
|
86557b9e0b | ||
|
525ef1bf77 | ||
|
668c959f5a | ||
|
442ef40665 | ||
|
4c40aeb90b | ||
|
e428afe4ae | ||
|
69f8118883 | ||
|
2fd582e165 | ||
|
fa7c837f91 | ||
|
de265dfa0b | ||
|
8b41c2cfdd | ||
|
ebfe2653ea | ||
|
d48e250835 | ||
|
eac5ad2a26 | ||
|
899abeafe4 | ||
|
a712d7ec87 | ||
|
fe0c129e0b | ||
|
b1d7c03514 | ||
|
75a5263c60 | ||
|
7598556b64 | ||
|
4fdb45f23f | ||
|
b4a5775ffb | ||
|
19627b13e4 | ||
|
1bb011f815 | ||
|
2c22295233 | ||
|
d70dd61030 | ||
|
5cf558935d | ||
|
9e639ff1f6 | ||
|
b37d3f232b | ||
|
4da091eddd | ||
|
fc97535ccb | ||
|
76abdf3403 | ||
|
5a34601606 | ||
|
aa385765a1 | ||
|
578d104cf6 | ||
|
c94c464920 | ||
|
d0c996b2b4 | ||
|
66ea15f13a | ||
|
08cafe23d5 | ||
|
6413303e60 | ||
|
30140b7d7e | ||
|
bd5ab1c6cd | ||
|
552cc456d1 | ||
|
4d56a33ab0 | ||
|
9d3e458c55 | ||
|
e63da6ea68 | ||
|
7a25bd885e | ||
|
819d8692c6 | ||
|
6b9c1682b1 | ||
|
aabf6334f3 | ||
|
ca95533e8a | ||
|
8dd24ad2a4 | ||
|
d307cfede9 | ||
|
4319ada736 | ||
|
e497f0e88d | ||
|
2692cd8b04 | ||
|
498b632899 | ||
|
b16b366327 | ||
|
f166b298ec | ||
|
47be32f3d1 | ||
|
d6ac41a9f4 | ||
|
793e4640e4 | ||
|
6505403e58 | ||
|
1600f2e6bd | ||
|
72fd6e9251 | ||
|
08f46b8de0 | ||
|
98b7095a21 | ||
|
ce41edab3f | ||
|
e368515eef | ||
|
d282208ac3 | ||
|
a4ad64dda3 | ||
|
65864f92f2 | ||
|
c814cf0d35 | ||
|
81ed2e5465 | ||
|
04981ad759 | ||
|
aaeb221f52 | ||
|
bda48ed85e | ||
|
3b39027655 | ||
|
5ef47e916a | ||
|
5bde3f4c97 | ||
|
8b3944e134 | ||
|
9115dc0aba | ||
|
95b0e65b07 | ||
|
90ee219c44 | ||
|
c4ab638083 | ||
|
63ff75cf12 | ||
|
8d933bf187 | ||
|
2f094cbfe6 | ||
|
a5a0bc10f9 | ||
|
e91243a94e | ||
|
866cb1ca63 | ||
|
30e5111dd5 | ||
|
2c325f8bd3 | ||
|
fcce392066 | ||
|
ee3b9be8e2 | ||
|
fedcd4bb0e | ||
|
3944b36b98 | ||
|
898892d5f0 | ||
|
14743b0ffb | ||
|
7f10145a91 | ||
|
f799bf025b | ||
|
56193155a0 | ||
|
da22ef6c0d | ||
|
b59619d2e4 | ||
|
b4e4921cb6 | ||
|
d77d36b1f4 | ||
|
e6a8fc2448 | ||
|
caf9585c3c | ||
|
3bcd6f1aab | ||
|
737e9d7ffc | ||
|
866907ee3d | ||
|
180bd1044b | ||
|
92d20c1120 | ||
|
3036dddca4 | ||
|
97f07ae211 | ||
|
f6a1844dbe | ||
|
6e619d98a3 | ||
|
8e77d28165 | ||
|
a81bcbe0a9 | ||
|
fc18e54e63 | ||
|
c1f5f98f79 | ||
|
148db6a6c5 | ||
|
4edfe426e4 | ||
|
50a1c5bc92 | ||
|
0d616f9eb0 | ||
|
504d0caae5 | ||
|
3316f59041 | ||
|
9620340b6b | ||
|
abac4b879e | ||
|
5f76872e17 | ||
|
065cbb460b | ||
|
ac32f0a81d | ||
|
3042c7100c | ||
|
929732034c | ||
|
00a541d6a0 | ||
|
7299d3728a | ||
|
8c1f96f7ab | ||
|
c47d6ef1f7 | ||
|
7b5267cf63 | ||
|
83949ee269 | ||
|
174bb7776d | ||
|
e2b1de523e | ||
|
1482e2f960 | ||
|
7c7702f91d | ||
|
2c8d4f5abd | ||
|
e42afe7daf | ||
|
f42316c86d | ||
|
74d1dbb95a | ||
|
5286ed3b0a | ||
|
ffade87df1 | ||
|
99aee076e5 | ||
|
fd865a8386 | ||
|
66f940a2ec | ||
|
084c8cc9c0 | ||
|
354ddcb382 | ||
|
bbdc50c532 | ||
|
39bd338a62 | ||
|
91207991f2 | ||
|
8b7d1a65d0 | ||
|
4ec559743d | ||
|
a9b3fdd3ae | ||
|
40afa8d937 | ||
|
a44681e19b | ||
|
d01ae1512f | ||
|
e21244f7a3 | ||
|
4860fbe7b5 | ||
|
5851ba8686 | ||
|
3af1e7df21 | ||
|
a5b8e68422 | ||
|
81111326ff | ||
|
b527b232cf | ||
|
befd7abe10 | ||
|
af2c686628 | ||
|
f2e6fc695a | ||
|
94f5cd1d30 | ||
|
d71fb7229f | ||
|
834a88fc3f | ||
|
38fb2f41ad | ||
|
2bf209bb4f | ||
|
3418bf6ccd | ||
|
6184f74ef5 | ||
|
3938478aab | ||
|
37ded7380e | ||
|
f127448d00 | ||
|
6d8b4e661f | ||
|
2ab736e292 | ||
|
47e9980bb1 | ||
|
14f69583aa | ||
|
1719aef8cb | ||
|
28c52d4ac3 | ||
|
818d9a1210 | ||
|
d47b13c45a | ||
|
c51c257b06 | ||
|
d538432d79 | ||
|
1d168222fd | ||
|
5c26513278 | ||
|
4a026f4230 | ||
|
fd5b56b96d | ||
|
8dc2cc24d7 | ||
|
e92ba2de43 | ||
|
897bcd5d5c | ||
|
95a91bd816 | ||
|
3103adb6a6 | ||
|
4860be4747 | ||
|
934cfb86b5 | ||
|
d30dafa14d | ||
|
84cb31556a | ||
|
5152e73779 | ||
|
3fd83279c0 | ||
|
8857df969c | ||
|
ec66697005 | ||
|
b1a61e74a3 | ||
|
a0c390de8d | ||
|
ec44170322 | ||
|
a1381fbedb | ||
|
7ff4e5672d | ||
|
20b50c0096 | ||
|
b5cd4c471a | ||
|
d094bde414 | ||
|
6ab88cafaa | ||
|
61f9f5a05f | ||
|
51a0aaeff4 | ||
|
1496ce1614 | ||
|
ec2db2ff75 | ||
|
a30a617212 | ||
|
73a6f764d0 | ||
|
eef4a25d0c | ||
|
0d8bdf392f | ||
|
c8d2955cdc | ||
|
c67726b3d0 | ||
|
788ba75432 | ||
|
955ddc6ea6 | ||
|
c179b269ab | ||
|
e5afb283cf | ||
|
a415874f59 | ||
|
0c35d5cc29 | ||
|
a277ab8e42 | ||
|
1c95001f8f | ||
|
27b22fedde | ||
|
1edd53f00f | ||
|
e1d624a06f | ||
|
8ec8a7f11c | ||
|
7a156cbd7f | ||
|
542e11fcd9 | ||
|
83476e3d4a | ||
|
4f80a599b6 | ||
|
d6d22677da | ||
|
0e3dba2a7a | ||
|
d05b7c8e19 | ||
|
28b94c4d42 | ||
|
5ff94358a0 | ||
|
1df0e34293 | ||
|
24ad74ee26 | ||
|
40b65e28a7 | ||
|
d8b8ac85eb | ||
|
5b833c83be | ||
|
4bba16fd18 | ||
|
aed0c822f1 | ||
|
075a0e2623 | ||
|
e8f7660c75 | ||
|
e7ccb1480a | ||
|
825ec8c597 | ||
|
d47220a23c | ||
|
e5d995d826 | ||
|
ea522c6135 | ||
|
aaaac72fdb | ||
|
c0d0468da9 | ||
|
0f1322d2df | ||
|
e7ff2688c8 | ||
|
ff0cd457b4 | ||
|
732ed62819 | ||
|
f8ddba3ad0 | ||
|
4f02c8ba2d | ||
|
0344f3aa85 | ||
|
b6128bbb51 | ||
|
e614610aaf | ||
|
6b8b35f950 | ||
|
3909a93bc2 | ||
|
eaed90d9b4 | ||
|
20a09a3071 | ||
|
ab5d9bb67b | ||
|
8fcc3c4efe | ||
|
910bd392f6 | ||
|
5bb80251b1 | ||
|
ec2e266c76 | ||
|
e6ce5d5df7 | ||
|
daea0b9b57 | ||
|
5eb46419b4 | ||
|
0a9ad614e6 | ||
|
37bb8c14e0 | ||
|
91e5d21cdf | ||
|
2fc073591b | ||
|
6fa1458378 | ||
|
c3840b6c49 | ||
|
115d690731 | ||
|
1c03b29f7b | ||
|
e65679f455 | ||
|
8f2586cfb5 | ||
|
aa78b46e9c | ||
|
c9ffab4602 | ||
|
61d1c18957 | ||
|
48f8db6c30 | ||
|
13f908b9b5 | ||
|
bb5f0e122f | ||
|
66baee8b99 | ||
|
ad921b3c56 | ||
|
f824a72c7f | ||
|
feee77f84d | ||
|
f014745676 | ||
|
ec099b8ea3 | ||
|
a9428fe390 | ||
|
5f890e3ce9 | ||
|
d6285af1fc | ||
|
8d8c10fe92 | ||
|
5c98412929 | ||
|
6f55a13169 | ||
|
c1b8db0c28 | ||
|
1648569fad | ||
|
0ca1350a03 | ||
|
a56b018713 | ||
|
2abbee9540 | ||
|
058bfeed1d | ||
|
d2045611b6 | ||
|
8dc5242e29 | ||
|
26136fda8d | ||
|
6d2a900487 | ||
|
eb06945b5b | ||
|
2c9f67938f | ||
|
af7f11bb2a | ||
|
5744ef64a4 | ||
|
c4b38894cd | ||
|
48bcf74678 | ||
|
35f5997075 | ||
|
0bc47920d3 | ||
|
08219c02b3 | ||
|
366398cc53 | ||
|
b381f9d095 | ||
|
8cc22a60c3 | ||
|
ec6879b78e | ||
|
90f31fbd0a | ||
|
43220a6063 | ||
|
7c384f361a | ||
|
bf800b5e76 | ||
|
7865026f53 | ||
|
f3bab6c5b7 | ||
|
c5f9d9188a | ||
|
4a227c62a5 | ||
|
d7bbe884ef | ||
|
9725a2286a | ||
|
674efeb1f7 | ||
|
0c35e9adce | ||
|
42cebcca3c | ||
|
a9671befc1 | ||
|
40bda46795 | ||
|
077252f13b | ||
|
0fb7c99c33 | ||
|
93bc97e54f | ||
|
55f71fd846 | ||
|
3ca8204837 | ||
|
02b68a0ac1 | ||
|
6e1e52cbc3 | ||
|
e02b3379eb | ||
|
a7d3d574c0 | ||
|
7c387c0b0e | ||
|
cfab11e16a | ||
|
f0fc4a0d89 | ||
|
1b1f216278 | ||
|
6a3f067eca | ||
|
9e79b9ffd9 | ||
|
440edde5e1 | ||
|
ea4b9bafb2 | ||
|
d6c9ac94d2 | ||
|
48cb5297e7 | ||
|
ba3799527c | ||
|
7325dd4a5a | ||
|
f9dd0fca4c | ||
|
577c327a44 | ||
|
f35e2d513d | ||
|
462b27d87f | ||
|
ca5984059c | ||
|
9ac8d63e22 | ||
|
630d79439c | ||
|
a3adb19bef | ||
|
e3e628247d | ||
|
0dd1502f57 | ||
|
77f4d2207a | ||
|
6f122f48d3 | ||
|
684d51cebb | ||
|
2b25f51e0d | ||
|
f3d3b86668 | ||
|
f4a91bcb8a | ||
|
e5085327ff | ||
|
1d3b312f22 | ||
|
ce2457d5a9 | ||
|
c064fdeb8d | ||
|
ee5828da6a | ||
|
b466a40ffb | ||
|
497992c4ea | ||
|
1999e4f3f5 | ||
|
d8e0c8adea | ||
|
64914849ac | ||
|
84e4620706 | ||
|
7995f3813c | ||
|
f380e34a5e | ||
|
2dcc8ec08d | ||
|
8c5b08d81c | ||
|
beececd101 | ||
|
820b5ff0d1 | ||
|
9d9c3960ef | ||
|
c2ee8627ff | ||
|
227408c4fc | ||
|
e564b0d775 | ||
|
c67053bcce | ||
|
64b2e44697 | ||
|
b0a7439b30 | ||
|
18543523e8 | ||
|
8605708e02 | ||
|
3282eda525 | ||
|
8739aef4ff | ||
|
35ef1be8ef | ||
|
9c5df8004d | ||
|
0698f732af | ||
|
97259a3049 | ||
|
7a66313cfb | ||
|
57c2c41d75 | ||
|
74ff9f2371 | ||
|
34a8478da8 | ||
|
54980a7868 | ||
|
277acf61d0 | ||
|
6cbe072c37 | ||
|
61983465aa | ||
|
d6f13d8e0c | ||
|
da84d77353 | ||
|
29f73d6669 | ||
|
05347b9703 | ||
|
aebcb1a996 | ||
|
09c6f48b12 | ||
|
8e0a00db04 | ||
|
72c228a3ab | ||
|
1ee1f2e9d7 | ||
|
ebaa47dcee | ||
|
3de0f99d4e | ||
|
9478e1f74c | ||
|
6a153ac33e | ||
|
31e3c4316d | ||
|
9591a36ee8 | ||
|
c43b1ecbc3 | ||
|
f7303cf7b6 | ||
|
496eed7aaf | ||
|
a1d63d109d | ||
|
c77261dd5c | ||
|
d287548c77 | ||
|
c2a4f3810b | ||
|
e1e0db6ebe | ||
|
ea552a6f39 | ||
|
4b9e76914a | ||
|
c34159db39 | ||
|
f5ba517323 | ||
|
c837cb3e77 | ||
|
ed8b7b5e2a | ||
|
a02d35d386 | ||
|
bca7038692 | ||
|
beec1b57fb | ||
|
efd3d31082 | ||
|
ba1e2d5dda | ||
|
631a43c577 | ||
|
8e26b7e007 | ||
|
58e68a1b8a | ||
|
89336772f8 | ||
|
259b92d13e | ||
|
4e25c07689 | ||
|
8351a45cb2 | ||
|
c77d2e8a97 | ||
|
f541d947bb | ||
|
21bdc585f3 | ||
|
9ccfac44d5 | ||
|
cbcf609108 | ||
|
d96754213c | ||
|
777a9d0f51 | ||
|
667eca5c0c | ||
|
1662fa9ab1 | ||
|
fe4f138292 | ||
|
a542400d15 | ||
|
2a5acd3dda | ||
|
ef6e9a6bb4 | ||
|
3d6c33f450 | ||
|
0e0ee3e21b | ||
|
3153441f14 | ||
|
3db38ea7f4 | ||
|
6ec977aa00 | ||
|
b9a2ff2558 | ||
|
131918e4c2 | ||
|
f4a3f573c2 | ||
|
03e3bd947f | ||
|
0d51cce2fb | ||
|
4cc9ee7e67 | ||
|
d2df3c2c21 | ||
|
635e0566a3 | ||
|
fbd6b2583d | ||
|
ee06925319 | ||
|
9897719562 | ||
|
2aee2990c0 | ||
|
0abbb467af | ||
|
79b9b60914 | ||
|
0c59e8622b | ||
|
f7c665fd6e | ||
|
c37fea89e6 | ||
|
0d0d37bbea | ||
|
f2c92c68a2 | ||
|
8a8d1dedcf | ||
|
1b32ac45f8 | ||
|
9015eebf87 | ||
|
ce6e298a68 | ||
|
74bf784b29 | ||
|
c55f5d87db | ||
|
4e49c37028 | ||
|
fae3b7a90f | ||
|
27e70ba8ec | ||
|
7c2f6be10e | ||
|
2e6651cb36 | ||
|
af64a8bb5c | ||
|
0c0d181551 | ||
|
71a2e64aee | ||
|
23218818ac | ||
|
232b18d820 | ||
|
7a92a33b27 | ||
|
2778e45421 | ||
|
654c03d131 | ||
|
18b0473fe9 | ||
|
9f555cde20 | ||
|
852e2ffc13 | ||
|
f7bff8802f | ||
|
8a98408056 | ||
|
64ced5a345 | ||
|
73685eb080 | ||
|
5613917974 | ||
|
8710a1cb0a | ||
|
813b35c9d1 | ||
|
c65ac223a0 | ||
|
2e9a57a0b8 | ||
|
d0eea21735 | ||
|
b541b9661a | ||
|
9a1362695b | ||
|
0d969b1764 | ||
|
8ba1b27f23 | ||
|
e24cf32f81 | ||
|
437d304c72 | ||
|
ae584ac620 | ||
|
e1b21bf1e9 | ||
|
9a591bf4fe | ||
|
39e5926760 | ||
|
6fda28d030 | ||
|
c63a990091 | ||
|
8268d4e017 | ||
|
a485f6b4a3 | ||
|
2497a53484 | ||
|
8bd411da0a | ||
|
61564202b5 | ||
|
2e63272f2f | ||
|
9c1bc32fe9 | ||
|
a3686eeb5e | ||
|
76326ed369 | ||
|
f7788fc7e7 | ||
|
db391c37a9 | ||
|
e4ff578bcc | ||
|
e628eb2c6f | ||
|
340a4b05b5 | ||
|
6ec9f446eb | ||
|
f0ab43fea2 | ||
|
fbe99509d6 | ||
|
af4838321e | ||
|
fe4f7632a7 | ||
|
fb5302c29b | ||
|
188d880493 | ||
|
386dbe1059 | ||
|
9a614fefaf | ||
|
088da327b5 | ||
|
0f7ef9f47a | ||
|
8faac9b94a | ||
|
6c1c917750 | ||
|
f0584966c2 | ||
|
ec5e33cad6 | ||
|
510fc64140 | ||
|
552bc893e1 | ||
|
dee3be21a3 | ||
|
c72f0ec0f0 | ||
|
9d044669f3 | ||
|
dd083a6195 | ||
|
58087358d1 | ||
|
62aec0318b | ||
|
0f8b59a245 | ||
|
4bbfd83898 | ||
|
5243f2e82c | ||
|
afac7d7e3f | ||
|
164520f593 | ||
|
9149c7e999 | ||
|
6ba603a03c | ||
|
431a483edc | ||
|
5e3cc88326 | ||
|
7c7b2e8e7e | ||
|
b3ec5bc7ea | ||
|
89e3be4ee9 | ||
|
1e34842799 | ||
|
1b0d8428df | ||
|
152580cefe | ||
|
f5e7abb428 | ||
|
4f61a8a1ab | ||
|
08803bd136 | ||
|
6a6263c8bd | ||
|
588db48be5 | ||
|
65109c725d | ||
|
989988a5ae | ||
|
063a377df4 | ||
|
d1eed1c702 | ||
|
6fd349c6e0 | ||
|
d9c4f506fd | ||
|
f27e4a4a29 | ||
|
e7364e2165 | ||
|
6599f2ff90 | ||
|
a6d77cfd06 | ||
|
5bf6af0c39 | ||
|
71f5bce785 | ||
|
86d82c7334 | ||
|
bb872831de | ||
|
923f1d1b10 | ||
|
c83f86bef5 | ||
|
32e56bd029 | ||
|
5a4d3bad17 | ||
|
6eab84685e | ||
|
8314812354 | ||
|
b049dad6fd | ||
|
a5ce5d637f | ||
|
62027a9c4d | ||
|
9aa7f27d82 | ||
|
b16110f17b | ||
|
7e0177e1e4 | ||
|
839fb09bf0 | ||
|
7914be3ca5 | ||
|
da62790584 | ||
|
f1454777a8 | ||
|
72b7866950 | ||
|
b15d0120cf | ||
|
041167b20a | ||
|
73a8c06804 | ||
|
1e5cc509a7 | ||
|
3881edf6f3 | ||
|
fa42210c49 | ||
|
6e9d214096 | ||
|
90103fa07e | ||
|
7c6a50cc46 | ||
|
1a4163b686 | ||
|
75fa35ad7f | ||
|
c20fc715e2 | ||
|
8946e6df7e | ||
|
dd6e8198e0 | ||
|
cbb343567a | ||
|
dfe2b717a6 | ||
|
7ae488a2bb | ||
|
1e0728c5d4 | ||
|
af4ef5fa02 | ||
|
14a290e77d | ||
|
f4ac9b35c2 | ||
|
931c1a6887 | ||
|
41d7baa013 | ||
|
9cc5ed1802 | ||
|
18bdd435f1 | ||
|
4e74e9dfa9 | ||
|
ee620f0277 | ||
|
a9c9d49a12 | ||
|
e8a2f816f0 | ||
|
3b59be59ae | ||
|
fabf45a9d8 | ||
|
17b9c45311 | ||
|
dfb1665b5f | ||
|
b64cc15d61 | ||
|
9880e29d69 | ||
|
c8a98e03c8 | ||
|
5efab11752 | ||
|
a97a4af0dd | ||
|
95e12689e6 | ||
|
c65d0a0770 | ||
|
139d624787 | ||
|
67bea281cc | ||
|
0efd48113e | ||
|
bbf222ca72 | ||
|
fac555fe68 | ||
|
707685642c | ||
|
9ea0a1072d | ||
|
7dcdfd7bf2 | ||
|
f54acf3de0 | ||
|
9119e3102b | ||
|
8a71a4a304 | ||
|
223292da02 | ||
|
800b5e44fc | ||
|
10db5b67b8 | ||
|
842461979c | ||
|
fddea5da01 | ||
|
231670e899 | ||
|
c62ca5fced | ||
|
e75d1b38b5 | ||
|
4d1ad4f975 | ||
|
55e4aa7a31 | ||
|
b74e1a570b | ||
|
2601a8a2f1 | ||
|
1abebca6dc | ||
|
a271fc9e19 | ||
|
7c4ca6ff74 | ||
|
17f94ab563 | ||
|
bbe1c7532a | ||
|
fb64ea8675 | ||
|
3f421410c1 | ||
|
3c9ede8abc | ||
|
1bc06138f4 | ||
|
f5ed0de392 | ||
|
6ee0583546 | ||
|
499c6be734 | ||
|
73f0bbc731 | ||
|
b8c75f3d2a | ||
|
1eb8f41e54 | ||
|
dee10199cc | ||
|
52f34cf976 | ||
|
455086e295 | ||
|
d93275c6ca | ||
|
4434c17c94 | ||
|
cb2013e7b4 | ||
|
3b85ab31a9 | ||
|
8602a1c24e | ||
|
a5a253820f | ||
|
d88f92eb4e | ||
|
683710fbc7 | ||
|
a05b67b7e5 | ||
|
0ed830eac5 | ||
|
8db5dec9d2 | ||
|
677107956f | ||
|
998111eca1 | ||
|
a38e05636d | ||
|
1bab7ea25e | ||
|
fb2ebbbb40 | ||
|
cd2570c28d | ||
|
ca97cb8700 | ||
|
2990a4f8c3 | ||
|
6e8d450804 | ||
|
6f2a0c412f | ||
|
261d7c3de4 | ||
|
59a7ee1a2c | ||
|
001d1a4319 | ||
|
b6c1760727 | ||
|
23f360b1db | ||
|
df9b41afcb | ||
|
a3ef7d7487 | ||
|
9809102897 | ||
|
f0b32fa541 | ||
|
834558245b | ||
|
5ffed8830c | ||
|
d34cbe61db | ||
|
f74f8b9ef3 | ||
|
5ca8e4b00d | ||
|
37aabda67e | ||
|
80a92c07f5 | ||
|
13d48ed315 | ||
|
ca29c3a422 | ||
|
a4ac824fe5 | ||
|
fc0c738f9d | ||
|
dc800b56b6 | ||
|
6ff5c3b500 | ||
|
8f278f89df | ||
|
0b3d3ad2b7 | ||
|
ab69f71912 | ||
|
02ebacca0c | ||
|
215a8e68d3 | ||
|
b9a985a677 | ||
|
0b441c4c8f | ||
|
e8f4909ac3 | ||
|
267a5658fb | ||
|
ceea01b165 | ||
|
ba4681e776 | ||
|
d68a9d1213 | ||
|
1454ffe7dd | ||
|
b549ae11fb | ||
|
bc62314811 | ||
|
8293074558 | ||
|
6360992dea | ||
|
e00270a8b2 | ||
|
aa2bd097d6 | ||
|
556e3349ab | ||
|
00f04ef3ce | ||
|
88c0f72bbf | ||
|
52b9f8a9fa | ||
|
233074ded0 | ||
|
35bea75647 | ||
|
4121a29b50 | ||
|
eba8b54870 | ||
|
c418771a43 | ||
|
d7edf3e651 | ||
|
1d479df4e8 | ||
|
666a472f06 | ||
|
17d8cb24d4 | ||
|
40b5e767d4 | ||
|
132da0e0ee | ||
|
5fe477767a | ||
|
1a53e28cc8 | ||
|
c17b0d6a3f | ||
|
df8d907fb4 | ||
|
de492f9a34 | ||
|
165830c317 | ||
|
51e99345de | ||
|
b7867059ce | ||
|
1a757a0146 | ||
|
b341688dbd | ||
|
e9e8ab1392 |
1091 changed files with 91611 additions and 46305 deletions
2
.mailmap
2
.mailmap
|
@ -18,7 +18,7 @@ Charles Davis <cdavis@codeweavers.com>
|
|||
Charles Davis <cdavis5x@gmail.com>
|
||||
Christopher Gautier <krys@via.ecp.fr>
|
||||
David A. Cuthbert <dacut@ece.cmu.edu>
|
||||
David Heidelberger <david@ixit.cz>
|
||||
David Heidelberg <david@ixit.cz>
|
||||
Dennis Björklund <db@zigo.dhs.org>
|
||||
Dennis Björklund <dennisb@cs.chalmers.se>
|
||||
Dimitrie O. Paun <dimi@bigfoot.com>
|
||||
|
|
611
ANNOUNCE.md
611
ANNOUNCE.md
|
@ -1,12 +1,12 @@
|
|||
The Wine development release 9.2 is now available.
|
||||
The Wine development release 9.5 is now available.
|
||||
|
||||
What's new in this release:
|
||||
- Mono engine updated to version 9.0.0.
|
||||
- A number of system tray fixes.
|
||||
- Exception handling improvements on ARM platforms.
|
||||
- Initial SLTG-format typelib support in widl.
|
||||
- Exception handling on ARM64EC.
|
||||
- Improvements to Minidump support.
|
||||
- Various bug fixes.
|
||||
|
||||
The source is available at <https://dl.winehq.org/wine/source/9.x/wine-9.2.tar.xz>
|
||||
The source is available at <https://dl.winehq.org/wine/source/9.x/wine-9.5.tar.xz>
|
||||
|
||||
Binary packages for various distributions will be available
|
||||
from <https://www.winehq.org/download>
|
||||
|
@ -16,306 +16,375 @@ You will find documentation on <https://www.winehq.org/documentation>
|
|||
Wine is available thanks to the work of many people.
|
||||
See the file [AUTHORS][1] for the complete list.
|
||||
|
||||
[1]: https://gitlab.winehq.org/wine/wine/-/raw/wine-9.2/AUTHORS
|
||||
[1]: https://gitlab.winehq.org/wine/wine/-/raw/wine-9.5/AUTHORS
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
### Bugs fixed in 9.2 (total 15):
|
||||
### Bugs fixed in 9.5 (total 27):
|
||||
|
||||
- #43993 Quick3270 5.21: crashes when using the Connect function
|
||||
- #47521 digikam 6.10 crashes on start
|
||||
- #51360 vkGetDeviceProcAddr invalid behavior for functions from extensions unsupported by host Vulkan instance
|
||||
- #51770 digikam-7.1.0 freezes on start
|
||||
- #51843 dlls/ws2_32/socket.c:839:17: error: ‘IP_ADD_SOURCE_MEMBERSHIP’ undeclared here
|
||||
- #53934 __unDName fails to demangle a name
|
||||
- #55997 Dolphin Emulator crashes from 5.0-17264
|
||||
- #56122 LANCommander won't start, prints "error code 0x8007046C" (ERROR_MAPPED_ALIGNMENT)
|
||||
- #56243 ShowSystray registry key was removed without alternative
|
||||
- #56250 Elite Dangerous client gets stuck on black screen after launch
|
||||
- #56256 Windows Sysinternals Process Explorer 17.05 shows incomplete user interface (32-bit).
|
||||
- #56259 Microsoft Webview 2 installer hangs forever
|
||||
- #56265 Epic Games Launcher 15.21.0 calls unimplemented function cfgmgr32.dll.CM_Get_Device_Interface_PropertyW
|
||||
- #56291 Kodu game lab crashes (with xnafx40_redist+dotnet48 preinstalled): Object reference not set to an instance of an object.
|
||||
- #56293 user32:msg test_recursive_hook fails on Windows 7
|
||||
- #25207 SHFileOperation does not create new directory on FO_MOVE
|
||||
- #29523 CDBurnerXP hangs on right-clicking empty space in the file browser
|
||||
- #40613 Multiple applications require UAC implementation to run installer/app as a normal user instead of administrator (WhatsApp Desktop, Smartflix, Squirrel Installers, OneDrive)
|
||||
- #44514 Elder Scrolls Online (Dragon Bones update) requires more than 32 samplers in pixel shaders with D3D11 renderer
|
||||
- #45862 Multiple applications need MFCreateSinkWriterFromURL() implementation (Overwatch highlights, RadiAnt DICOM Viewer, Grand Theft Auto V Rockstar Editor)
|
||||
- #48085 Wine error trying to install Mono after a version update
|
||||
- #51957 Program started via HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths should also be started if extension ".exe" is missing
|
||||
- #52352 YI Home installer crashes on unimplemented urlmon.dll.414
|
||||
- #52622 windows-rs 'lib' test crashes on unimplemented function d3dcompiler_47.dll.D3DCreateLinker
|
||||
- #53613 Visual novel RE:D Cherish! logo video and opening movie does not play
|
||||
- #53635 Alune Klient 14.03.2022 crashes on unimplemented function urlmon.dll.414
|
||||
- #54155 WeCom (aka WeChat Work) 4.x failed to launch.
|
||||
- #55421 Fallout Tactics launcher has graphics glitches
|
||||
- #55876 Acrom Controller Updater broken due to oleaut32 install
|
||||
- #56318 Totem Arts Launcher.exe does not open
|
||||
- #56367 Tomb Raider 3 GOG crashes at start
|
||||
- #56379 d2d1 unable to build
|
||||
- #56380 Rocket League crashes with Wine 9.3 after BakkesMod (trainer app) injects into the game
|
||||
- #56400 SSPI authentication does not work when connecting to sql server
|
||||
- #56406 wineserver crashes in set_input_desktop()
|
||||
- #56411 Failure to build wine 9.4 due to EGL 64-bit development files not found
|
||||
- #56433 QQ8.9.6 Installer crashes at very beginning due to a change in server/process.c
|
||||
- #56434 WScript.Network does not implement UserName, ComputerName, and UserDomain properties
|
||||
- #56435 capture mouse dont work in virtual desktop (work on wine 9.3)
|
||||
- #56445 d3d1-9 applications run out of memory after f6a1844dbe (ArmA: Cold War Assault, Final Fantasy XI Online, Far Cry 3)
|
||||
- #56450 Non-input USB HID devices stopped working in 9.1
|
||||
- #56458 ntdll tests skipped on win7 & win8: missing entry point kernel32.RtlPcToFileHeader
|
||||
|
||||
### Changes since 9.1:
|
||||
### Changes since 9.4:
|
||||
```
|
||||
Aida Jonikienė (1):
|
||||
configure: Use YEAR2038 macro when it's available.
|
||||
Akihiro Sagawa (2):
|
||||
dsound/tests: Add tests for implicit MTA creation in IDirectSound::Initialize().
|
||||
dsound: Initialize MTA in IDirectSound::Initialize().
|
||||
|
||||
Alex Henrie (2):
|
||||
krnl386: Emulate the VGA status register.
|
||||
explorer: Handle the back and forward buttons of a 5-button mouse.
|
||||
Alexandre Julliard (42):
|
||||
configure: Check the correct variable for the Wayland EGL library.
|
||||
ntdll: Implement RtlRestoreContext on ARM64EC.
|
||||
ntdll: Implement RtlWalkFrameChain on x86-64.
|
||||
ntdll: Implement RtlWalkFrameChain on i386.
|
||||
ntdll: Implement RtlWalkFrameChain on ARM.
|
||||
ntdll: Implement RtlWalkFrameChain on ARM64.
|
||||
ntdll: Implement RtlWalkFrameChain on ARM64EC.
|
||||
ntdll: Export RtlVirtualUnwind2 and RtlWalkFrameChain.
|
||||
ntdll: Share RtlCaptureStackBackTrace implementation across platforms.
|
||||
secur32/tests: Update count for new winehq.org certificate.
|
||||
ws2_32/tests: Fix a couple of failures on Windows.
|
||||
include: Define setjmpex prototype even when it's a builtin.
|
||||
ntdll/tests: Directly link to setjmp().
|
||||
ntdll/tests: Fix a backtrace test failure on Windows ARM64.
|
||||
ntdll: Add test for non-volatile regs in consolidated unwinds.
|
||||
ntdll: Port the RtlRestoreContext test to ARM64.
|
||||
ntdll: Port the RtlRestoreContext test to ARM.
|
||||
ntdll: Implement RtlUnwindEx on ARM64EC.
|
||||
ntdll: Move __C_specific_handler implementation to unwind.c.
|
||||
ntdll: Implement __C_specific_handler on ARM64EC.
|
||||
ntdll: Always use SEH support on ARM64.
|
||||
ntdll/tests: Skip segment register tests on ARM64EC.
|
||||
ntdll/tests: Fix debug register tests on ARM64EC.
|
||||
ntdll/tests: Fix a few more test failures on ARM64EC.
|
||||
ntdll: Implement RtlGetCallersAddress.
|
||||
kernelbase: Remove no longer needed DllMainCRTStartup function.
|
||||
include: Add some new error codes.
|
||||
include: Add some new status codes.
|
||||
ntdll: Add mappings for more status codes.
|
||||
jscript: Use the correct facility for JScript errors.
|
||||
netprofm: Use the correct symbols for error codes.
|
||||
msvcrt: Use floating point comparison builtins also in MSVC mode.
|
||||
ntdll/tests: Fix exception address checks in child process on ARM64EC.
|
||||
ntdll/tests: Update the KiUserExceptionDispatcher test for ARM64EC.
|
||||
configure: Don't build wow64 support in non-PE builds.
|
||||
wow64: Use a .seh handler in raise_exception().
|
||||
wow64: Always use a .seh handler in cpu_simulate().
|
||||
wow64: Access the BTCpuSimulate backend function pointer directly.
|
||||
wow64: Use a .seh handler for system calls.
|
||||
wow64cpu: Save non-volatile registers before switching to 32-bit code.
|
||||
wow64: Use setjmp/longjmp from ntdll.
|
||||
server: Add a helper to trace uint64 arrays.
|
||||
|
||||
Alexandre Julliard (37):
|
||||
configure: Reset host flags in all cross-compiler error paths.
|
||||
winsta: Start time is an input parameter in WinStationGetProcessSid.
|
||||
ntdll: Use the system setjmp/longjmp for exceptions in Unix libs.
|
||||
ntdll: Use a .seh handler for the unwind exception handler.
|
||||
ntdll: Avoid calling DbgBreakPoint() in process_breakpoint().
|
||||
ntdll: Move DbgUiRemoteBreakin() to the CPU backends.
|
||||
include: Include cfg.h from cfgmgr32.h.
|
||||
ntdll: Report the correct address for breakpoint exception on ARM platforms.
|
||||
kernel32/tests: Fix some test failures on ARM platforms.
|
||||
ntdll: Use a .seh handler for DbgUiRemoteBreakin().
|
||||
dbghelp/tests: Mark failing tests as todo.
|
||||
Revert "loader: Associate folder with explorer".
|
||||
configure: Require a PE compiler for 32-bit ARM.
|
||||
ntdll: Share the is_valid_frame() helper function.
|
||||
ntdll: Only call TEB handlers for frames inside the current stack.
|
||||
winedump: Make the ARM exception information more compact.
|
||||
winedump: Handle ARM64 exception unwind info with flag==3.
|
||||
winebuild: Default to plain "clang" in find_clang_tool().
|
||||
winebuild: Remove some no longer used code for ARM platforms.
|
||||
winebuild: Add .seh annotations on ARM.
|
||||
kernel32: Move Wow64Get/SetThreadContext implementation to kernelbase.
|
||||
kernel32: Don't export RtlRaiseException on ARM64.
|
||||
ntdll: Fix stack layout for ARM syscalls.
|
||||
ntdll/tests: Add some process machine tests for ARM64X.
|
||||
server: Don't report alternate 64-bit machines as supported.
|
||||
ntdll: Update the image information when loading a builtin dll.
|
||||
ntdll: Use the correct machine when loading ntdll on ARM64EC.
|
||||
server: Don't update the machine in the image information for ARM64EC modules.
|
||||
server: Don't update the entry point in the image information for ARM64EC modules.
|
||||
ntdll: Redirect the module entry point for ARM64EC modules.
|
||||
server: Add hybrid flag in image mapping information.
|
||||
ntdll: Use the current machine by default to create an ARM64X process.
|
||||
ntdll: Fix RtlWow64GetCurrentMachine() result on ARM64EC.
|
||||
uxtheme: Use BOOLEAN instead of BOOL in ordinal functions.
|
||||
gdi32/tests: Fix the expected GetTextMetrics() results on recent Windows.
|
||||
user32/tests: Fix some sysparams results on recent Windows.
|
||||
ntdll/tests: Mark a failing test as todo.
|
||||
Alexandros Frantzis (5):
|
||||
winewayland.drv: Implement wglCreateContextAttribsARB.
|
||||
winewayland.drv: Implement wglShareLists.
|
||||
winewayland.drv: Implement wgl(Get)SwapIntervalEXT.
|
||||
win32u: Cancel auto-repeat only if the repeat key is released.
|
||||
win32u: Cancel previous key auto-repeat when starting a new one.
|
||||
|
||||
Alexandros Frantzis (2):
|
||||
winewayland.drv: Track and apply latest window cursor on pointer enter.
|
||||
win32u: Use consistent locking order for display related mutexes.
|
||||
Andrew Nguyen (3):
|
||||
ddraw: Reserve extra space in the reference device description buffer.
|
||||
oleaut32: Bump version resource to Windows 10.
|
||||
ddraw: Release only valid texture parents on ddraw_texture_init failure.
|
||||
|
||||
Arkadiusz Hiler (4):
|
||||
winebus.sys: Fix units used for hat switches.
|
||||
winebus.sys: Use 4 bits for hat switches.
|
||||
wbemprox/tests: Test LIKE queries.
|
||||
wbemprox: Reimplement LIKE.
|
||||
Andrew Wesie (1):
|
||||
wined3d: Use bindless textures for GLSL shaders if possible.
|
||||
|
||||
Brendan Shanks (2):
|
||||
winebuild: Refactor find_tool().
|
||||
winebuild: As a last resort, search for tools un-prefixed using clang.
|
||||
Brendan McGrath (5):
|
||||
comdlg32: Use values from DeviceCapabilities in combobox.
|
||||
comdlg32: Add resolutions to PRINTDLG_ChangePrinterW.
|
||||
comdlg32: Populate printer name on the print dialogs.
|
||||
comdlg32: Use ANSI functions in ANSI WMCommandA.
|
||||
comdlg32: Don't treat cmb1 as the printer list unless in PRINT_SETUP.
|
||||
|
||||
Daniel Lehman (9):
|
||||
glu32/tests: Add a few tests for gluScaleImage.
|
||||
glu32: Return GL_OUT_OF_MEMORY from gluScaleImage if no context.
|
||||
glu32: Return GLU_INVALID_ENUM for illegal pixel types.
|
||||
advapi32/tests: Reduce reallocations.
|
||||
advapi32/tests: Add some more EventLog tests.
|
||||
oleaut32/tests: Add tests for VarBstrFromR8.
|
||||
oleaut32/tests: Add tests for VarBstrFromR4.
|
||||
ucrtbase/tests: Add sprintf tests.
|
||||
msvcrt/tests: Add sprintf tests.
|
||||
Brendan Shanks (6):
|
||||
ntdll: Remove support for msg_accrights FD passing.
|
||||
server: Remove support for msg_accrights FD passing.
|
||||
mountmgr: Replace sprintf with snprintf to avoid deprecation warnings on macOS.
|
||||
mountmgr: Replace some malloc/sprintf/strcpy calls with asprintf.
|
||||
opengl32: Replace sprintf with snprintf/asprintf to avoid deprecation warnings on macOS.
|
||||
secur32: Replace sprintf with snprintf to avoid deprecation warnings on macOS.
|
||||
|
||||
David Kahurani (5):
|
||||
gdiplus: Use GdipCreatePath2 in GdipClonePath.
|
||||
gdiplus: Use GdipCreatePath2 when serializing paths.
|
||||
gdiplus: Use path_list to path helper in GdipFlattenPath.
|
||||
gdiplus: Use path_list to path helper in GdipWidenPath.
|
||||
msvcrt: Free previous environment variable when clearing.
|
||||
Daniel Lehman (2):
|
||||
oleaut32/tests: Add tests for GetSizeMax after dirty flag cleared.
|
||||
oleaut32: Return success from GetSizeMax if not dirty.
|
||||
|
||||
David Gow (1):
|
||||
evr/dshow: Support NV12 in evr_render.
|
||||
|
||||
David Heidelberg (2):
|
||||
d3d9/tests: Replace LPDWORD cast with float_to_int function.
|
||||
mailmap: Add a mailmap entry for myself with the proper name.
|
||||
|
||||
Dmitry Timoshkov (6):
|
||||
d2d1: Make some strings const.
|
||||
wineps.drv: Return default resolution if PPD doesn't provide the list of supported resolutions.
|
||||
kerberos: Allocate memory for the output token if requested.
|
||||
comctl32/tests: Add more tests for IImageList2 interface.
|
||||
comctl32: Implement IImageList2::Initialize().
|
||||
widl: Add initial implementation of SLTG typelib generator.
|
||||
|
||||
Eric Pouech (18):
|
||||
dmime/tests: Fix copy & paste errors.
|
||||
dmime/tests: Add some tests for loops on wave tracks.
|
||||
dmime: Fix IDirectMusicAudioPath::GetObjectInPath() prototype.
|
||||
dmime: Remove unused fields in segment.
|
||||
dmime/tests: Add some tests about end-points.
|
||||
dbghelp/tests: Use Unicode encoding for generated PDB filenames.
|
||||
dbghelp/tests: Test SymSrvGetFileIndexInfo() on .dbg files.
|
||||
dbghelp: Implement SymSrvGetFileIndexInfo() for .dbg files.
|
||||
dbghelp: Implement SymSrvGetFileIndexInfo() for PDB/JG files.
|
||||
kernel32/tests: Added tests about std handle flags inheritance.
|
||||
kernel32/tests: Test DUPLICATE_SAME_ATTRIBUTES flag in DuplicateHandle().
|
||||
server: Implement support for DUPLICATE_SAME_ATTRIBUTES in DuplicateHandle().
|
||||
server: Preserve handle flags when inheriting a std handle.
|
||||
dmime: Fully implement IDirectMusicSegmentState::GetRepeats().
|
||||
dmime: Add tests about segment state's graph interface.
|
||||
dmime: Add IDirectMusicGraph interface to segment state.
|
||||
dmime: Generate track flags while in loop.
|
||||
dmime: Use sent duration in loop's playback.
|
||||
include: Update minidumpapiset.h.
|
||||
dbghelp/tests: Add tests for minidumps.
|
||||
dbghelp/tests: Add tests about generated memory chunks.
|
||||
dbghelp/tests: Add tests about minidump's callback.
|
||||
dbghelp/tests: Test exception information in minidump.
|
||||
dbghelp/tests: Add tests for function table lookup.
|
||||
dbghelp: Use an intermediate buffer in SymFunctionTableAccess (x86_64).
|
||||
dbghelp: Don't write minidump from running thread.
|
||||
dbghelp: Simplify thread info generation in minidump.
|
||||
dbghelp: Add support for V2 unwind info (x86_64).
|
||||
winedbg: Fallback to PE image when reading memory (minidump).
|
||||
winedbg: Reload module without virtual flag.
|
||||
dbghelp: No longer embed unwind information in minidump (x86_64).
|
||||
winedbg: Add ability to set executable name.
|
||||
winedbg: Extend 'attach' command to load minidump files.
|
||||
winedbg: Flush expr buffer upon internal exception.
|
||||
winedbg: Update the CPU information displayed when reloading a minidump.
|
||||
winedbg: Don't reload a minidump for a different machine.
|
||||
|
||||
Esme Povirk (6):
|
||||
gdiplus: Prefer Tahoma for generic sans serif font.
|
||||
mscoree: Update Wine Mono to 9.0.0.
|
||||
user32/tests: Accept EM_GETPASSWORDCHAR when edit is focused.
|
||||
gdiplus: Fix some degenerate cases combining infinite regions.
|
||||
gdiplus/tests: Thoroughly test region combines.
|
||||
user32/tests: Fix flags on expected EM_GETPASSWORDCHAR message.
|
||||
Esme Povirk (7):
|
||||
user32/tests: Accept HCBT_ACTIVATE in TrackPopupMenu.
|
||||
gdiplus: Check bounding box in GdipIsVisibleRegionPoint.
|
||||
user32/tests: Add another missing message for TrackPopupMenu.
|
||||
gdiplus/tests: Region bounds aren't rounded.
|
||||
gdiplus: Calculate region bounding box without generating HRGN.
|
||||
user32/tests: Accept WM_ACTIVATE in TrackPopupMenu.
|
||||
user32/tests: Further updates for win11 TrackPopupMenu failures.
|
||||
|
||||
Fabian Maurer (1):
|
||||
msi: Don't write past end of string when selecting parent directory.
|
||||
|
||||
Felix Münchhalfen (2):
|
||||
ntdll: Use pagesize alignment if MEM_REPLACE_PLACEHOLDER is set in flags of NtMapViewOfSection(Ex).
|
||||
kernelbase/tests: Add a test for MapViewOfFile3 with MEM_REPLACE_PLACEHOLDER.
|
||||
|
||||
Gabriel Ivăncescu (16):
|
||||
mshtml: Forward the script site's QueryService to the document's.
|
||||
mshtml: Forward SID_SInternetHostSecurityManager of the document obj to the doc node.
|
||||
mshtml: Implement IActiveScriptSite service.
|
||||
mshtml: Implement Exec for CGID_ScriptSite's CMDID_SCRIPTSITE_SECURITY_WINDOW.
|
||||
vbscript: Implement IActiveScriptSite service.
|
||||
jscript: Implement IActiveScriptSite service.
|
||||
mshtml: Use a hook to implement postMessage.
|
||||
mshtml: Implement `source` prop for MessageEvents.
|
||||
mshtml: Return E_ABORT from postMessage called without a caller ServiceProvider.
|
||||
mshtml: Implement `data` getter for MessageEvent objs.
|
||||
mshtml: Implement `origin` prop for MessageEvents.
|
||||
mshtml: Implement `initMessageEvent` for MessageEvents.
|
||||
mshtml: Expose the IHTMLEventObj5 props to scripts.
|
||||
mshtml/tests: Test builtin function default value getter with custom IOleCommandTarget.
|
||||
explorer: Don't activate the systray icon when showing it.
|
||||
explorer: Set layered style on systray icons only when it's actually layered.
|
||||
|
||||
Georg Lehmann (3):
|
||||
winevulkan: Prepare for VK_KHR_calibrated_timestamps.
|
||||
winevulkan: Update to VK spec version 1.3.277.
|
||||
winevulkan: Enable VK_ARM_render_pass_striped.
|
||||
Gabriel Ivăncescu (1):
|
||||
shell32: Construct the proper path target for UnixFolder.
|
||||
|
||||
Giovanni Mascellani (1):
|
||||
d2d1: Compile vertex shaders with D3DCompile().
|
||||
d2d1: Compile the pixel shader with D3DCompile().
|
||||
|
||||
Hans Leidekker (1):
|
||||
msxml3: Enable XPath object cache.
|
||||
Hans Leidekker (3):
|
||||
dnsapi/tests: Skip tests if no CNAME records are returned.
|
||||
ntdll/tests: Fix a test failure.
|
||||
ntdll/tests: Load NtMakeTemporaryObject() dynamically.
|
||||
|
||||
Helix Graziani (2):
|
||||
cfgmgr32: Add CM_Get_Device_Interface_PropertyW stub.
|
||||
windows.globalization: Add IIterable_HSTRING impl to IVectorView_HSTRING.
|
||||
Henri Verbeet (1):
|
||||
wined3d: Do not check the input signature element count for sm4+ shaders in shader_spirv_compile_arguments_init().
|
||||
|
||||
Ivo Ivanov (1):
|
||||
winebus.sys: Prefer hidraw if it is the only backend enabled.
|
||||
Jacek Caban (2):
|
||||
configure: Don't explicitly enable -Wenum-conversion on Clang.
|
||||
widl: Always close parsed input file.
|
||||
|
||||
Jacek Caban (11):
|
||||
ncrypt/tests: Don't use uninitialized variable in test_get_property.
|
||||
windowscodecs: Pass result as void pointer to ComponentInfo_GetUINTValue.
|
||||
mf: Avoid implicit enum to int pointer casts.
|
||||
mfplat: Avoid implicit cast in IMFAttributes_GetUINT32 call.
|
||||
mfplat/tests: Use MF_ATTRIBUTE_TYPE type in IMFMediaType_GetItemType call.
|
||||
mfplat: Introduce media_type_get_uint32 helper.
|
||||
mfmediaengine/tests: Use MF_MEDIA_ENGINE_CANPLAY type in IMFMediaEngine_CanPlayType call.
|
||||
mfmediaengine: Avoid implicit casts in IMFAttributes_GetUINT32 calls.
|
||||
include: Add RtlRestoreContext declaration.
|
||||
d3d10/tests: Avoid implicit cast changing value.
|
||||
dsound: Simplify f_to_32.
|
||||
Jinoh Kang (10):
|
||||
tools/gitlab: Run make_specfiles before building.
|
||||
ntdll/tests: Add tests for OBJ_PERMANENT object attribute.
|
||||
ntdll/tests: Add tests for NtMakeTemporaryObject.
|
||||
server: Generalize server request make_temporary to set_object_permanence.
|
||||
ntdll: Implement NtMakePermanentObject.
|
||||
ntdll/tests: Don't import kernel32.RtlPcToFileHeader.
|
||||
Revert "ntdll/tests: Load NtMakeTemporaryObject() dynamically."
|
||||
server: Check for DELETE access in NtMakeTemporaryObject().
|
||||
kernelbase: Open object with DELETE access for NtMakeTemporaryObject().
|
||||
gitlab: Output collapsible section markers in test stage script.
|
||||
|
||||
Louis Lenders (5):
|
||||
ntdll: Add stub for RtlGetDeviceFamilyInfoEnum.
|
||||
shcore: Add stub for RegisterScaleChangeNotifications.
|
||||
wbemprox: Add property 'Caption' to Win32_PnPEntity.
|
||||
wbemprox: Add property 'ClassGuid' to Win32_PnPEntity.
|
||||
wbemprox: Add property 'Caption' to Win32_DiskDrive.
|
||||
Kyrylo Babikov (1):
|
||||
dbghelp: Fix PDB processing using the FPO stream instead of FPOEXT.
|
||||
|
||||
Marc-Aurel Zent (2):
|
||||
ntdll: Reimplement set_native_thread_name() for macOS.
|
||||
ntdll: Fix DW_OP_abs absolute value warning on labs() for clang.
|
||||
Louis Lenders (1):
|
||||
shell32: Try appending .exe when looking up an App Paths key.
|
||||
|
||||
Nikolay Sivov (3):
|
||||
mfplat/tests: Skip device manager test if d3d11 device can't be created.
|
||||
mfplat/tests: Skip tests that require d3d9 support.
|
||||
d3d10/effect: Clarify constant buffer flags field meaning.
|
||||
Marcus Meissner (1):
|
||||
ntdll/tests: Fix size passed to GetModuleFileNameW.
|
||||
|
||||
Paul Gofman (6):
|
||||
ntdll/tests: Fix test_user_shared_data() for a more generic set of present features.
|
||||
server: Check if we have waiting asyncs in (send_socket) before enforcing blocking send.
|
||||
server: Check if we have waiting asyncs in sock_dispatch_asyncs() before clearing POLLOUT.
|
||||
explorer: Don't pop start menu on "minimize all windows" systray command.
|
||||
explorer: Don't pop start menu on "undo minimize all windows" systray command.
|
||||
msvcrt: Adjust _gmtime64_s() accepted time limits.
|
||||
Mark Jansen (1):
|
||||
kernel32/tests: Add tests for job object accounting.
|
||||
|
||||
Nikolay Sivov (16):
|
||||
include: Add ID2D1Factory7 definition.
|
||||
include: Add ID2D1DeviceContext6 definition.
|
||||
d3dcompiler: Set correct compilation target for effects profiles.
|
||||
d3dcompiler: Wrap fx_4_x output in a dxbc container.
|
||||
d3d10/tests: Add a small effect compilation test.
|
||||
wshom/network: Use TRACE() for implemented method.
|
||||
wshom/network: Implement GetTypeInfo().
|
||||
wshom/network: Implement ComputerName() property.
|
||||
wshom/network: Check pointer argument in get_UserName().
|
||||
d3dx10/tests: Remove todo's from now passing tests.
|
||||
d3d10_1/tests: Remove todo from now passing test.
|
||||
wshom/network: Implement UserDomain property.
|
||||
msxml6/tests: Add some tests for MXWriter60.
|
||||
msxml/tests: Move some of the validation tests to their modules.
|
||||
msxml/tests: Move version-specific schema tests to corresponding modules.
|
||||
include: Remove XMLSchemaCache60 from msxml2.idl.
|
||||
|
||||
Noah Berner (1):
|
||||
advapi32/tests: Add todo_wine to tests that are currently failing.
|
||||
|
||||
Paul Gofman (11):
|
||||
imm32: Set lengths to 0 for NULL strings in ImmSetCompositionString().
|
||||
cryptowinrt: Force debug info in critical sections.
|
||||
diasymreader: Force debug info in critical sections.
|
||||
dsdmo: Force debug info in critical sections.
|
||||
qasf: Force debug info in critical sections.
|
||||
services: Force debug info in critical sections.
|
||||
explorer: Force debug info in critical sections.
|
||||
ntdll: Only allocate debug info in critical sections with RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO.
|
||||
server: Ignore some ICMP-originated socket errors for connectionless sockets.
|
||||
strmbase: Fallback to InitializeCriticalSection() if RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO is unsupported.
|
||||
ntdll: Don't use debug info presence to detect critical section global status.
|
||||
|
||||
Pavel Ondračka (1):
|
||||
d3d9/tests: Define enums outside of struct.
|
||||
|
||||
Piotr Caban (6):
|
||||
msvcrt: Store _unDName function parameter backreferences in parsed_symbol structure.
|
||||
msvcrt: Remove no longer used parameters reference arguments from _unDname helpers.
|
||||
winedump: Sync demangling code with msvcrt.
|
||||
jsproxy: Don't ignore hostname and url length in InternetGetProxyInfo.
|
||||
winhttp/tests: Add more WinHttpGetProxyForUrl tests.
|
||||
winhttp: Add support for WINHTTP_AUTOPROXY_HOST_LOWERCASE flag in WinHttpGetProxyForUrl.
|
||||
ntdll: Workaround sendmsg bug on macOS.
|
||||
winedump: Fix REG_DWORD dumping with no data.
|
||||
advapi32/tests: Merge RegLoadKey and RegUnLoadKey tests.
|
||||
advapi32/tests: Remove all files created by RegLoadKey tests.
|
||||
advapi32/tests: Test if modifications are saved in RegUnLoadKey.
|
||||
advapi32/tests: Remove all files created by RegLoadAppKey tests.
|
||||
|
||||
Rémi Bernon (48):
|
||||
explorer: Restore a per-desktop ShowSystray registry setting.
|
||||
mf/tests: Check inserted topology loader transforms explicitly.
|
||||
mf/topology_loader: Use a local variable for the indirect connection method.
|
||||
mf/topology_loader: Ignore SetOutputType errors when doing indirect connect.
|
||||
mf/topology_loader: Initialize transform output type before adding converter.
|
||||
mf/topology_loader: Try to connect transform nodes with their current types first.
|
||||
winegstreamer: Implement H264 decoder GetInputCurrentType.
|
||||
winegstreamer: Ask GStreamer to stop messing with signal handlers.
|
||||
vulkan-1/tests: Enable VK_VERSION_1_1 as requested by validation layers.
|
||||
vulkan-1/tests: Create surface and device before calling test_null_hwnd.
|
||||
vulkan-1/tests: Test VK_KHR_win32_surface with windows in various states.
|
||||
vulkan-1/tests: Add more VK_KHR_win32_surface surface formats tests.
|
||||
vulkan-1/tests: Test VK_KHR_win32_surface WSI with swapchain functions.
|
||||
imm32/tests: Also ignore NotifyIME calls when ignoring WM_IME_NOTIFY.
|
||||
imm32/tests: Fix some spurious failures with Windows ko_KR IME.
|
||||
win32u: Only queue a single IME update during ImeProcessKey.
|
||||
winevulkan: Keep the create_info HWND on the surface wrappers.
|
||||
winevulkan: Return VK_ERROR_SURFACE_LOST_KHR from surface functions.
|
||||
winewayland: Remove now unnecessary VK_ERROR_SURFACE_LOST_KHR checks.
|
||||
winevulkan: Remove now unnecessary vkGetPhysicalDeviceSurfaceSupportKHR driver entry.
|
||||
winevulkan: Remove now unnecessary vkGetPhysicalDeviceSurfacePresentModesKHR driver entry.
|
||||
winevulkan: Remove now unnecessary vkGetDeviceGroupSurfacePresentModesKHR driver entry.
|
||||
user32/tests: Run rawinput device tests in the separate desktop.
|
||||
user32/tests: Rewrite the rawinput buffer test with keyboard input.
|
||||
dinput/tests: Add a helper to wait on HID input reads.
|
||||
dinput/tests: Add more tests for HID rawinput buffer.
|
||||
dinput/tests: Test rawinput messages with non-input desktop.
|
||||
dinput/tests: Use a polled HID touchscreen device.
|
||||
dinput/tests: Test rawinput with the virtual HID touchscreen.
|
||||
winegstreamer: Trace wg_transform input and output caps.
|
||||
winegstreamer: Handle allocation query in a separate helper.
|
||||
winegstreamer: Handle sink caps query in a separate helper.
|
||||
winegstreamer: Handle sink event caps in a separate helper.
|
||||
winegstreamer: Use GST_PTR_FORMAT to trace GStreamer objects.
|
||||
winegstreamer: Ignore wg_transform input / output video format fps.
|
||||
winegstreamer: Allow wg_transform size changes with an explicit attribute.
|
||||
mf/tests: Report more transform current type mismatches.
|
||||
mf/tests: Add some tests with video processor aperture handling.
|
||||
mfreadwrite/tests: Initialize test source stream types from descriptors.
|
||||
mfreadwrite/tests: Test source reader exposed transforms and types.
|
||||
mfreadwrite/tests: Test source reader transforms with MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING.
|
||||
mfreadwrite/tests: Test source reader transforms with MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING.
|
||||
server: Combine HID usage page and usage together.
|
||||
server: Stop using union rawinput in hw_input_t.
|
||||
server: Stop using hardware_msg_data in rawinput_message.
|
||||
server: Move rawinput message conversion from win32u.
|
||||
server: Fix rawinput buffer sizes and alignment on WoW64.
|
||||
win32u: Get rid of the rawinput thread data and buffer.
|
||||
Robin Kertels (1):
|
||||
d3d9/tests: Skip desktop window tests if device creation fails.
|
||||
|
||||
Shaun Ren (4):
|
||||
sapi: Create a new engine only when needed in ISpVoice.
|
||||
sapi: Add ISpeechObjectToken stub.
|
||||
sapi: Add ISpeechObjectTokens stub.
|
||||
sapi: Add stub implementation for ISpeechObjectTokens::get__NewEnum.
|
||||
Rémi Bernon (74):
|
||||
win32u: Move D3DKMT functions to a new d3dkmt.c source.
|
||||
win32u: Move D3DKMT VidPn* functions out of winex11.
|
||||
win32u: Add an adapter struct to the device manager context.
|
||||
win32u: Split writing monitor to registry to a separate helper.
|
||||
win32u: Get rid of the monitor display_device.
|
||||
win32u: Get rid of the monitor state_flags.
|
||||
win32u: Get rid of the adapter display_device.
|
||||
win32u: Get rid of the monitor flags.
|
||||
win32u: Enumerate monitors from their device keys.
|
||||
mfreadwrite/reader: Handle MF_E_TRANSFORM_STREAM_CHANGE results.
|
||||
win32u: Fix incorrect ascii key name in get_config_key.
|
||||
winevulkan: Use an rb_tree and allocate entries for handle mappings.
|
||||
winevulkan: Use a single allocation for device and queues.
|
||||
winevulkan: Pass VkDeviceQueueCreateInfo to wine_vk_device_init_queues.
|
||||
winevulkan: Rename wine_vk_physical_device_alloc parameters and variables.
|
||||
winevulkan: Use a single allocation for instance and physical devices.
|
||||
winevulkan: Get rid of the wine_vk_device_free helper.
|
||||
winevulkan: Simplify wine_vk_instance_free helper.
|
||||
winevulkan: Add handle mappings on creation success only.
|
||||
winevulkan: Get rid of the wine_vk_instance_free helper.
|
||||
mfplat/tests: Test each VIDEOINFOHEADER field conversion separately.
|
||||
mfplat/mediatype: Implement implicit MFInitMediaTypeFromVideoInfoHeader subtype.
|
||||
mfplat/mediatype: Implement MFInitMediaTypeFromVideoInfoHeader2.
|
||||
mfplat/tests: Add tests for MFInitMediaTypeFromVideoInfoHeader2.
|
||||
mfplat/mediatype: Implement MFInitAMMediaTypeFromMFMediaType for FORMAT_VideoInfo2.
|
||||
mfplat/tests: Test aperture to VIDEOINFOHEADER fields mapping.
|
||||
mfplat/mediatype: Support FORMAT_VideoInfo2 in MFInitMediaTypeFromAMMediaType.
|
||||
mfplat/mediatype: Set MF_MT_SAMPLE_SIZE from bmiHeader.biSizeImage.
|
||||
mfplat/mediatype: Map rcSource to MF_MT_(PAN_SCAN|MINIMUM_DISPLAY)_APERTURE.
|
||||
mfplat/mediatype: Set rcSource and rcTarget if stride differs from width.
|
||||
mfplat/tests: Add more MFAverageTimePerFrameToFrameRate tests.
|
||||
mfplat: Support flexible frame time in MFAverageTimePerFrameToFrameRate.
|
||||
mfplat/mediatype: Implement MF_MT_FRAME_RATE from VIDEOINFOHEADER2.
|
||||
mfplat/mediatype: Implement VIDEOINFOHEADER2 dwControlFlags conversion.
|
||||
mfplat/mediatype: Implement some VIDEOINFOHEADER2 dwInterlaceFlags conversion.
|
||||
mfplat/tests: Test that aperture is dropped with VIDEOINFOHEADER2.
|
||||
mfplat/tests: Test that MFCreateMFVideoFormatFromMFMediaType appends user data.
|
||||
mfplat/mediatype: Append user data in MFCreateMFVideoFormatFromMFMediaType.
|
||||
mfplat/tests: Check the conditions for the MFVideoFlag_BottomUpLinearRep flags.
|
||||
mfplat/mediatype: Stub MFInitMediaTypeFromMFVideoFormat.
|
||||
mfplat/tests: Add tests for MFInitMediaTypeFromMFVideoFormat.
|
||||
mfplat/mediatype: Implement MFInitMediaTypeFromMFVideoFormat.
|
||||
winebus: Add HID usages in the device descriptor when possible.
|
||||
winebus: Read hidraw device usages from their report descriptors.
|
||||
winebus: Prefer hidraw for everything that is not a game controller.
|
||||
winebus: Remove devices that are ignored wrt hidraw preferences.
|
||||
winevulkan: Allow only one vulkan surface at a time for an HWND.
|
||||
win32u: Avoid a crash when cleaning up a monitor without an adapter.
|
||||
winegstreamer: Release sink caps in the error path.
|
||||
winegstreamer: Append an optional parser before decoders.
|
||||
mfplat/tests: Add some broken results for Win7.
|
||||
mfplat/tests: Test initializing mediatype from AAC WAVEFORMATEXTENSIBLE.
|
||||
mfplat/tests: Check how AAC attributes are copied from user data.
|
||||
mfplat/mediatype: Check format pointers and sizes in MFInitMediaTypeFromAMMediaType.
|
||||
mfplat/mediatype: Support audio major type in MFInitMediaTypeFromAMMediaType.
|
||||
mfplat/mediatype: Force WAVEFORMATEXTENSIBLE in MFCreateWaveFormatExFromMFMediaType in some cases.
|
||||
mfplat/mediatype: Implement MFCreateMediaTypeFromRepresentation.
|
||||
mfplat/mediatype: Use MFCreateWaveFormatExFromMFMediaType in init_am_media_type_audio_format.
|
||||
ntoskrnl.exe: Open symbolic link with DELETE before making them temporary.
|
||||
server: Avoid removing thread twice from its desktop thread list.
|
||||
winex11: Accept key and mouse events with QS_RAWINPUT.
|
||||
server: Send WM_WINE_CLIPCURSOR message only when necessary.
|
||||
server: Send WM_WINE_SETCURSOR message only when necessary.
|
||||
win32u: Use a structure to pass peek_message arguments.
|
||||
server: Check for internal hardware messages before others.
|
||||
server: Process internal messages when checking queue status.
|
||||
user32/tests: Add missing winetest_pop_context.
|
||||
user32/tests: Add some LoadKeyboardLayoutEx tests.
|
||||
winemac: Use SONAME_LIBVULKAN as an alias for MoltenVK.
|
||||
win32u: Move vulkan loading and init guard out of the drivers.
|
||||
win32u: Move vkGet(Instance|Device)ProcAddr out the drivers.
|
||||
winevulkan: Stop generating the wine/vulkan_driver.h header.
|
||||
win32u: Move vkGet(Device|Instance)ProcAddr helpers inline.
|
||||
mfplat: Append MFVIDEOFORMAT user data after the structure padding.
|
||||
|
||||
Tim Clem (1):
|
||||
winebus.sys: Do not attempt to open keyboard and mouse HID devices on macOS.
|
||||
Santino Mazza (2):
|
||||
mf/test: Check the topologies id's in topo loader.
|
||||
mf/topoloader: Preserve input topology id.
|
||||
|
||||
Vibhav Pant (1):
|
||||
configure: Correctly derive the target from CC if it's set to an absolute path.
|
||||
Vijay Kiran Kamuju (4):
|
||||
include: Add Windows.UI.ViewManagement.UIViewSettings definitions.
|
||||
urlmon: Add stub for ordinal 414.
|
||||
d3dcompiler: Add D3DCreateLinker stub.
|
||||
user32: Add LoadKeyboardLayoutEx stub.
|
||||
|
||||
Yuxuan Shui (2):
|
||||
dmusic: Fix loading wave data from soundfont.
|
||||
mf: Only preroll when starting from stopped state.
|
||||
Yuxuan Shui (8):
|
||||
shell32/tests: Check FindExecutable is looking in the correct current directory.
|
||||
shell32/tests: Check ShellExecute is looking in the correct current directory.
|
||||
shell32: PathResolve(file, NULL, ...) should not look in the current directory.
|
||||
shell32: Make sure PathResolve can find files in the current directory.
|
||||
shell32: PathResolve should be able to find files that already have extensions.
|
||||
shell32: PathResolve should remove trailing dot.
|
||||
shell32: Fix FindExecutable search path.
|
||||
shell32: Rely solely on SHELL_FindExecutable for ShellExecute.
|
||||
|
||||
Zebediah Figura (8):
|
||||
wined3d: Move state objects from state.c to device.c.
|
||||
wined3d: Rename state.c to ffp_gl.c.
|
||||
wined3d: Move sampler_texdim() and texture_activate_dimensions() to ffp_gl.c.
|
||||
d3d8/tests: Add more tests for SPECULARENABLE.
|
||||
wined3d/glsl: Always set WINED3D_SHADER_CONST_FFP_LIGHTS in FFP constant update masks.
|
||||
wined3d/glsl: Pass through the specular varying when SPECULARENABLE is FALSE.
|
||||
wined3d/arb: Always disable the fragment pipeline in shader_arb_select().
|
||||
wined3d/arb: Compare the fragment pipe ops in shader_arb_select() instead of using an extra field.
|
||||
Zebediah Figura (12):
|
||||
ntdll: Assign a primary token in elevate_token().
|
||||
d3d9/tests: Remove a no longer accurate comment.
|
||||
d3d11/tests: Add a test for using a large number of SRV resources.
|
||||
wined3d: Rename the shader_select_compute method to shader_apply_compute_state.
|
||||
wined3d: Move checking shader_update_mask to shader_glsl_apply_compute_state().
|
||||
shell32/tests: Remove obsolete workarounds from test_move().
|
||||
quartz: Implement SetVideoClippingWindow() and PresentImage() in the VMR7 presenter.
|
||||
quartz: Reimplement the VMR7 using the VMR7 presenter.
|
||||
quartz: Implement IVMRSurfaceAllocatorNotify::AdviseSurfaceAllocator().
|
||||
quartz: Return S_OK from IVMRSurfaceAllocator_PrepareSurface().
|
||||
quartz/tests: Add some tests for VMR7 renderless mode.
|
||||
wined3d: Avoid leaking string buffers in shader_glsl_load_bindless_samplers().
|
||||
|
||||
Zhiyi Zhang (7):
|
||||
winex11.drv: Translate whole_rect to x11 root coordinates in set_size_hints().
|
||||
user32/tests: Fix test_recursive_messages() test failures on win7.
|
||||
mf: Make session_get_node_object() more robust.
|
||||
mf: Add a session_flush_nodes() helper.
|
||||
mf/tests: Add a create_test_topology() helper.
|
||||
mf: Support seeking while a session is started.
|
||||
mf/tests: Test IMFMediaSession::Start().
|
||||
Zhenbo Li (1):
|
||||
shell32: Create nonexistent destination directories in FO_MOVE.
|
||||
|
||||
Zhiyi Zhang (5):
|
||||
mfreadwrite: Fix a memory leak (Coverity).
|
||||
win32u: Support HiDPI for the non-client close button in WS_EX_TOOLWINDOW windows.
|
||||
win32u: Fix a possible condition that makes EnumDisplayMonitors() not reporting any monitors.
|
||||
win32u: Don't enumerate mirrored monitor clones for GetSystemMetrics(SM_CMONITORS).
|
||||
win32u: Don't enumerate mirrored monitor clones when unnecessary.
|
||||
```
|
||||
|
|
10
AUTHORS
10
AUTHORS
|
@ -405,7 +405,7 @@ David Gow
|
|||
David Grant
|
||||
David Hammerton
|
||||
David Hedberg
|
||||
David Heidelberger
|
||||
David Heidelberg
|
||||
David Hemmo
|
||||
David Howells
|
||||
David Kahurani
|
||||
|
@ -591,6 +591,7 @@ Gavriel State
|
|||
Gediminas Jakutis
|
||||
Geoff Clare
|
||||
Geoffrey Hausheer
|
||||
Geoffrey McRae
|
||||
Geoff Thorpe
|
||||
Georg Beyerle
|
||||
George Gov
|
||||
|
@ -973,6 +974,7 @@ Karl Lessard
|
|||
Karl Relton
|
||||
Karol Herbst
|
||||
Karsten Elfenbein
|
||||
Kartavya Vashishtha
|
||||
Kasper Sandberg
|
||||
Katarzyna Caban
|
||||
K.B.Dharun Krishna
|
||||
|
@ -1034,12 +1036,14 @@ Kristian Nielsen
|
|||
Kristján Gerhardsson
|
||||
Kristofer Henriksson
|
||||
Kristoffer Gleditsch
|
||||
Krzysztof Bogacki
|
||||
Krzysztof Foltman
|
||||
Krzysztof Kotlenga
|
||||
Krzysztof Nowicki
|
||||
Kurt Kartaltepe
|
||||
Kusanagi Kouichi
|
||||
Kyle Luna
|
||||
Kyrylo Babikov
|
||||
Lance Jackson
|
||||
Lars-Ake Fredlund
|
||||
Lars Heete
|
||||
|
@ -1309,6 +1313,7 @@ Niels Kristian Bech Jensen
|
|||
Nigel Liang
|
||||
Nikita Morozkin
|
||||
Nikita V. Youshchenko
|
||||
Nikola Kuburović
|
||||
Nikola Pavlica
|
||||
Nikolas Zimmermann
|
||||
Nikolay Bogoychev
|
||||
|
@ -1316,6 +1321,7 @@ Nikolay Sivov
|
|||
Nikolay Stefanov
|
||||
Nils Kuhnhenn
|
||||
Nix N. Nix
|
||||
Noah Berner
|
||||
Noel Borthwick
|
||||
Noomen Hamza
|
||||
Norman Stevens
|
||||
|
@ -1383,6 +1389,7 @@ Paul van Schayck
|
|||
Paul Vriens
|
||||
Pavel Borecki
|
||||
Pavel Kankovsky
|
||||
Pavel Ondračka
|
||||
Pavel Roskin
|
||||
Pavel Semerad
|
||||
Pavel Troller
|
||||
|
@ -1479,6 +1486,7 @@ Ralf S. Engelschall
|
|||
Ramon Garcia
|
||||
Randy Weems
|
||||
Raphael Junqueira
|
||||
Rastislav Stanik
|
||||
Raul Dias
|
||||
Raul Fernandes
|
||||
Raul Metsma
|
||||
|
|
|
@ -169,6 +169,7 @@ P: Aric Stewart <aric@codeweavers.com>
|
|||
F: dlls/hid/
|
||||
F: dlls/hidclass.sys/
|
||||
F: dlls/hidparse.sys/
|
||||
F: dlls/mouhid.sys/
|
||||
F: dlls/winehid.sys/
|
||||
|
||||
HTTP server
|
||||
|
@ -217,7 +218,6 @@ P: Zebediah Figura <z.figura12@gmail.com>
|
|||
F: dlls/mf/tests/transform.c
|
||||
F: dlls/winegstreamer/aac_decoder.c
|
||||
F: dlls/winegstreamer/color_convert.c
|
||||
F: dlls/winegstreamer/h264_decoder.c
|
||||
F: dlls/winegstreamer/media_source.c
|
||||
F: dlls/winegstreamer/mfplat.c
|
||||
F: dlls/winegstreamer/resampler.c
|
||||
|
|
|
@ -42,7 +42,7 @@ especially the wealth of information found at https://www.winehq.org.
|
|||
|
||||
To compile and run Wine, you must have one of the following:
|
||||
|
||||
- Linux version 2.0.36 or later
|
||||
- Linux version 2.6.22 or later
|
||||
- FreeBSD 12.4 or later
|
||||
- Solaris x86 9 or later
|
||||
- NetBSD-current
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
Wine version 9.2
|
||||
Wine version 9.5
|
||||
|
|
422
configure
vendored
422
configure
vendored
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for Wine 9.2.
|
||||
# Generated by GNU Autoconf 2.71 for Wine 9.5.
|
||||
#
|
||||
# Report bugs to <wine-devel@winehq.org>.
|
||||
#
|
||||
|
@ -611,8 +611,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='Wine'
|
||||
PACKAGE_TARNAME='wine'
|
||||
PACKAGE_VERSION='9.2'
|
||||
PACKAGE_STRING='Wine 9.2'
|
||||
PACKAGE_VERSION='9.5'
|
||||
PACKAGE_STRING='Wine 9.5'
|
||||
PACKAGE_BUGREPORT='wine-devel@winehq.org'
|
||||
PACKAGE_URL='https://www.winehq.org'
|
||||
|
||||
|
@ -702,6 +702,10 @@ INOTIFY_LIBS
|
|||
INOTIFY_CFLAGS
|
||||
PCSCLITE_LIBS
|
||||
PCAP_LIBS
|
||||
WAYLAND_EGL_LIBS
|
||||
WAYLAND_EGL_CFLAGS
|
||||
EGL_LIBS
|
||||
EGL_CFLAGS
|
||||
XKBREGISTRY_LIBS
|
||||
XKBREGISTRY_CFLAGS
|
||||
XKBCOMMON_LIBS
|
||||
|
@ -929,7 +933,6 @@ with_capi
|
|||
with_coreaudio
|
||||
with_cups
|
||||
with_dbus
|
||||
with_float_abi
|
||||
with_fontconfig
|
||||
with_freetype
|
||||
with_gettext
|
||||
|
@ -1233,6 +1236,7 @@ enable_midimap
|
|||
enable_mlang
|
||||
enable_mmcndmgr
|
||||
enable_mmdevapi
|
||||
enable_mouhid_sys
|
||||
enable_mountmgr_sys
|
||||
enable_mp3dmod
|
||||
enable_mpr
|
||||
|
@ -1493,6 +1497,7 @@ enable_windows_media
|
|||
enable_windows_networking_hostname
|
||||
enable_windows_networking
|
||||
enable_windows_perception_stub
|
||||
enable_windows_security_authentication_onlineid
|
||||
enable_windows_security_credentials_ui_userconsentverifier
|
||||
enable_windows_storage_applicationdata
|
||||
enable_windows_system_profile_systemmanufacturers
|
||||
|
@ -1802,6 +1807,10 @@ XKBCOMMON_CFLAGS
|
|||
XKBCOMMON_LIBS
|
||||
XKBREGISTRY_CFLAGS
|
||||
XKBREGISTRY_LIBS
|
||||
EGL_CFLAGS
|
||||
EGL_LIBS
|
||||
WAYLAND_EGL_CFLAGS
|
||||
WAYLAND_EGL_LIBS
|
||||
INOTIFY_CFLAGS
|
||||
INOTIFY_LIBS
|
||||
DBUS_CFLAGS
|
||||
|
@ -2388,7 +2397,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures Wine 9.2 to adapt to many kinds of systems.
|
||||
\`configure' configures Wine 9.5 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -2458,7 +2467,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of Wine 9.2:";;
|
||||
short | recursive ) echo "Configuration of Wine 9.5:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -2487,7 +2496,6 @@ Optional Packages:
|
|||
--without-coreaudio do not use the CoreAudio sound support
|
||||
--without-cups do not use CUPS
|
||||
--without-dbus do not use DBus (dynamic device support)
|
||||
--with-float-abi=abi specify the ABI (soft|softfp|hard) for ARM platforms
|
||||
--without-fontconfig do not use fontconfig
|
||||
--without-freetype do not use the FreeType library
|
||||
--without-gettext do not use gettext
|
||||
|
@ -2629,6 +2637,12 @@ Some influential environment variables:
|
|||
C compiler flags for xkbregistry, overriding pkg-config
|
||||
XKBREGISTRY_LIBS
|
||||
Linker flags for xkbregistry, overriding pkg-config
|
||||
EGL_CFLAGS C compiler flags for egl, overriding pkg-config
|
||||
EGL_LIBS Linker flags for egl, overriding pkg-config
|
||||
WAYLAND_EGL_CFLAGS
|
||||
C compiler flags for wayland-egl, overriding pkg-config
|
||||
WAYLAND_EGL_LIBS
|
||||
Linker flags for wayland-egl, overriding pkg-config
|
||||
INOTIFY_CFLAGS
|
||||
C compiler flags for libinotify, overriding pkg-config
|
||||
INOTIFY_LIBS
|
||||
|
@ -2756,7 +2770,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
Wine configure 9.2
|
||||
Wine configure 9.5
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
@ -3207,7 +3221,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by Wine $as_me 9.2, which was
|
||||
It was created by Wine $as_me 9.5, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
|
@ -4271,13 +4285,6 @@ then :
|
|||
fi
|
||||
|
||||
|
||||
# Check whether --with-float-abi was given.
|
||||
if test ${with_float_abi+y}
|
||||
then :
|
||||
withval=$with_float_abi;
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-fontconfig was given.
|
||||
if test ${with_fontconfig+y}
|
||||
then :
|
||||
|
@ -6362,24 +6369,11 @@ printf "%s\n" "$wine_cv_thumb2" >&6; }
|
|||
if test x"$wine_cv_thumb2" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -mthumb"
|
||||
TARGETFLAGS="$TARGETFLAGS -mthumb"
|
||||
else
|
||||
CFLAGS="$CFLAGS -marm"
|
||||
TARGETFLAGS="$TARGETFLAGS -marm"
|
||||
fi
|
||||
case $with_float_abi in
|
||||
soft|softfp|hard)
|
||||
float_abi=$with_float_abi ;;
|
||||
*)
|
||||
case $host_os in
|
||||
*eabihf)
|
||||
float_abi=hard ;;
|
||||
*)
|
||||
float_abi=softfp
|
||||
saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -mfloat-abi=$float_abi"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -mfloat-abi=$float_abi" >&5
|
||||
printf %s "checking whether $CC supports -mfloat-abi=$float_abi... " >&6; }
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports floating point instructions" >&5
|
||||
printf %s "checking whether $CC supports floating point instructions... " >&6; }
|
||||
if test ${wine_cv_float_abi+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
|
@ -6406,38 +6400,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
|||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $wine_cv_float_abi" >&5
|
||||
printf "%s\n" "$wine_cv_float_abi" >&6; }
|
||||
if test $wine_cv_float_abi = no
|
||||
then
|
||||
float_abi=soft
|
||||
as_fn_append wine_warnings "|Floating point is not supported for this target. The resulting build won't be compatible with Windows ARM binaries."
|
||||
fi
|
||||
CFLAGS=$saved_CFLAGS
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
CFLAGS="$CFLAGS -mfloat-abi=$float_abi"
|
||||
TARGETFLAGS="$TARGETFLAGS -mfloat-abi=$float_abi"
|
||||
test $wine_cv_float_abi != no || as_fn_error $? "The ARM target needs to support floating point instructions." "$LINENO" 5
|
||||
;;
|
||||
esac
|
||||
|
||||
enable_win16=${enable_win16:-i386}
|
||||
enable_win64=${enable_win64:-no}
|
||||
enable_wow64=${enable_wow64:-aarch64,x86_64}
|
||||
enable_wow64win=${enable_wow64win:-aarch64,x86_64}
|
||||
enable_wow64cpu=${enable_wow64cpu:-x86_64}
|
||||
enable_vcruntime140_1=${enable_vcruntime140_1:-x86_64,arm64ec}
|
||||
|
||||
enable_cmd=${enable_cmd:-yes}
|
||||
enable_dllhost=${enable_dllhost:-yes}
|
||||
enable_dpnsvr=${enable_dpnsvr:-i386,x86_64,arm64ec}
|
||||
enable_dxdiag=${enable_dxdiag:-yes}
|
||||
enable_msiexec=${enable_msiexec:-yes}
|
||||
enable_netsh=${enable_netsh:-yes}
|
||||
enable_regsvr32=${enable_regsvr32:-yes}
|
||||
enable_rundll32=${enable_rundll32:-yes}
|
||||
|
||||
enable_winetest=${enable_winetest:-$enable_tests}
|
||||
|
||||
if test "x$enable_win64" = "xyes"
|
||||
then
|
||||
test -z "$with_wine64" || as_fn_error $? "--enable-win64 and --with-wine64 are mutually exclusive.
|
||||
|
@ -11521,7 +11487,41 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"
|
|||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wabsolute-value"
|
||||
fi }
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-Wenum-conversion" | $as_tr_sh`
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-Wenum-enum-conversion" | $as_tr_sh`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wenum-enum-conversion" >&5
|
||||
printf %s "checking whether $CC supports -Wenum-enum-conversion... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -Wenum-enum-conversion"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else $as_nop
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
:
|
||||
else $as_nop
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-Wenum-conversion" | $as_tr_sh`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wenum-conversion" >&5
|
||||
printf %s "checking whether $CC supports -Wenum-conversion... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
|
@ -11555,6 +11555,42 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"
|
|||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wenum-conversion"
|
||||
fi }
|
||||
fi }
|
||||
|
||||
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-flarge-source-files -Wmisleading-indentation" | $as_tr_sh`
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -flarge-source-files -Wmisleading-indentation" >&5
|
||||
printf %s "checking whether $CC supports -flarge-source-files -Wmisleading-indentation... " >&6; }
|
||||
if eval test \${$as_ac_var+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_wine_try_cflags_saved=$CFLAGS
|
||||
ac_wine_try_cflags_saved_exeext=$ac_exeext
|
||||
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -flarge-source-files -Wmisleading-indentation"
|
||||
ac_exeext=".exe"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
void *__os_arm64x_dispatch_ret = 0;
|
||||
int __cdecl mainCRTStartup(void) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$as_ac_var=yes"
|
||||
else $as_nop
|
||||
eval "$as_ac_var=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
ac_exeext=$ac_wine_try_cflags_saved_exeext
|
||||
fi
|
||||
eval ac_res=\$$as_ac_var
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wno-misleading-indentation"
|
||||
fi }
|
||||
|
||||
case $wine_arch in
|
||||
i386) { as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-fno-omit-frame-pointer" | $as_tr_sh`
|
||||
|
@ -13570,7 +13606,7 @@ then :
|
|||
MPG123_PE_LIBS=mpg123
|
||||
if ${MPG123_PE_CFLAGS:+false} :
|
||||
then :
|
||||
MPG123_PE_CFLAGS="-I\$(top_srcdir)/libs/mpg123/src/libmpg123"
|
||||
MPG123_PE_CFLAGS="-I\$(top_srcdir)/libs/mpg123/src/include"
|
||||
else $as_nop
|
||||
enable_mpg123=no
|
||||
fi
|
||||
|
@ -16167,6 +16203,188 @@ fi
|
|||
|
||||
CPPFLAGS=$ac_save_CPPFLAGS
|
||||
|
||||
if test "x$with_opengl" != "xno"
|
||||
then
|
||||
rm -f conftest.err
|
||||
if ${EGL_CFLAGS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
EGL_CFLAGS=`$PKG_CONFIG --cflags egl 2>conftest.err`
|
||||
fi
|
||||
fi
|
||||
|
||||
if ${EGL_LIBS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
EGL_LIBS=`$PKG_CONFIG --libs egl 2>/dev/null`
|
||||
fi
|
||||
fi
|
||||
|
||||
EGL_LIBS=${EGL_LIBS:-"-lEGL"}
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: egl cflags: $EGL_CFLAGS" >&5
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: egl libs: $EGL_LIBS" >&5
|
||||
if test -s conftest.err; then
|
||||
printf %s "$as_me:${as_lineno-$LINENO}: egl errors: " >&5
|
||||
cat conftest.err >&5
|
||||
fi
|
||||
rm -f conftest.err
|
||||
ac_save_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $EGL_CFLAGS"
|
||||
ac_fn_c_check_header_compile "$LINENO" "EGL/egl.h" "ac_cv_header_EGL_egl_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_EGL_egl_h" = xyes
|
||||
then :
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -lEGL" >&5
|
||||
printf %s "checking for -lEGL... " >&6; }
|
||||
if test ${ac_cv_lib_soname_EGL+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_check_soname_save_LIBS=$LIBS
|
||||
LIBS="-lEGL $EGL_LIBS $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char eglGetProcAddress ();
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return eglGetProcAddress ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
case "$LIBEXT" in
|
||||
dll) ac_cv_lib_soname_EGL=`$ac_cv_path_LDD conftest.exe | grep "EGL" | sed -e "s/dll.*/dll/"';2,$d'` ;;
|
||||
dylib) ac_cv_lib_soname_EGL=`$OTOOL -L conftest$ac_exeext | grep "libEGL\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libEGL\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;;
|
||||
*) ac_cv_lib_soname_EGL=`$READELF -d conftest$ac_exeext | grep "NEEDED.*libEGL\\.$LIBEXT" | sed -e "s/^.*\\[\\(libEGL\\.$LIBEXT[^ ]*\\)\\].*$/\1/"';2,$d'`
|
||||
if ${ac_cv_lib_soname_EGL:+false} :
|
||||
then :
|
||||
ac_cv_lib_soname_EGL=`$LDD conftest$ac_exeext | grep "libEGL\\.$LIBEXT" | sed -e "s/^.*\(libEGL\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'`
|
||||
fi ;;
|
||||
esac
|
||||
else $as_nop
|
||||
ac_cv_lib_soname_EGL=
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_soname_save_LIBS
|
||||
fi
|
||||
if ${ac_cv_lib_soname_EGL:+false} :
|
||||
then :
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
printf "%s\n" "not found" >&6; }
|
||||
|
||||
else $as_nop
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_EGL" >&5
|
||||
printf "%s\n" "$ac_cv_lib_soname_EGL" >&6; }
|
||||
|
||||
printf "%s\n" "#define SONAME_LIBEGL \"$ac_cv_lib_soname_EGL\"" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS=$ac_save_CPPFLAGS
|
||||
|
||||
rm -f conftest.err
|
||||
if ${WAYLAND_EGL_CFLAGS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
WAYLAND_EGL_CFLAGS=`$PKG_CONFIG --cflags wayland-egl 2>conftest.err`
|
||||
fi
|
||||
fi
|
||||
|
||||
if ${WAYLAND_EGL_LIBS:+false} :
|
||||
then :
|
||||
if test ${PKG_CONFIG+y}
|
||||
then :
|
||||
WAYLAND_EGL_LIBS=`$PKG_CONFIG --libs wayland-egl 2>/dev/null`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-egl cflags: $WAYLAND_EGL_CFLAGS" >&5
|
||||
printf "%s\n" "$as_me:${as_lineno-$LINENO}: wayland-egl libs: $WAYLAND_EGL_LIBS" >&5
|
||||
if test -s conftest.err; then
|
||||
printf %s "$as_me:${as_lineno-$LINENO}: wayland-egl errors: " >&5
|
||||
cat conftest.err >&5
|
||||
fi
|
||||
rm -f conftest.err
|
||||
ac_save_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $WAYLAND_EGL_CFLAGS"
|
||||
ac_fn_c_check_header_compile "$LINENO" "wayland-egl.h" "ac_cv_header_wayland_egl_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_wayland_egl_h" = xyes
|
||||
then :
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wl_egl_window_create in -lwayland-egl" >&5
|
||||
printf %s "checking for wl_egl_window_create in -lwayland-egl... " >&6; }
|
||||
if test ${ac_cv_lib_wayland_egl_wl_egl_window_create+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lwayland-egl $WAYLAND_EGL_LIBS $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char wl_egl_window_create ();
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return wl_egl_window_create ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_lib_wayland_egl_wl_egl_window_create=yes
|
||||
else $as_nop
|
||||
ac_cv_lib_wayland_egl_wl_egl_window_create=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wayland_egl_wl_egl_window_create" >&5
|
||||
printf "%s\n" "$ac_cv_lib_wayland_egl_wl_egl_window_create" >&6; }
|
||||
if test "x$ac_cv_lib_wayland_egl_wl_egl_window_create" = xyes
|
||||
then :
|
||||
|
||||
printf "%s\n" "#define HAVE_LIBWAYLAND_EGL 1" >>confdefs.h
|
||||
|
||||
else $as_nop
|
||||
WAYLAND_EGL_LIBS=""
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
CPPFLAGS=$ac_save_CPPFLAGS
|
||||
|
||||
if test "x$with_wayland" != "x"
|
||||
then
|
||||
if test -z "$ac_cv_lib_soname_EGL" -o "$ac_cv_lib_wayland_egl_wl_egl_window_create" != yes
|
||||
then :
|
||||
case "x$with_opengl" in
|
||||
x) as_fn_append wine_notices "|EGL ${notice_platform}development files not found, the Wayland driver won't support OpenGL" ;;
|
||||
xno) ;;
|
||||
*) as_fn_error $? "EGL ${notice_platform}development files not found, the Wayland driver won't support OpenGL
|
||||
This is an error since --with-opengl was requested." "$LINENO" 5 ;;
|
||||
esac
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o -z "$XKBREGISTRY_LIBS" -o "$ac_cv_header_linux_input_h" = "no"
|
||||
then :
|
||||
|
@ -18949,6 +19167,7 @@ printf "%s\n" "$ac_cv_lib_soname_MoltenVK" >&6; }
|
|||
|
||||
printf "%s\n" "#define SONAME_LIBMOLTENVK \"$ac_cv_lib_soname_MoltenVK\"" >>confdefs.h
|
||||
|
||||
printf "%s\n" "#define SONAME_LIBVULKAN \"$ac_cv_lib_soname_MoltenVK\"" >>confdefs.h
|
||||
|
||||
fi
|
||||
fi
|
||||
|
@ -19503,6 +19722,35 @@ then :
|
|||
EXTRACFLAGS="$EXTRACFLAGS -Wwrite-strings"
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -flarge-source-files -Wmisleading-indentation" >&5
|
||||
printf %s "checking whether the compiler supports -flarge-source-files -Wmisleading-indentation... " >&6; }
|
||||
if test ${ac_cv_cflags__flarge_source_files__Wmisleading_indentation+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_wine_try_cflags_saved=$CFLAGS
|
||||
CFLAGS="$CFLAGS -flarge-source-files -Wmisleading-indentation"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
int main(int argc, char **argv) { return 0; }
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_cflags__flarge_source_files__Wmisleading_indentation=yes
|
||||
else $as_nop
|
||||
ac_cv_cflags__flarge_source_files__Wmisleading_indentation=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CFLAGS=$ac_wine_try_cflags_saved
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags__flarge_source_files__Wmisleading_indentation" >&5
|
||||
printf "%s\n" "$ac_cv_cflags__flarge_source_files__Wmisleading_indentation" >&6; }
|
||||
if test "x$ac_cv_cflags__flarge_source_files__Wmisleading_indentation" = xyes
|
||||
then :
|
||||
EXTRACFLAGS="$EXTRACFLAGS -Wno-misleading-indentation"
|
||||
fi
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wpointer-arith" >&5
|
||||
printf %s "checking whether the compiler supports -Wpointer-arith... " >&6; }
|
||||
if test ${ac_cv_cflags__Wpointer_arith+y}
|
||||
|
@ -20784,19 +21032,6 @@ printf "%s\n" "#define HAVE_LINUX_GETHOSTBYNAME_R_6 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrights" "ac_cv_member_struct_msghdr_msg_accrights" "#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
# include <sys/un.h>
|
||||
#endif
|
||||
"
|
||||
if test "x$ac_cv_member_struct_msghdr_msg_accrights" = xyes
|
||||
then :
|
||||
|
||||
printf "%s\n" "#define HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS 1" >>confdefs.h
|
||||
|
||||
|
||||
fi
|
||||
ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" "#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
@ -21554,6 +21789,32 @@ fi ;;
|
|||
esac
|
||||
|
||||
|
||||
enable_win16=${enable_win16:-i386}
|
||||
enable_vcruntime140_1=${enable_vcruntime140_1:-x86_64,arm64ec}
|
||||
|
||||
if test -n "$PE_ARCHS"
|
||||
then
|
||||
enable_wow64=${enable_wow64:-aarch64,x86_64}
|
||||
enable_wow64win=${enable_wow64win:-aarch64,x86_64}
|
||||
enable_wow64cpu=${enable_wow64cpu:-x86_64}
|
||||
else
|
||||
enable_wow64=${enable_wow64:-no}
|
||||
enable_wow64win=${enable_wow64win:-no}
|
||||
enable_wow64cpu=${enable_wow64cpu:-no}
|
||||
fi
|
||||
|
||||
enable_cmd=${enable_cmd:-yes}
|
||||
enable_dllhost=${enable_dllhost:-yes}
|
||||
enable_dpnsvr=${enable_dpnsvr:-i386,x86_64,arm64ec}
|
||||
enable_dxdiag=${enable_dxdiag:-yes}
|
||||
enable_msiexec=${enable_msiexec:-yes}
|
||||
enable_netsh=${enable_netsh:-yes}
|
||||
enable_regsvr32=${enable_regsvr32:-yes}
|
||||
enable_rundll32=${enable_rundll32:-yes}
|
||||
|
||||
enable_winetest=${enable_winetest:-$enable_tests}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -21975,6 +22236,7 @@ wine_fn_config_makefile dlls/mmdevapi/tests enable_tests
|
|||
wine_fn_config_makefile dlls/mmdevldr.vxd enable_win16
|
||||
wine_fn_config_makefile dlls/mmsystem.dll16 enable_win16
|
||||
wine_fn_config_makefile dlls/monodebg.vxd enable_win16
|
||||
wine_fn_config_makefile dlls/mouhid.sys enable_mouhid_sys
|
||||
wine_fn_config_makefile dlls/mountmgr.sys enable_mountmgr_sys
|
||||
wine_fn_config_makefile dlls/mouse.drv16 enable_win16
|
||||
wine_fn_config_makefile dlls/mp3dmod enable_mp3dmod
|
||||
|
@ -22405,6 +22667,8 @@ wine_fn_config_makefile dlls/windows.networking.hostname/tests enable_tests
|
|||
wine_fn_config_makefile dlls/windows.networking enable_windows_networking
|
||||
wine_fn_config_makefile dlls/windows.perception.stub enable_windows_perception_stub
|
||||
wine_fn_config_makefile dlls/windows.perception.stub/tests enable_tests
|
||||
wine_fn_config_makefile dlls/windows.security.authentication.onlineid enable_windows_security_authentication_onlineid
|
||||
wine_fn_config_makefile dlls/windows.security.authentication.onlineid/tests enable_tests
|
||||
wine_fn_config_makefile dlls/windows.security.credentials.ui.userconsentverifier enable_windows_security_credentials_ui_userconsentverifier
|
||||
wine_fn_config_makefile dlls/windows.security.credentials.ui.userconsentverifier/tests enable_tests
|
||||
wine_fn_config_makefile dlls/windows.storage.applicationdata enable_windows_storage_applicationdata
|
||||
|
@ -23360,7 +23624,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by Wine $as_me 9.2, which was
|
||||
This file was extended by Wine $as_me 9.5, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -23424,7 +23688,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
Wine config.status 9.2
|
||||
Wine config.status 9.5
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
@ -23765,6 +24029,10 @@ XKBCOMMON_CFLAGS = $XKBCOMMON_CFLAGS
|
|||
XKBCOMMON_LIBS = $XKBCOMMON_LIBS
|
||||
XKBREGISTRY_CFLAGS = $XKBREGISTRY_CFLAGS
|
||||
XKBREGISTRY_LIBS = $XKBREGISTRY_LIBS
|
||||
EGL_CFLAGS = $EGL_CFLAGS
|
||||
EGL_LIBS = $EGL_LIBS
|
||||
WAYLAND_EGL_CFLAGS = $WAYLAND_EGL_CFLAGS
|
||||
WAYLAND_EGL_LIBS = $WAYLAND_EGL_LIBS
|
||||
PCAP_LIBS = $PCAP_LIBS
|
||||
PCSCLITE_LIBS = $PCSCLITE_LIBS
|
||||
INOTIFY_CFLAGS = $INOTIFY_CFLAGS
|
||||
|
|
112
configure.ac
112
configure.ac
|
@ -29,7 +29,6 @@ AC_ARG_WITH(capi, AS_HELP_STRING([--without-capi],[do not use CAPI (ISDN su
|
|||
AC_ARG_WITH(coreaudio, AS_HELP_STRING([--without-coreaudio],[do not use the CoreAudio sound support]))
|
||||
AC_ARG_WITH(cups, AS_HELP_STRING([--without-cups],[do not use CUPS]))
|
||||
AC_ARG_WITH(dbus, AS_HELP_STRING([--without-dbus],[do not use DBus (dynamic device support)]))
|
||||
AC_ARG_WITH(float-abi, AS_HELP_STRING([--with-float-abi=abi],[specify the ABI (soft|softfp|hard) for ARM platforms]))
|
||||
AC_ARG_WITH(fontconfig,AS_HELP_STRING([--without-fontconfig],[do not use fontconfig]))
|
||||
AC_ARG_WITH(freetype, AS_HELP_STRING([--without-freetype],[do not use the FreeType library]))
|
||||
AC_ARG_WITH(gettext, AS_HELP_STRING([--without-gettext],[do not use gettext]))
|
||||
|
@ -146,58 +145,15 @@ case $host in
|
|||
if test x"$wine_cv_thumb2" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -mthumb"
|
||||
TARGETFLAGS="$TARGETFLAGS -mthumb"
|
||||
else
|
||||
CFLAGS="$CFLAGS -marm"
|
||||
TARGETFLAGS="$TARGETFLAGS -marm"
|
||||
fi
|
||||
case $with_float_abi in
|
||||
soft|softfp|hard)
|
||||
float_abi=$with_float_abi ;;
|
||||
*)
|
||||
case $host_os in
|
||||
*eabihf)
|
||||
float_abi=hard ;;
|
||||
*)
|
||||
float_abi=softfp
|
||||
saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -mfloat-abi=$float_abi"
|
||||
AC_CACHE_CHECK([whether $CC supports -mfloat-abi=$float_abi],wine_cv_float_abi,
|
||||
[WINE_TRY_ASM_LINK(["vmrs r2,fpscr"],,,[wine_cv_float_abi=yes],[wine_cv_float_abi=no])])
|
||||
if test $wine_cv_float_abi = no
|
||||
then
|
||||
float_abi=soft
|
||||
WINE_WARNING([Floating point is not supported for this target. The resulting build won't be compatible with Windows ARM binaries.])
|
||||
fi
|
||||
CFLAGS=$saved_CFLAGS
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
CFLAGS="$CFLAGS -mfloat-abi=$float_abi"
|
||||
TARGETFLAGS="$TARGETFLAGS -mfloat-abi=$float_abi"
|
||||
AC_CACHE_CHECK([whether $CC supports floating point instructions],wine_cv_float_abi,
|
||||
[WINE_TRY_ASM_LINK(["vmrs r2,fpscr"],,,[wine_cv_float_abi=yes],[wine_cv_float_abi=no])])
|
||||
test $wine_cv_float_abi != no || AC_MSG_ERROR([The ARM target needs to support floating point instructions.])
|
||||
;;
|
||||
esac
|
||||
|
||||
enable_win16=${enable_win16:-i386}
|
||||
enable_win64=${enable_win64:-no}
|
||||
enable_wow64=${enable_wow64:-aarch64,x86_64}
|
||||
enable_wow64win=${enable_wow64win:-aarch64,x86_64}
|
||||
enable_wow64cpu=${enable_wow64cpu:-x86_64}
|
||||
enable_vcruntime140_1=${enable_vcruntime140_1:-x86_64,arm64ec}
|
||||
|
||||
dnl Explicitly enable some programs for arm64ec
|
||||
enable_cmd=${enable_cmd:-yes}
|
||||
enable_dllhost=${enable_dllhost:-yes}
|
||||
enable_dpnsvr=${enable_dpnsvr:-i386,x86_64,arm64ec}
|
||||
enable_dxdiag=${enable_dxdiag:-yes}
|
||||
enable_msiexec=${enable_msiexec:-yes}
|
||||
enable_netsh=${enable_netsh:-yes}
|
||||
enable_regsvr32=${enable_regsvr32:-yes}
|
||||
enable_rundll32=${enable_rundll32:-yes}
|
||||
|
||||
dnl Disable winetest too if tests are disabled
|
||||
enable_winetest=${enable_winetest:-$enable_tests}
|
||||
|
||||
dnl Some special cases for the 64-bit build
|
||||
if test "x$enable_win64" = "xyes"
|
||||
then
|
||||
|
@ -990,7 +946,10 @@ This is an error since --enable-archs=$wine_arch was requested.])])
|
|||
WINE_TRY_PE_CFLAGS([-Wpointer-arith])
|
||||
WINE_TRY_PE_CFLAGS([-Wlogical-op])
|
||||
WINE_TRY_PE_CFLAGS([-Wabsolute-value])
|
||||
WINE_TRY_PE_CFLAGS([-Wenum-conversion])
|
||||
WINE_TRY_PE_CFLAGS([-Wenum-enum-conversion],[:],WINE_TRY_PE_CFLAGS([-Wenum-conversion]))
|
||||
|
||||
dnl GCC can't handle large files when -Wmisleading-indentation is enabled (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549)
|
||||
WINE_TRY_PE_CFLAGS([-flarge-source-files -Wmisleading-indentation],[AS_VAR_APPEND(${wine_arch}_EXTRACFLAGS,[" -Wno-misleading-indentation"])])
|
||||
|
||||
case $wine_arch in
|
||||
i386) WINE_TRY_PE_CFLAGS([-fno-omit-frame-pointer])
|
||||
|
@ -1186,7 +1145,7 @@ WINE_EXTLIB_FLAGS(JPEG, jpeg, jpeg, "-I\$(top_srcdir)/libs/jpeg")
|
|||
WINE_EXTLIB_FLAGS(JXR, jxr, jxr, "-I\$(top_srcdir)/libs/jxr/jxrgluelib -I\$(top_srcdir)/libs/jxr/image/sys")
|
||||
WINE_EXTLIB_FLAGS(LCMS2, lcms2, lcms2, "-I\$(top_srcdir)/libs/lcms2/include")
|
||||
WINE_EXTLIB_FLAGS(LDAP, ldap, ldap, "-I\$(top_srcdir)/libs/ldap/include")
|
||||
WINE_EXTLIB_FLAGS(MPG123, mpg123, mpg123, "-I\$(top_srcdir)/libs/mpg123/src/libmpg123")
|
||||
WINE_EXTLIB_FLAGS(MPG123, mpg123, mpg123, "-I\$(top_srcdir)/libs/mpg123/src/include")
|
||||
WINE_EXTLIB_FLAGS(MUSL, musl, musl)
|
||||
WINE_EXTLIB_FLAGS(PNG, png, "png \$(ZLIB_PE_LIBS)", "-I\$(top_srcdir)/libs/png")
|
||||
WINE_EXTLIB_FLAGS(TIFF, tiff, "tiff \$(ZLIB_PE_LIBS)", "-I\$(top_srcdir)/libs/tiff/libtiff")
|
||||
|
@ -1401,6 +1360,22 @@ then
|
|||
WINE_PACKAGE_FLAGS(XKBREGISTRY,[xkbregistry],,,,
|
||||
[AC_CHECK_HEADERS([xkbcommon/xkbregistry.h])
|
||||
AC_CHECK_LIB(xkbregistry,rxkb_context_new,[:],[XKBREGISTRY_LIBS=""],[$XKBREGISTRY_LIBS])])
|
||||
if test "x$with_opengl" != "xno"
|
||||
then
|
||||
WINE_PACKAGE_FLAGS(EGL,[egl],[-lEGL],,,
|
||||
[AC_CHECK_HEADER([EGL/egl.h],
|
||||
[WINE_CHECK_SONAME(EGL,eglGetProcAddress,,,[$EGL_LIBS])])])
|
||||
WINE_PACKAGE_FLAGS(WAYLAND_EGL,[wayland-egl],,,,
|
||||
[AC_CHECK_HEADER([wayland-egl.h],
|
||||
[AC_CHECK_LIB(wayland-egl,wl_egl_window_create,
|
||||
[AC_DEFINE(HAVE_LIBWAYLAND_EGL, 1, [Define if we have the wayland-egl development environment])],
|
||||
[WAYLAND_EGL_LIBS=""],[$WAYLAND_EGL_LIBS])])])
|
||||
if test "x$with_wayland" != "x"
|
||||
then
|
||||
WINE_NOTICE_WITH(opengl, [test -z "$ac_cv_lib_soname_EGL" -o "$ac_cv_lib_wayland_egl_wl_egl_window_create" != yes],
|
||||
[EGL ${notice_platform}development files not found, the Wayland driver won't support OpenGL])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o -z "$XKBREGISTRY_LIBS" -o "$ac_cv_header_linux_input_h" = "no"],
|
||||
[Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.],
|
||||
|
@ -1852,7 +1827,7 @@ then
|
|||
WINE_CHECK_SONAME(vulkan, vkGetInstanceProcAddr)
|
||||
if test "x$ac_cv_lib_soname_vulkan" = "x"
|
||||
then
|
||||
WINE_CHECK_SONAME(MoltenVK, vkGetInstanceProcAddr)
|
||||
WINE_CHECK_SONAME(MoltenVK, vkGetInstanceProcAddr, [AC_DEFINE_UNQUOTED(SONAME_LIBVULKAN,["$ac_cv_lib_soname_MoltenVK"])])
|
||||
fi
|
||||
fi
|
||||
WINE_NOTICE_WITH(vulkan,[test "x$ac_cv_lib_soname_vulkan" = "x" -a "x$ac_cv_lib_soname_MoltenVK" = "x"],
|
||||
|
@ -1887,6 +1862,9 @@ then
|
|||
WINE_TRY_CFLAGS([-Wvla])
|
||||
WINE_TRY_CFLAGS([-Wwrite-strings])
|
||||
|
||||
dnl GCC can't handle large files when -Wmisleading-indentation is enabled (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549)
|
||||
WINE_TRY_CFLAGS([-flarge-source-files -Wmisleading-indentation],[EXTRACFLAGS="$EXTRACFLAGS -Wno-misleading-indentation"])
|
||||
|
||||
dnl Check for noisy string.h
|
||||
WINE_TRY_CFLAGS([-Wpointer-arith],
|
||||
[saved_string_h_CFLAGS=$CFLAGS
|
||||
|
@ -2165,7 +2143,7 @@ AC_CACHE_CHECK([whether we can use re-entrant gethostbyname_r Linux style],
|
|||
fi
|
||||
|
||||
dnl Check for socket structure members
|
||||
AC_CHECK_MEMBERS([struct msghdr.msg_accrights, struct sockaddr_un.sun_len],,,
|
||||
AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
@ -2373,6 +2351,35 @@ case $host_vendor in
|
|||
*sun*) WINE_CHECK_DEFINE([__sun__]) ;;
|
||||
esac
|
||||
|
||||
dnl *** Check for modules to disable by default
|
||||
|
||||
enable_win16=${enable_win16:-i386}
|
||||
enable_vcruntime140_1=${enable_vcruntime140_1:-x86_64,arm64ec}
|
||||
|
||||
if test -n "$PE_ARCHS"
|
||||
then
|
||||
enable_wow64=${enable_wow64:-aarch64,x86_64}
|
||||
enable_wow64win=${enable_wow64win:-aarch64,x86_64}
|
||||
enable_wow64cpu=${enable_wow64cpu:-x86_64}
|
||||
else
|
||||
enable_wow64=${enable_wow64:-no}
|
||||
enable_wow64win=${enable_wow64win:-no}
|
||||
enable_wow64cpu=${enable_wow64cpu:-no}
|
||||
fi
|
||||
|
||||
dnl Explicitly enable some programs for arm64ec
|
||||
enable_cmd=${enable_cmd:-yes}
|
||||
enable_dllhost=${enable_dllhost:-yes}
|
||||
enable_dpnsvr=${enable_dpnsvr:-i386,x86_64,arm64ec}
|
||||
enable_dxdiag=${enable_dxdiag:-yes}
|
||||
enable_msiexec=${enable_msiexec:-yes}
|
||||
enable_netsh=${enable_netsh:-yes}
|
||||
enable_regsvr32=${enable_regsvr32:-yes}
|
||||
enable_rundll32=${enable_rundll32:-yes}
|
||||
|
||||
dnl Disable winetest too if tests are disabled
|
||||
enable_winetest=${enable_winetest:-$enable_tests}
|
||||
|
||||
dnl **** Generate output files ****
|
||||
|
||||
AH_TOP([#ifndef __WINE_CONFIG_H
|
||||
|
@ -2792,6 +2799,7 @@ WINE_CONFIG_MAKEFILE(dlls/mmdevapi/tests)
|
|||
WINE_CONFIG_MAKEFILE(dlls/mmdevldr.vxd,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(dlls/mmsystem.dll16,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(dlls/monodebg.vxd,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(dlls/mouhid.sys)
|
||||
WINE_CONFIG_MAKEFILE(dlls/mountmgr.sys)
|
||||
WINE_CONFIG_MAKEFILE(dlls/mouse.drv16,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(dlls/mp3dmod)
|
||||
|
@ -3222,6 +3230,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.networking.hostname/tests)
|
|||
WINE_CONFIG_MAKEFILE(dlls/windows.networking)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.perception.stub)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.perception.stub/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.security.authentication.onlineid)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.security.authentication.onlineid/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.security.credentials.ui.userconsentverifier)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.security.credentials.ui.userconsentverifier/tests)
|
||||
WINE_CONFIG_MAKEFILE(dlls/windows.storage.applicationdata)
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
threading(both),
|
||||
uuid(b8da6310-e19b-11d0-933c-00a0c90dcaa9) /* IActiveScriptStats */
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
|
|
@ -70,6 +70,9 @@ LSTATUS WINAPI RegOverridePredefKey( HKEY hkey, HKEY override )
|
|||
*/
|
||||
LSTATUS WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR lpSubKey, PHKEY phkResult )
|
||||
{
|
||||
if (!phkResult)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return RegCreateKeyExW( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
|
||||
MAXIMUM_ALLOWED, NULL, phkResult, NULL );
|
||||
}
|
||||
|
@ -82,6 +85,9 @@ LSTATUS WINAPI RegCreateKeyW( HKEY hkey, LPCWSTR lpSubKey, PHKEY phkResult )
|
|||
*/
|
||||
LSTATUS WINAPI RegCreateKeyA( HKEY hkey, LPCSTR lpSubKey, PHKEY phkResult )
|
||||
{
|
||||
if (!phkResult)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return RegCreateKeyExA( hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,
|
||||
MAXIMUM_ALLOWED, NULL, phkResult, NULL );
|
||||
}
|
||||
|
|
|
@ -1260,10 +1260,10 @@ static void test_container_sd(void)
|
|||
ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %lu\n", err);
|
||||
ok(len, "expected len > 0\n");
|
||||
|
||||
sd = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
sd = malloc(len);
|
||||
ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, (BYTE *)sd, &len, OWNER_SECURITY_INFORMATION);
|
||||
ok(ret, "got %lu\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, sd);
|
||||
free(sd);
|
||||
|
||||
ret = CryptReleaseContext(prov, 0);
|
||||
ok(ret, "got %lu\n", GetLastError());
|
||||
|
|
|
@ -445,14 +445,14 @@ static void test_read(void)
|
|||
todo_wine
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
|
||||
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
|
||||
buf = malloc(sizeof(EVENTLOGRECORD));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
|
||||
0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
|
||||
ok(!ret, "Expected failure\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
|
||||
handle = OpenEventLogA(NULL, "Application");
|
||||
if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE))
|
||||
|
@ -463,7 +463,7 @@ static void test_read(void)
|
|||
ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError());
|
||||
|
||||
/* Show that we need the proper dwFlags with a (for the rest) proper call */
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
|
||||
buf = malloc(sizeof(EVENTLOGRECORD));
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
|
||||
|
@ -504,7 +504,7 @@ static void test_read(void)
|
|||
todo_wine
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
|
||||
/* First check if there are any records (in practice only on Wine: FIXME) */
|
||||
count = 0;
|
||||
|
@ -517,7 +517,7 @@ static void test_read(void)
|
|||
}
|
||||
|
||||
/* Get the buffer size for the first record */
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
|
||||
buf = malloc(sizeof(EVENTLOGRECORD));
|
||||
read = needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
|
||||
|
@ -529,7 +529,7 @@ static void test_read(void)
|
|||
|
||||
/* Read the first record */
|
||||
toread = needed;
|
||||
buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread);
|
||||
buf = realloc(buf, toread);
|
||||
read = needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, toread, &read, &needed);
|
||||
|
@ -538,7 +538,7 @@ static void test_read(void)
|
|||
broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record */
|
||||
"Expected the requested size to be read\n");
|
||||
ok(needed == 0, "Expected no extra bytes to be read\n");
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
|
||||
CloseEventLog(handle);
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ static void test_readwrite(void)
|
|||
if (pCreateWellKnownSid)
|
||||
{
|
||||
sidsize = SECURITY_MAX_SID_SIZE;
|
||||
user = HeapAlloc(GetProcessHeap(), 0, sidsize);
|
||||
user = malloc(sidsize);
|
||||
SetLastError(0xdeadbeef);
|
||||
pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize);
|
||||
sidavailable = TRUE;
|
||||
|
@ -846,12 +846,12 @@ static void test_readwrite(void)
|
|||
ok(ret, "Expected success : %ld\n", GetLastError());
|
||||
|
||||
/* Needed to catch earlier Vista (with no ServicePack for example) */
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
|
||||
buf = malloc(sizeof(EVENTLOGRECORD));
|
||||
if (!(ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
|
||||
0, buf, sizeof(EVENTLOGRECORD), &read, &needed)) &&
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
|
||||
buf = realloc(buf, needed);
|
||||
ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
|
||||
0, buf, needed, &read, &needed);
|
||||
}
|
||||
|
@ -865,7 +865,7 @@ static void test_readwrite(void)
|
|||
if (record->EventType == EVENTLOG_SUCCESS)
|
||||
on_vista = TRUE;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* This will clear the eventlog. The record numbering for new
|
||||
|
@ -949,13 +949,13 @@ static void test_readwrite(void)
|
|||
size = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size);
|
||||
localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
localcomputer = malloc(size);
|
||||
pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
localcomputer = malloc(size);
|
||||
GetComputerNameA(localcomputer, &size);
|
||||
}
|
||||
|
||||
|
@ -964,7 +964,7 @@ static void test_readwrite(void)
|
|||
ok(handle != NULL, "OpenEventLogA(%s) failed : %ld\n", eventlogname, GetLastError());
|
||||
i = 0;
|
||||
size = sizeof(EVENTLOGRECORD) + 128;
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
buf = malloc(size);
|
||||
for (;;)
|
||||
{
|
||||
DWORD read, needed;
|
||||
|
@ -989,9 +989,9 @@ static void test_readwrite(void)
|
|||
|
||||
if (needed > size)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
size = needed;
|
||||
buf = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
buf = malloc(size);
|
||||
}
|
||||
ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
|
||||
0, buf, needed, &read, &needed);
|
||||
|
@ -1069,7 +1069,7 @@ static void test_readwrite(void)
|
|||
winetest_pop_context();
|
||||
i++;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
free(buf);
|
||||
CloseEventLog(handle);
|
||||
|
||||
/* Test clearing a real eventlog */
|
||||
|
@ -1088,8 +1088,8 @@ static void test_readwrite(void)
|
|||
CloseEventLog(handle);
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, localcomputer);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
free(localcomputer);
|
||||
free(user);
|
||||
}
|
||||
|
||||
/* Before Vista:
|
||||
|
@ -1240,7 +1240,7 @@ static void test_start_trace(void)
|
|||
LONG ret;
|
||||
|
||||
buffersize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(sessionname) + sizeof(filepath);
|
||||
properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
|
||||
properties = calloc(1, buffersize);
|
||||
properties->Wnode.BufferSize = buffersize;
|
||||
properties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
|
||||
properties->LogFileMode = EVENT_TRACE_FILE_MODE_NONE;
|
||||
|
@ -1317,7 +1317,7 @@ static void test_start_trace(void)
|
|||
/* clean up */
|
||||
ControlTraceA(handle, sessionname, properties, EVENT_TRACE_CONTROL_STOP);
|
||||
done:
|
||||
HeapFree(GetProcessHeap(), 0, properties);
|
||||
free(properties);
|
||||
DeleteFileA(filepath);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,15 +243,15 @@ static void test_LsaLookupNames2(void)
|
|||
return;
|
||||
}
|
||||
|
||||
name[0].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1));
|
||||
name[0].Buffer = malloc(sizeof(n1));
|
||||
name[0].Length = name[0].MaximumLength = sizeof(n1);
|
||||
memcpy(name[0].Buffer, n1, sizeof(n1));
|
||||
|
||||
name[1].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1));
|
||||
name[1].Buffer = malloc(sizeof(n1));
|
||||
name[1].Length = name[1].MaximumLength = sizeof(n1) - sizeof(WCHAR);
|
||||
memcpy(name[1].Buffer, n1, sizeof(n1) - sizeof(WCHAR));
|
||||
|
||||
name[2].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n2));
|
||||
name[2].Buffer = malloc(sizeof(n2));
|
||||
name[2].Length = name[2].MaximumLength = sizeof(n2);
|
||||
memcpy(name[2].Buffer, n2, sizeof(n2));
|
||||
|
||||
|
@ -307,9 +307,9 @@ static void test_LsaLookupNames2(void)
|
|||
LsaFreeMemory(sids);
|
||||
LsaFreeMemory(domains);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, name[0].Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, name[1].Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, name[2].Buffer);
|
||||
free(name[0].Buffer);
|
||||
free(name[1].Buffer);
|
||||
free(name[2].Buffer);
|
||||
|
||||
status = LsaClose(handle);
|
||||
ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08lx\n", status);
|
||||
|
|
|
@ -195,7 +195,7 @@ static void _test_hkey_main_Value_A(int line, LPCSTR name, LPCSTR string,
|
|||
lok(type == REG_SZ, "RegQueryValueExA/1 returned type %ld\n", type);
|
||||
lok(cbData == full_byte_len, "cbData=%ld instead of %ld or %ld\n", cbData, full_byte_len, str_byte_len);
|
||||
|
||||
value = HeapAlloc(GetProcessHeap(), 0, cbData+1);
|
||||
value = malloc(cbData+1);
|
||||
memset(value, 0xbd, cbData+1);
|
||||
type=0xdeadbeef;
|
||||
ret = RegQueryValueExA(hkey_main, name, NULL, &type, value, &cbData);
|
||||
|
@ -213,7 +213,7 @@ static void _test_hkey_main_Value_A(int line, LPCSTR name, LPCSTR string,
|
|||
debugstr_an(string, full_byte_len), full_byte_len);
|
||||
lok(*(value+cbData) == 0xbd, "RegQueryValueExA/2 overflowed at offset %lu: %02x != bd\n", cbData, *(value+cbData));
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
#define test_hkey_main_Value_W(name, string, full_byte_len) _test_hkey_main_Value_W(__LINE__, name, string, full_byte_len)
|
||||
|
@ -243,7 +243,7 @@ static void _test_hkey_main_Value_W(int line, LPCWSTR name, LPCWSTR string,
|
|||
"cbData=%ld instead of %ld\n", cbData, full_byte_len);
|
||||
|
||||
/* Give enough space to overflow by one WCHAR */
|
||||
value = HeapAlloc(GetProcessHeap(), 0, cbData+2);
|
||||
value = malloc(cbData+2);
|
||||
memset(value, 0xbd, cbData+2);
|
||||
type=0xdeadbeef;
|
||||
ret = RegQueryValueExW(hkey_main, name, NULL, &type, value, &cbData);
|
||||
|
@ -258,7 +258,7 @@ static void _test_hkey_main_Value_W(int line, LPCWSTR name, LPCWSTR string,
|
|||
/* This implies that when cbData == 0, RegQueryValueExW() should not modify the buffer */
|
||||
lok(*(value+cbData) == 0xbd, "RegQueryValueExW/2 overflowed at %lu: %02x != bd\n", cbData, *(value+cbData));
|
||||
lok(*(value+cbData+1) == 0xbd, "RegQueryValueExW/2 overflowed at %lu+1: %02x != bd\n", cbData, *(value+cbData+1));
|
||||
HeapFree(GetProcessHeap(), 0, value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
static void test_set_value(void)
|
||||
|
@ -1218,7 +1218,7 @@ static void test_reg_open_key(void)
|
|||
ok(ret == ERROR_SUCCESS,
|
||||
"Expected SetEntriesInAclA to return ERROR_SUCCESS, got %lu, last error %lu\n", ret, GetLastError());
|
||||
|
||||
sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
sd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
ok(bRet == TRUE,
|
||||
"Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %lu\n", bRet, GetLastError());
|
||||
|
@ -1256,7 +1256,7 @@ static void test_reg_open_key(void)
|
|||
RegCloseKey(hkResult);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sd);
|
||||
free(sd);
|
||||
LocalFree(key_acl);
|
||||
FreeSid(world_sid);
|
||||
RegDeleteKeyA(hkRoot64, "");
|
||||
|
@ -1279,6 +1279,19 @@ static void test_reg_create_key(void)
|
|||
PACL key_acl;
|
||||
SECURITY_DESCRIPTOR *sd;
|
||||
|
||||
/* NULL return key check */
|
||||
ret = RegCreateKeyA(hkey_main, "Subkey1", NULL);
|
||||
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
|
||||
|
||||
ret = RegCreateKeyW(hkey_main, L"Subkey1", NULL);
|
||||
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
|
||||
|
||||
ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, NULL, NULL);
|
||||
ok(ret == ERROR_BADKEY, "Got unexpected ret %ld.\n", ret);
|
||||
|
||||
ret = RegCreateKeyExW(hkey_main, L"Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, NULL, NULL);
|
||||
ok(ret == ERROR_BADKEY, "Got unexpected ret %ld.\n", ret);
|
||||
|
||||
ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL);
|
||||
ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret);
|
||||
/* should succeed: all versions of Windows ignore the access rights
|
||||
|
@ -1380,7 +1393,7 @@ static void test_reg_create_key(void)
|
|||
ok(dwRet == ERROR_SUCCESS,
|
||||
"Expected SetEntriesInAclA to return ERROR_SUCCESS, got %lu, last error %lu\n", dwRet, GetLastError());
|
||||
|
||||
sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
sd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
ok(bRet == TRUE,
|
||||
"Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %lu\n", bRet, GetLastError());
|
||||
|
@ -1418,7 +1431,7 @@ static void test_reg_create_key(void)
|
|||
RegCloseKey(hkey1);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sd);
|
||||
free(sd);
|
||||
LocalFree(key_acl);
|
||||
FreeSid(world_sid);
|
||||
RegDeleteKeyA(hkRoot64, "");
|
||||
|
@ -1529,62 +1542,68 @@ static BOOL set_privileges(LPCSTR privilege, BOOL set)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_reg_save_key(void)
|
||||
static void delete_dir(const char *path)
|
||||
{
|
||||
DWORD ret;
|
||||
char file[2 * MAX_PATH], *p;
|
||||
WIN32_FIND_DATAA fd;
|
||||
HANDLE hfind;
|
||||
BOOL r;
|
||||
|
||||
if (!set_privileges(SE_BACKUP_NAME, TRUE) ||
|
||||
!set_privileges(SE_RESTORE_NAME, FALSE))
|
||||
strcpy(file, path);
|
||||
p = file + strlen(file);
|
||||
p[0] = '\\';
|
||||
p[1] = '*';
|
||||
p[2] = 0;
|
||||
hfind = FindFirstFileA(file, &fd);
|
||||
if (hfind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
win_skip("Failed to set SE_BACKUP_NAME privileges, skipping tests\n");
|
||||
return;
|
||||
do
|
||||
{
|
||||
if (!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, ".."))
|
||||
continue;
|
||||
|
||||
strcpy(p + 1, fd.cFileName);
|
||||
r = DeleteFileA(file);
|
||||
ok(r, "DeleteFile failed on %s: %ld\n", debugstr_a(file), GetLastError());
|
||||
} while(FindNextFileA(hfind, &fd));
|
||||
FindClose(hfind);
|
||||
}
|
||||
|
||||
ret = RegSaveKeyA(hkey_main, "saved_key", NULL);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
set_privileges(SE_BACKUP_NAME, FALSE);
|
||||
r = RemoveDirectoryA(path);
|
||||
ok(r, "RemoveDirectory failed: %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_reg_load_key(void)
|
||||
{
|
||||
DWORD ret;
|
||||
HKEY hkHandle;
|
||||
|
||||
if (!set_privileges(SE_RESTORE_NAME, TRUE) ||
|
||||
!set_privileges(SE_BACKUP_NAME, FALSE))
|
||||
{
|
||||
win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", "saved_key");
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
set_privileges(SE_RESTORE_NAME, FALSE);
|
||||
|
||||
ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &hkHandle);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
RegCloseKey(hkHandle);
|
||||
}
|
||||
|
||||
static void test_reg_unload_key(void)
|
||||
{
|
||||
char saved_key[2 * MAX_PATH], buf[16], *p;
|
||||
UNICODE_STRING key_name;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
DWORD ret;
|
||||
DWORD ret, size;
|
||||
HKEY key;
|
||||
|
||||
if (!set_privileges(SE_RESTORE_NAME, TRUE) ||
|
||||
!set_privileges(SE_BACKUP_NAME, FALSE))
|
||||
!set_privileges(SE_BACKUP_NAME, TRUE))
|
||||
{
|
||||
win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Test", 0, KEY_READ, &key);
|
||||
GetTempPathA(MAX_PATH, saved_key);
|
||||
strcat(saved_key, "\\wine_reg_test");
|
||||
CreateDirectoryA(saved_key, NULL);
|
||||
strcat(saved_key, "\\saved_key");
|
||||
|
||||
ret = RegSaveKeyA(hkey_main, saved_key, NULL);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", saved_key);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &key);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
ret = RegSetValueExA(key, "test", 0, REG_SZ, (BYTE *)"value", 6);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
/* try to unload though the key handle is live */
|
||||
|
@ -1598,6 +1617,27 @@ static void test_reg_unload_key(void)
|
|||
ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test");
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
/* check if modifications are saved */
|
||||
ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", saved_key);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &key);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
size = sizeof(buf);
|
||||
ret = RegGetValueA(key, NULL, "test", RRF_RT_REG_SZ, NULL, buf, &size);
|
||||
todo_wine ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
ok(size == 6, "size = %ld\n", size);
|
||||
ok(!strcmp(buf, "value"), "buf = %s\n", buf);
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
|
||||
ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test");
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
pRtlInitUnicodeString(&key_name, L"\\REGISTRY\\User\\.Default");
|
||||
InitializeObjectAttributes(&attr, &key_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
status = pNtUnloadKey(&attr);
|
||||
|
@ -1607,9 +1647,11 @@ static void test_reg_unload_key(void)
|
|||
ok(ret == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", ret);
|
||||
|
||||
set_privileges(SE_RESTORE_NAME, FALSE);
|
||||
set_privileges(SE_BACKUP_NAME, FALSE);
|
||||
|
||||
DeleteFileA("saved_key");
|
||||
DeleteFileA("saved_key.LOG");
|
||||
p = strrchr(saved_key, '\\');
|
||||
*p = 0;
|
||||
delete_dir(saved_key);
|
||||
}
|
||||
|
||||
/* Helper function to wait for a file blocked by the registry to be available */
|
||||
|
@ -1631,31 +1673,26 @@ static void wait_file_available(char *path)
|
|||
static void test_reg_load_app_key(void)
|
||||
{
|
||||
DWORD ret, size;
|
||||
char temppath[MAX_PATH], hivefilepath[MAX_PATH];
|
||||
char hivefilepath[2 * MAX_PATH], *p;
|
||||
const BYTE test_data[] = "Hello World";
|
||||
BYTE output[sizeof(test_data)];
|
||||
HKEY appkey = NULL;
|
||||
|
||||
GetTempPathA(sizeof(temppath), temppath);
|
||||
GetTempFileNameA(temppath, "key", 0, hivefilepath);
|
||||
DeleteFileA(hivefilepath);
|
||||
|
||||
if (!set_privileges(SE_BACKUP_NAME, TRUE) ||
|
||||
!set_privileges(SE_RESTORE_NAME, FALSE))
|
||||
if (!set_privileges(SE_BACKUP_NAME, TRUE))
|
||||
{
|
||||
win_skip("Failed to set SE_BACKUP_NAME privileges, skipping tests\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GetTempPathA(MAX_PATH, hivefilepath);
|
||||
strcat(hivefilepath, "\\wine_reg_test");
|
||||
CreateDirectoryA(hivefilepath, NULL);
|
||||
strcat(hivefilepath, "\\saved_key");
|
||||
|
||||
ret = RegSaveKeyA(hkey_main, hivefilepath, NULL);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
{
|
||||
win_skip("Failed to save test key 0x%lx\n", ret);
|
||||
return;
|
||||
}
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);
|
||||
|
||||
set_privileges(SE_BACKUP_NAME, FALSE);
|
||||
set_privileges(SE_RESTORE_NAME, FALSE);
|
||||
|
||||
/* Test simple key load */
|
||||
/* Check if the changes are saved */
|
||||
|
@ -1684,8 +1721,10 @@ static void test_reg_load_app_key(void)
|
|||
RegCloseKey(appkey);
|
||||
|
||||
wait_file_available(hivefilepath);
|
||||
ret = DeleteFileA(hivefilepath);
|
||||
ok(ret, "couldn't delete hive file %ld\n", GetLastError());
|
||||
|
||||
p = strrchr(hivefilepath, '\\');
|
||||
*p = 0;
|
||||
delete_dir(hivefilepath);
|
||||
}
|
||||
|
||||
/* tests that show that RegConnectRegistry and
|
||||
|
@ -2425,7 +2464,7 @@ static void test_symlinks(void)
|
|||
pRtlFormatCurrentUserKeyPath( &target_str );
|
||||
|
||||
target_len = target_str.Length + sizeof(targetW);
|
||||
target = HeapAlloc( GetProcessHeap(), 0, target_len );
|
||||
target = malloc( target_len );
|
||||
memcpy( target, target_str.Buffer, target_str.Length );
|
||||
memcpy( target + target_str.Length/sizeof(WCHAR), targetW, sizeof(targetW) );
|
||||
|
||||
|
@ -2530,7 +2569,7 @@ static void test_symlinks(void)
|
|||
ok( !status, "NtDeleteKey failed: 0x%08lx\n", status );
|
||||
RegCloseKey( link );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, target );
|
||||
free( target );
|
||||
pRtlFreeUnicodeString( &target_str );
|
||||
}
|
||||
|
||||
|
@ -2778,6 +2817,28 @@ static void test_redirection(void)
|
|||
RegCloseKey( root32 );
|
||||
RegCloseKey( root64 );
|
||||
|
||||
err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\WOW6432Node\\test1\\test2", 0, NULL, 0,
|
||||
KEY_WRITE | KEY_WOW64_32KEY, NULL, &key, NULL );
|
||||
ok(!err, "got %#lx.\n", err);
|
||||
RegCloseKey(key);
|
||||
|
||||
err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\test1\\test2", 0, NULL, 0, KEY_WRITE | KEY_WOW64_32KEY,
|
||||
NULL, &key, NULL );
|
||||
ok(!err, "got %#lx.\n", err);
|
||||
RegCloseKey(key);
|
||||
|
||||
err = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\test1\\test2", 0, KEY_WRITE | KEY_WOW64_32KEY, &key );
|
||||
ok(!err, "got %#lx.\n", err);
|
||||
RegCloseKey(key);
|
||||
|
||||
if (pRegDeleteTreeA)
|
||||
{
|
||||
err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\\WOW6432Node\\test1");
|
||||
ok(!err, "got %#lx.\n", err);
|
||||
err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\\test1");
|
||||
ok(err == ERROR_FILE_NOT_FOUND, "got %#lx.\n", err);
|
||||
}
|
||||
|
||||
/* Software\Classes is shared/reflected so behavior is different */
|
||||
|
||||
err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine",
|
||||
|
@ -4951,9 +5012,7 @@ START_TEST(registry)
|
|||
test_classesroot();
|
||||
test_classesroot_enum();
|
||||
test_classesroot_mask();
|
||||
test_reg_save_key();
|
||||
test_reg_load_key();
|
||||
test_reg_unload_key();
|
||||
test_reg_load_app_key();
|
||||
test_reg_copy_tree();
|
||||
test_reg_delete_tree();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1000,14 +1000,14 @@ static void test_query_svc(void)
|
|||
}
|
||||
|
||||
/* Pass a correct buffer and buffersize but a NULL handle */
|
||||
statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
|
||||
statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS));
|
||||
bufsize = needed;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
|
||||
ok(!ret, "Expected failure\n");
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE,
|
||||
"Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, statusproc);
|
||||
free(statusproc);
|
||||
|
||||
/* Correct handle and info level */
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -1023,21 +1023,21 @@ static void test_query_svc(void)
|
|||
}
|
||||
|
||||
/* All parameters are OK but we don't have enough rights */
|
||||
statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
|
||||
statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS));
|
||||
bufsize = sizeof(SERVICE_STATUS_PROCESS);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
|
||||
ok(!ret, "Expected failure\n");
|
||||
ok(GetLastError() == ERROR_ACCESS_DENIED,
|
||||
"Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, statusproc);
|
||||
free(statusproc);
|
||||
|
||||
/* Open the service with just enough rights. */
|
||||
CloseServiceHandle(svc_handle);
|
||||
svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
|
||||
|
||||
/* Everything should be fine now. */
|
||||
statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
|
||||
statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS));
|
||||
bufsize = sizeof(SERVICE_STATUS_PROCESS);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
|
||||
|
@ -1056,7 +1056,7 @@ static void test_query_svc(void)
|
|||
ok(broken(GetLastError() == ERROR_INVALID_PARAMETER) /* NT4 */ ||
|
||||
GetLastError() == ERROR_INVALID_ADDRESS, "got %ld\n", GetLastError());
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, statusproc);
|
||||
free(statusproc);
|
||||
|
||||
CloseServiceHandle(svc_handle);
|
||||
CloseServiceHandle(scm_handle);
|
||||
|
@ -1274,14 +1274,14 @@ static BOOL test_enum_svc(int attempt)
|
|||
tempneeded = needed;
|
||||
|
||||
/* Allocate the correct needed bytes */
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
bufsize = needed;
|
||||
needed = 0xdeadbeef;
|
||||
returned = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
services, bufsize, &needed, &returned, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
|
@ -1291,14 +1291,14 @@ static BOOL test_enum_svc(int attempt)
|
|||
/* Store the number of returned services */
|
||||
tempreturned = returned;
|
||||
|
||||
servicesA = HeapAlloc(GetProcessHeap(), 0, neededA);
|
||||
servicesA = malloc(neededA);
|
||||
bufsize = neededA;
|
||||
neededA = 0xdeadbeef;
|
||||
returnedA = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
servicesA, bufsize, &neededA, &returnedA, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, servicesA);
|
||||
free(servicesA);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
if (!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY && GetACP() == CP_UTF8)
|
||||
|
@ -1314,7 +1314,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
* More than one service will be missing because of the space needed for
|
||||
* the strings.
|
||||
*/
|
||||
services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
|
||||
services = malloc(tempneeded);
|
||||
bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW);
|
||||
needed = 0xdeadbeef;
|
||||
returned = 0xdeadbeef;
|
||||
|
@ -1323,7 +1323,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
services, bufsize, &needed, &returned, NULL);
|
||||
if (ret && needed == 0 && attempt)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
goto retry; /* service stop race condition */
|
||||
}
|
||||
ok(!ret, "Expected failure\n");
|
||||
|
@ -1346,7 +1346,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
services, bufsize, &needed, &returned, &resume);
|
||||
if (ret && needed == 0 && attempt)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
goto retry; /* service stop race condition */
|
||||
}
|
||||
ok(!ret, "Expected failure\n");
|
||||
|
@ -1365,7 +1365,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
services, bufsize, &needed, &returned, &resume);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
|
@ -1390,10 +1390,10 @@ static BOOL test_enum_svc(int attempt)
|
|||
/* Get the number of active win32 services */
|
||||
EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
|
||||
&needed, &returned, NULL);
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE,
|
||||
services, needed, &needed, &returned, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1402,10 +1402,10 @@ static BOOL test_enum_svc(int attempt)
|
|||
/* Get the number of inactive win32 services */
|
||||
EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
|
||||
&needed, &returned, NULL);
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE,
|
||||
services, needed, &needed, &returned, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1414,10 +1414,10 @@ static BOOL test_enum_svc(int attempt)
|
|||
/* Get the number of win32 services */
|
||||
EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
|
||||
&needed, &returned, NULL);
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
services, needed, &needed, &returned, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1435,7 +1435,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
*/
|
||||
EnumServicesStatusW(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
NULL, 0, &needed, &returned, NULL);
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
services, needed, &needed, &returned, NULL);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
|
@ -1482,7 +1482,7 @@ static BOOL test_enum_svc(int attempt)
|
|||
}
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
|
||||
if ((servicecountactive || servicecountinactive) && attempt)
|
||||
goto retry; /* service start|stop race condition */
|
||||
|
@ -1695,11 +1695,11 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
/* Show the Ex call returns the same service count as the regular enum */
|
||||
EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
NULL, 0, &needed, &returned, NULL);
|
||||
services = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
services = malloc(needed);
|
||||
returned = 0xdeadbeef;
|
||||
ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
services, needed, &needed, &returned, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, services);
|
||||
free(services);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
|
@ -1710,14 +1710,14 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
tempreturned = returned;
|
||||
|
||||
/* Allocate the correct needed bytes */
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
|
||||
exservices = malloc(tempneeded);
|
||||
bufsize = tempneeded;
|
||||
needed = 0xdeadbeef;
|
||||
returned = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
(BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
|
@ -1731,7 +1731,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
* More than one service will be missing because of the space needed for
|
||||
* the strings.
|
||||
*/
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
|
||||
exservices = malloc(tempneeded);
|
||||
bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW);
|
||||
needed = 0xdeadbeef;
|
||||
returned = 0xdeadbeef;
|
||||
|
@ -1740,7 +1740,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
(BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
|
||||
if (ret && needed == 0 && attempt)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
goto retry; /* service stop race condition */
|
||||
}
|
||||
ok(!ret, "Expected failure\n");
|
||||
|
@ -1763,7 +1763,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
(BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
|
||||
if (ret && needed == 0 && attempt)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
goto retry; /* service stop race condition */
|
||||
}
|
||||
ok(!ret, "Expected failure\n");
|
||||
|
@ -1782,7 +1782,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
(BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
|
@ -1795,10 +1795,10 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
/* Get the number of active win32 services */
|
||||
pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
|
||||
NULL, 0, &needed, &returned, NULL, NULL);
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
exservices = malloc(needed);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
|
||||
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1807,10 +1807,10 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
/* Get the number of inactive win32 services */
|
||||
pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
|
||||
NULL, 0, &needed, &returned, NULL, NULL);
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
exservices = malloc(needed);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
|
||||
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1819,10 +1819,10 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
/* Get the number of win32 services */
|
||||
pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
NULL, 0, &needed, &returned, NULL, NULL);
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
exservices = malloc(needed);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
|
||||
(BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
goto retry; /* service start race condition */
|
||||
|
||||
|
@ -1837,7 +1837,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
|
||||
SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
|
||||
ok(!ret, "Expected failure\n");
|
||||
exservices = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
exservices = malloc(needed);
|
||||
ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
|
||||
SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA && attempt)
|
||||
|
@ -1908,7 +1908,7 @@ static BOOL test_enum_svc_ex(int attempt)
|
|||
}
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, exservices);
|
||||
free(exservices);
|
||||
|
||||
if ((servicecountactive || servicecountinactive) && attempt)
|
||||
goto retry; /* service start|stop race condition */
|
||||
|
@ -2154,7 +2154,7 @@ static void test_sequence(void)
|
|||
ok(!ret, "Expected failure\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
|
||||
|
||||
config = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
config = malloc(needed);
|
||||
given = needed;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = QueryServiceConfigA(svc_handle, config, given, &needed);
|
||||
|
@ -2182,7 +2182,7 @@ static void test_sequence(void)
|
|||
ok(ret, "ChangeServiceConfig failed (err=%ld)\n", GetLastError());
|
||||
|
||||
QueryServiceConfigA(svc_handle, NULL, 0, &needed);
|
||||
config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
|
||||
config = realloc(config, needed);
|
||||
ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
|
||||
ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
|
||||
config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
|
||||
|
@ -2201,7 +2201,7 @@ static void test_sequence(void)
|
|||
ok(ret, "Expected success, got error %lu\n", GetLastError());
|
||||
CloseServiceHandle(svc_handle);
|
||||
CloseServiceHandle(scm_handle);
|
||||
HeapFree(GetProcessHeap(), 0, config);
|
||||
free(config);
|
||||
}
|
||||
|
||||
static void test_queryconfig2(void)
|
||||
|
@ -2890,7 +2890,7 @@ static void test_EventLog(void)
|
|||
ok(!ret, "QueryServiceConfig should fail\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
|
||||
|
||||
config = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
config = malloc(size);
|
||||
ret = QueryServiceConfigA(svc_handle, config, size, &size);
|
||||
ok(ret, "QueryServiceConfig error %lu\n", GetLastError());
|
||||
|
||||
|
@ -2912,7 +2912,7 @@ static void test_EventLog(void)
|
|||
!strcmp(config->lpDisplayName, "Event Log") /* XP */ ||
|
||||
!strcmp(config->lpDisplayName, "Windows Event Log") /* Vista+ */, "got %s\n", config->lpDisplayName);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, config);
|
||||
free(config);
|
||||
|
||||
memset(&status, 0, sizeof(status));
|
||||
size = sizeof(status);
|
||||
|
|
|
@ -254,6 +254,8 @@ static ULONG WINAPI filter_Release(IMediaStreamFilter *iface)
|
|||
free(filter->streams);
|
||||
if (filter->clock)
|
||||
IReferenceClock_Release(filter->clock);
|
||||
if (filter->cs.DebugInfo)
|
||||
filter->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&filter->cs);
|
||||
free(filter);
|
||||
}
|
||||
|
@ -1100,7 +1102,7 @@ HRESULT filter_create(IUnknown *outer, void **out)
|
|||
object->refcount = 1;
|
||||
list_init(&object->free_events);
|
||||
list_init(&object->used_events);
|
||||
InitializeCriticalSection(&object->cs);
|
||||
InitializeCriticalSectionEx(&object->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MediaStreamFilter.cs");
|
||||
|
||||
TRACE("Created media stream filter %p.\n", object);
|
||||
|
|
|
@ -122,7 +122,7 @@ coclass WAVFile { interface IAVIFile; }
|
|||
threading(both),
|
||||
uuid(0002000d-0000-0000-c000-000000000046)
|
||||
]
|
||||
coclass PSFactoryBuffer { interface IFactoryBuffer; }
|
||||
coclass PSFactoryBuffer { interface IPSFactoryBuffer; }
|
||||
|
||||
[
|
||||
helpstring("ACM Compressed Audio Stream"),
|
||||
|
|
|
@ -254,6 +254,8 @@ static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame *iface, LONG lPos)
|
|||
} /* for (lNext < lPos) */
|
||||
} /* if (This->lCurrentFrame != lPos) */
|
||||
|
||||
This->lCurrentFrame = lPos;
|
||||
|
||||
return (This->hic == NULL ? This->lpInFormat : This->lpOutFormat);
|
||||
}
|
||||
|
||||
|
|
|
@ -241,19 +241,23 @@ struct key_asymmetric_decrypt_params
|
|||
struct key *key;
|
||||
UCHAR *input;
|
||||
unsigned input_len;
|
||||
void *padding;
|
||||
UCHAR *output;
|
||||
ULONG output_len;
|
||||
ULONG *ret_len;
|
||||
ULONG flags;
|
||||
};
|
||||
|
||||
struct key_asymmetric_encrypt_params
|
||||
{
|
||||
struct key *key;
|
||||
UCHAR *input;
|
||||
unsigned input_len;
|
||||
unsigned input_len;
|
||||
void *padding;
|
||||
UCHAR *output;
|
||||
ULONG output_len;
|
||||
ULONG output_len;
|
||||
ULONG *ret_len;
|
||||
ULONG flags;
|
||||
};
|
||||
|
||||
struct key_asymmetric_duplicate_params
|
||||
|
|
|
@ -732,7 +732,7 @@ static NTSTATUS get_rsa_property( enum chain_mode mode, const WCHAR *prop, UCHAR
|
|||
{
|
||||
*ret_size = sizeof(ULONG);
|
||||
if (size < sizeof(ULONG)) return STATUS_BUFFER_TOO_SMALL;
|
||||
if (buf) *(ULONG *)buf = BCRYPT_SUPPORTED_PAD_PKCS1_SIG;
|
||||
if (buf) *(ULONG *)buf = BCRYPT_SUPPORTED_PAD_PKCS1_SIG | BCRYPT_SUPPORTED_PAD_OAEP;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2254,7 +2254,7 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP)
|
||||
if (flags & BCRYPT_PAD_NONE)
|
||||
{
|
||||
FIXME( "flags %#lx not implemented\n", flags );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -2263,10 +2263,12 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
|
||||
asymmetric_params.input = input;
|
||||
asymmetric_params.input_len = input_len;
|
||||
asymmetric_params.padding = padding;
|
||||
asymmetric_params.key = key;
|
||||
asymmetric_params.output = output;
|
||||
asymmetric_params.output_len = output_len;
|
||||
asymmetric_params.ret_len = ret_len;
|
||||
asymmetric_params.flags = flags;
|
||||
ret = UNIX_CALL(key_asymmetric_encrypt, &asymmetric_params);
|
||||
}
|
||||
|
||||
|
@ -2299,7 +2301,7 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP)
|
||||
if (flags & BCRYPT_PAD_NONE)
|
||||
{
|
||||
FIXME( "flags %#lx not implemented\n", flags );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -2309,9 +2311,11 @@ NTSTATUS WINAPI BCryptDecrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp
|
|||
params.key = key;
|
||||
params.input = input;
|
||||
params.input_len = input_len;
|
||||
params.padding = padding;
|
||||
params.output = output;
|
||||
params.output_len = output_len;
|
||||
params.ret_len = ret_len;
|
||||
params.flags = flags;
|
||||
ret = UNIX_CALL(key_asymmetric_decrypt, ¶ms);
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,9 @@ static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_pa
|
|||
const gnutls_datum_t *);
|
||||
static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
|
||||
|
||||
/* Not present in gnutls version < 3.8.4 */
|
||||
static int (*pgnutls_x509_spki_set_rsa_oaep_params)(gnutls_x509_spki_t, gnutls_digest_algorithm_t, gnutls_datum_t *);
|
||||
|
||||
static void *libgnutls_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(gnutls_cipher_decrypt2);
|
||||
|
@ -303,6 +306,12 @@ static void compat_gnutls_x509_spki_deinit(gnutls_x509_spki_t spki)
|
|||
{
|
||||
}
|
||||
|
||||
static int compat_gnutls_x509_spki_set_rsa_oaep_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
|
||||
gnutls_datum_t *label)
|
||||
{
|
||||
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||
}
|
||||
|
||||
static void compat_gnutls_x509_spki_set_rsa_pss_params(gnutls_x509_spki_t spki, gnutls_digest_algorithm_t dig,
|
||||
unsigned int salt_size)
|
||||
{
|
||||
|
@ -444,6 +453,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
LOAD_FUNCPTR_OPT(gnutls_pubkey_verify_hash2)
|
||||
LOAD_FUNCPTR_OPT(gnutls_x509_spki_deinit)
|
||||
LOAD_FUNCPTR_OPT(gnutls_x509_spki_init)
|
||||
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_oaep_params)
|
||||
LOAD_FUNCPTR_OPT(gnutls_x509_spki_set_rsa_pss_params)
|
||||
|
||||
#undef LOAD_FUNCPTR_OPT
|
||||
|
@ -2617,6 +2627,27 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS privkey_set_rsa_oaep_params( gnutls_privkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
|
||||
{
|
||||
gnutls_x509_spki_t spki;
|
||||
int ret;
|
||||
|
||||
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
|
||||
ret = pgnutls_privkey_set_spki( key, spki, 0 );
|
||||
pgnutls_x509_spki_deinit( spki );
|
||||
if (ret < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_asymmetric_decrypt( void *args )
|
||||
{
|
||||
const struct key_asymmetric_decrypt_params *params = args;
|
||||
|
@ -2624,6 +2655,28 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
|
|||
NTSTATUS status = STATUS_SUCCESS;
|
||||
int ret;
|
||||
|
||||
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
|
||||
{
|
||||
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
|
||||
gnutls_digest_algorithm_t dig;
|
||||
gnutls_datum_t label;
|
||||
|
||||
if (!pad || !pad->pszAlgId)
|
||||
{
|
||||
WARN( "padding info not found\n" );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
|
||||
{
|
||||
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
label.data = pad->pbLabel;
|
||||
label.size = pad->cbLabel;
|
||||
if ((status = privkey_set_rsa_oaep_params( key_data(params->key)->a.privkey, dig, &label ))) return status;
|
||||
}
|
||||
|
||||
e.data = params->input;
|
||||
e.size = params->input_len;
|
||||
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
|
||||
|
@ -2634,12 +2687,33 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
|
|||
|
||||
*params->ret_len = d.size;
|
||||
if (params->output_len >= d.size) memcpy( params->output, d.data, *params->ret_len );
|
||||
else status = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (params->output) status = STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
free( d.data );
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS pubkey_set_rsa_oaep_params( gnutls_pubkey_t key, gnutls_digest_algorithm_t dig, gnutls_datum_t *label )
|
||||
{
|
||||
gnutls_x509_spki_t spki;
|
||||
int ret;
|
||||
|
||||
if (((ret = pgnutls_x509_spki_init( &spki ) < 0)))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
pgnutls_x509_spki_set_rsa_oaep_params( spki, dig, label );
|
||||
ret = pgnutls_pubkey_set_spki( key, spki, 0 );
|
||||
pgnutls_x509_spki_deinit( spki );
|
||||
if (ret < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_asymmetric_encrypt( void *args )
|
||||
{
|
||||
const struct key_asymmetric_encrypt_params *params = args;
|
||||
|
@ -2649,6 +2723,28 @@ static NTSTATUS key_asymmetric_encrypt( void *args )
|
|||
|
||||
if (!key_data(params->key)->a.pubkey) return STATUS_INVALID_HANDLE;
|
||||
|
||||
if (params->key->alg_id == ALG_ID_RSA && params->flags & BCRYPT_PAD_OAEP)
|
||||
{
|
||||
BCRYPT_OAEP_PADDING_INFO *pad = params->padding;
|
||||
gnutls_digest_algorithm_t dig;
|
||||
gnutls_datum_t label;
|
||||
|
||||
if (!pad || !pad->pszAlgId || !pad->pbLabel)
|
||||
{
|
||||
WARN( "padding info not found\n" );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if ((dig = get_digest_from_id( pad->pszAlgId )) == GNUTLS_DIG_UNKNOWN)
|
||||
{
|
||||
FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
label.data = pad->pbLabel;
|
||||
label.size = pad->cbLabel;
|
||||
if ((status = pubkey_set_rsa_oaep_params( key_data(params->key)->a.pubkey, dig, &label ))) return status;
|
||||
}
|
||||
|
||||
d.data = params->input;
|
||||
d.size = params->input_len;
|
||||
if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e)))
|
||||
|
@ -2751,12 +2847,19 @@ struct key32
|
|||
|
||||
union padding
|
||||
{
|
||||
BCRYPT_OAEP_PADDING_INFO oaep;
|
||||
BCRYPT_PKCS1_PADDING_INFO pkcs1;
|
||||
BCRYPT_PSS_PADDING_INFO pss;
|
||||
};
|
||||
|
||||
union padding32
|
||||
{
|
||||
struct
|
||||
{
|
||||
PTR32 pszAlgId;
|
||||
PTR32 pbLabel;
|
||||
ULONG cbLabel;
|
||||
} oaep;
|
||||
struct
|
||||
{
|
||||
PTR32 pszAlgId;
|
||||
|
@ -2774,13 +2877,21 @@ static union padding *get_padding( union padding32 *padding32, union padding *pa
|
|||
|
||||
switch (flags)
|
||||
{
|
||||
case BCRYPT_PAD_OAEP:
|
||||
padding->oaep.pszAlgId = ULongToPtr( padding32->oaep.pszAlgId );
|
||||
padding->oaep.pbLabel = ULongToPtr( padding32->oaep.pbLabel );
|
||||
padding->oaep.cbLabel = padding32->oaep.cbLabel;
|
||||
return padding;
|
||||
|
||||
case BCRYPT_PAD_PKCS1:
|
||||
padding->pkcs1.pszAlgId = ULongToPtr( padding32->pkcs1.pszAlgId );
|
||||
return padding;
|
||||
|
||||
case BCRYPT_PAD_PSS:
|
||||
padding->pss.pszAlgId = ULongToPtr( padding32->pss.pszAlgId );
|
||||
padding->pss.cbSalt = padding32->pss.cbSalt;
|
||||
return padding;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2965,22 +3076,27 @@ static NTSTATUS wow64_key_asymmetric_decrypt( void *args )
|
|||
PTR32 key;
|
||||
PTR32 input;
|
||||
ULONG input_len;
|
||||
PTR32 padding;
|
||||
PTR32 output;
|
||||
ULONG output_len;
|
||||
PTR32 ret_len;
|
||||
ULONG flags;
|
||||
} const *params32 = args;
|
||||
|
||||
NTSTATUS ret;
|
||||
struct key key;
|
||||
union padding padding;
|
||||
struct key32 *key32 = ULongToPtr( params32->key );
|
||||
struct key_asymmetric_decrypt_params params =
|
||||
{
|
||||
get_asymmetric_key( key32, &key ),
|
||||
ULongToPtr(params32->input),
|
||||
params32->input_len,
|
||||
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
|
||||
ULongToPtr(params32->output),
|
||||
params32->output_len,
|
||||
ULongToPtr(params32->ret_len)
|
||||
ULongToPtr(params32->ret_len),
|
||||
params32->flags
|
||||
};
|
||||
|
||||
ret = key_asymmetric_decrypt( ¶ms );
|
||||
|
@ -2995,22 +3111,27 @@ static NTSTATUS wow64_key_asymmetric_encrypt( void *args )
|
|||
PTR32 key;
|
||||
PTR32 input;
|
||||
ULONG input_len;
|
||||
PTR32 padding;
|
||||
PTR32 output;
|
||||
ULONG output_len;
|
||||
PTR32 ret_len;
|
||||
ULONG flags;
|
||||
} const *params32 = args;
|
||||
|
||||
NTSTATUS ret;
|
||||
struct key key;
|
||||
union padding padding;
|
||||
struct key32 *key32 = ULongToPtr( params32->key );
|
||||
struct key_asymmetric_encrypt_params params =
|
||||
{
|
||||
get_asymmetric_key( key32, &key ),
|
||||
ULongToPtr(params32->input),
|
||||
params32->input_len,
|
||||
get_padding( ULongToPtr(params32->padding), &padding, params32->flags ),
|
||||
ULongToPtr(params32->output),
|
||||
params32->output_len,
|
||||
ULongToPtr(params32->ret_len)
|
||||
ULongToPtr(params32->ret_len),
|
||||
params32->flags
|
||||
};
|
||||
|
||||
ret = key_asymmetric_encrypt( ¶ms );
|
||||
|
|
|
@ -2444,20 +2444,16 @@ static const UCHAR rsa_encrypted_no_padding[] =
|
|||
|
||||
static void test_rsa_encrypt(void)
|
||||
{
|
||||
static UCHAR input[] = "Hello World!";
|
||||
static UCHAR input_no_padding[64] = { 0 };
|
||||
UCHAR encrypted[64], decrypted[64];
|
||||
BCRYPT_ALG_HANDLE rsa = 0;
|
||||
BCRYPT_KEY_HANDLE key = 0, key2;
|
||||
NTSTATUS ret = 0;
|
||||
DWORD encrypted_size = 60;
|
||||
UCHAR *encrypted_a = NULL;
|
||||
UCHAR *encrypted_b = NULL;
|
||||
DWORD decrypted_size = 0;
|
||||
UCHAR input[] = "Hello World!", input_no_padding[64] = { 0 }, encrypted[64], decrypted[64];
|
||||
BCRYPT_ALG_HANDLE rsa;
|
||||
BCRYPT_KEY_HANDLE key, key2;
|
||||
NTSTATUS ret;
|
||||
DWORD encrypted_size, decrypted_size;
|
||||
UCHAR *encrypted_a = NULL, *encrypted_b = NULL;
|
||||
BCRYPT_OAEP_PADDING_INFO oaep_pad;
|
||||
|
||||
oaep_pad.pszAlgId = BCRYPT_MD5_ALGORITHM;
|
||||
oaep_pad.pbLabel = (PUCHAR)"test";
|
||||
oaep_pad.pszAlgId = BCRYPT_SHA256_ALGORITHM;
|
||||
oaep_pad.pbLabel = (UCHAR *)"test";
|
||||
oaep_pad.cbLabel = 5;
|
||||
|
||||
ret = BCryptOpenAlgorithmProvider(&rsa, BCRYPT_RSA_ALGORITHM, NULL, 0);
|
||||
|
@ -2478,10 +2474,11 @@ static void test_rsa_encrypt(void)
|
|||
ret = BCryptImportKeyPair(rsa, NULL, BCRYPT_RSAPRIVATE_BLOB, &key, rsaPrivateBlob, sizeof(rsaPrivateBlob), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
|
||||
|
||||
todo_wine {
|
||||
/* No padding */
|
||||
todo_wine {
|
||||
memset(input_no_padding, 0, sizeof(input_no_padding));
|
||||
strcpy((char *)input_no_padding, "Hello World");
|
||||
encrypted_size = 0;
|
||||
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
@ -2496,22 +2493,32 @@ static void test_rsa_encrypt(void)
|
|||
|
||||
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, 12, &encrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_BUFFER_TOO_SMALL, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
||||
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
||||
ret = BCryptEncrypt(key, input_no_padding, sizeof(input_no_padding), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
}
|
||||
ok(!memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs should be the same\n");
|
||||
ok(!memcmp(encrypted_b, rsa_encrypted_no_padding, encrypted_size), "Data mismatch.\n");
|
||||
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE);
|
||||
todo_wine {
|
||||
decrypted_size = 0;
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "Decrypted output it's not what expected\n");
|
||||
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_NONE);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input_no_padding), "got %lu\n", decrypted_size);
|
||||
ok(!memcmp(decrypted, input_no_padding, sizeof(input_no_padding)), "unexpected output\n");
|
||||
}
|
||||
|
||||
encrypted_size = 60;
|
||||
/* PKCS1 Padding */
|
||||
encrypted_size = 0;
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
@ -2523,22 +2530,54 @@ static void test_rsa_encrypt(void)
|
|||
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), NULL, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
|
||||
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
decrypted_size = 0;
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
|
||||
|
||||
todo_wine {
|
||||
encrypted_size = 60;
|
||||
/* OAEP Padding */
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, NULL, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
|
||||
|
||||
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2, (UCHAR *)&rsaLegacyPrivateBlob,
|
||||
sizeof(rsaLegacyPrivateBlob), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
|
||||
|
||||
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0, encrypted, sizeof(encrypted),
|
||||
&encrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
||||
memset(decrypted, 0, sizeof(decrypted));
|
||||
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0, decrypted, sizeof(decrypted),
|
||||
&decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
|
||||
BCryptDestroyKey(key2);
|
||||
BCryptDestroyKey(key);
|
||||
|
||||
/* OAEP Padding */
|
||||
ret = BCryptGenerateKeyPair(rsa, &key, 640 /* minimum size for sha256 hash */, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
|
||||
ret = BCryptFinalizeKeyPair(key, 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
|
||||
|
||||
todo_wine {
|
||||
encrypted_size = 0;
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, NULL, 0, &encrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
|
||||
|
||||
encrypted_a = realloc(encrypted_a, encrypted_size);
|
||||
memset(encrypted_a, 0, encrypted_size);
|
||||
encrypted_b = realloc(encrypted_b, encrypted_size);
|
||||
|
@ -2546,38 +2585,28 @@ static void test_rsa_encrypt(void)
|
|||
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_a, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
|
||||
|
||||
ret = BCryptEncrypt(key, input, sizeof(input), &oaep_pad, NULL, 0, encrypted_b, encrypted_size, &encrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 80, "got size of %ld\n", encrypted_size);
|
||||
ok(memcmp(encrypted_a, encrypted_b, encrypted_size), "Both outputs are the same\n");
|
||||
|
||||
decrypted_size = 0;
|
||||
memset(decrypted, 0, sizeof(decrypted));
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, NULL, 0, &decrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
|
||||
BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
|
||||
|
||||
ret = BCryptDecrypt(key, encrypted_a, encrypted_size, &oaep_pad, NULL, 0, decrypted, decrypted_size, &decrypted_size, BCRYPT_PAD_OAEP);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got %lu\n", decrypted_size);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "unexpected output\n");
|
||||
}
|
||||
|
||||
free(encrypted_a);
|
||||
free(encrypted_b);
|
||||
|
||||
ret = BCryptImportKeyPair(rsa, NULL, LEGACY_RSAPRIVATE_BLOB, &key2,
|
||||
(UCHAR *)&rsaLegacyPrivateBlob, sizeof(rsaLegacyPrivateBlob), 0);
|
||||
ok(ret == STATUS_SUCCESS, "got %#lx\n", ret);
|
||||
|
||||
ret = BCryptEncrypt(key2, input, sizeof(input), NULL, NULL, 0,
|
||||
encrypted, sizeof(encrypted), &encrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(encrypted_size == 64, "got size of %ld\n", encrypted_size);
|
||||
|
||||
memset(decrypted, 0, sizeof(decrypted));
|
||||
ret = BCryptDecrypt(key, encrypted, sizeof(encrypted), NULL, NULL, 0,
|
||||
decrypted, sizeof(decrypted), &decrypted_size, BCRYPT_PAD_PKCS1);
|
||||
ok(ret == STATUS_SUCCESS, "got %lx\n", ret);
|
||||
ok(decrypted_size == sizeof(input), "got size of %ld\n", decrypted_size);
|
||||
ok(!memcmp(decrypted, input, sizeof(input)), "Decrypted output it's not what expected\n");
|
||||
|
||||
BCryptDestroyKey(key2);
|
||||
BCryptDestroyKey(key);
|
||||
|
||||
if (pBCryptHash)
|
||||
|
|
|
@ -149,7 +149,7 @@ HRESULT CompCatCacheDaemon_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
|
|||
|
||||
This->IRunnableTask_iface.lpVtbl = &CompCatCacheDaemonVtbl;
|
||||
This->refCount = 1;
|
||||
InitializeCriticalSection(&This->cs);
|
||||
InitializeCriticalSectionEx(&This->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CompCatCacheDaemon.cs");
|
||||
|
||||
TRACE("returning %p\n", This);
|
||||
|
|
|
@ -626,7 +626,7 @@ HRESULT ProgressDialog_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
|
|||
This->IProgressDialog_iface.lpVtbl = &ProgressDialogVtbl;
|
||||
This->IOleWindow_iface.lpVtbl = &OleWindowVtbl;
|
||||
This->refCount = 1;
|
||||
InitializeCriticalSection(&This->cs);
|
||||
InitializeCriticalSectionEx(&This->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ProgressDialog.cs");
|
||||
|
||||
TRACE("returning %p\n", This);
|
||||
|
|
|
@ -376,7 +376,7 @@ static struct apartment *apartment_construct(DWORD model)
|
|||
apt->refs = 1;
|
||||
apt->remunk_exported = FALSE;
|
||||
apt->oidc = 1;
|
||||
InitializeCriticalSection(&apt->cs);
|
||||
InitializeCriticalSectionEx(&apt->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
apt->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": apartment");
|
||||
|
||||
apt->multi_threaded = !(model & COINIT_APARTMENTTHREADED);
|
||||
|
|
|
@ -1575,7 +1575,7 @@ static HRESULT proxy_manager_construct(
|
|||
list_init(&This->entry);
|
||||
list_init(&This->interfaces);
|
||||
|
||||
InitializeCriticalSection(&This->cs);
|
||||
InitializeCriticalSectionEx(&This->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": proxy_manager");
|
||||
|
||||
/* the apartment the object was unmarshaled into */
|
||||
|
|
|
@ -187,7 +187,7 @@ static struct stub_manager *new_stub_manager(struct apartment *apt, IUnknown *ob
|
|||
|
||||
list_init(&sm->ifstubs);
|
||||
|
||||
InitializeCriticalSection(&sm->lock);
|
||||
InitializeCriticalSectionEx(&sm->lock, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
sm->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": stub_manager");
|
||||
|
||||
IUnknown_AddRef(object);
|
||||
|
|
|
@ -813,7 +813,7 @@ static BOOL ANIMATE_Create(HWND hWnd, const CREATESTRUCTW *lpcs)
|
|||
|
||||
TRACE("Animate style %#lx, parent %p\n", infoPtr->dwStyle, infoPtr->hwndNotify);
|
||||
|
||||
InitializeCriticalSection(&infoPtr->cs);
|
||||
InitializeCriticalSectionEx(&infoPtr->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
infoPtr->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ANIMATE_INFO*->cs");
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -763,106 +763,18 @@ HIMAGELIST WINAPI
|
|||
ImageList_Create (INT cx, INT cy, UINT flags,
|
||||
INT cInitial, INT cGrow)
|
||||
{
|
||||
HIMAGELIST himl;
|
||||
INT nCount;
|
||||
HBITMAP hbmTemp;
|
||||
UINT ilc = (flags & 0xFE);
|
||||
static const WORD aBitBlend25[] =
|
||||
{0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
|
||||
|
||||
static const WORD aBitBlend50[] =
|
||||
{0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
|
||||
IImageList2 *himl;
|
||||
|
||||
TRACE("(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
|
||||
|
||||
if (cx < 0 || cy < 0) return NULL;
|
||||
if (!((flags&ILC_COLORDDB) == ILC_COLORDDB) && (cx == 0 || cy == 0)) return NULL;
|
||||
|
||||
/* Create the IImageList interface for the image list */
|
||||
if (FAILED(ImageListImpl_CreateInstance(NULL, &IID_IImageList, (void **)&himl)))
|
||||
if (FAILED(ImageListImpl_CreateInstance(NULL, &IID_IImageList2, (void **)&himl)))
|
||||
return NULL;
|
||||
|
||||
cGrow = (WORD)((max( cGrow, 1 ) + 3) & ~3);
|
||||
if (IImageList2_Initialize(himl, cx, cy, flags, cInitial, cGrow) == S_OK)
|
||||
return (HIMAGELIST)himl;
|
||||
|
||||
if (cGrow > 256)
|
||||
{
|
||||
/* Windows doesn't limit the size here, but X11 doesn't let us allocate such huge bitmaps */
|
||||
WARN( "grow %d too large, limiting to 256\n", cGrow );
|
||||
cGrow = 256;
|
||||
}
|
||||
|
||||
himl->cx = cx;
|
||||
himl->cy = cy;
|
||||
himl->flags = flags;
|
||||
himl->cMaxImage = cInitial + 1;
|
||||
himl->cInitial = cInitial;
|
||||
himl->cGrow = cGrow;
|
||||
himl->clrFg = CLR_DEFAULT;
|
||||
himl->clrBk = CLR_NONE;
|
||||
himl->color_table_set = FALSE;
|
||||
|
||||
/* initialize overlay mask indices */
|
||||
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
|
||||
himl->nOvlIdx[nCount] = -1;
|
||||
|
||||
/* Create Image & Mask DCs */
|
||||
himl->hdcImage = CreateCompatibleDC (0);
|
||||
if (!himl->hdcImage)
|
||||
goto cleanup;
|
||||
if (himl->flags & ILC_MASK){
|
||||
himl->hdcMask = CreateCompatibleDC(0);
|
||||
if (!himl->hdcMask)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Default to ILC_COLOR4 if none of the ILC_COLOR* flags are specified */
|
||||
if (ilc == ILC_COLOR)
|
||||
{
|
||||
ilc = ILC_COLOR4;
|
||||
himl->flags |= ILC_COLOR4;
|
||||
}
|
||||
|
||||
if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
|
||||
himl->uBitsPixel = ilc;
|
||||
else
|
||||
himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
|
||||
|
||||
if (himl->cMaxImage > 0) {
|
||||
himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage);
|
||||
SelectObject(himl->hdcImage, himl->hbmImage);
|
||||
} else
|
||||
himl->hbmImage = 0;
|
||||
|
||||
if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
|
||||
SIZE sz;
|
||||
|
||||
imagelist_get_bitmap_size(himl, himl->cMaxImage, &sz);
|
||||
himl->hbmMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
|
||||
if (himl->hbmMask == 0) {
|
||||
ERR("Error creating mask bitmap!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
SelectObject(himl->hdcMask, himl->hbmMask);
|
||||
}
|
||||
else
|
||||
himl->hbmMask = 0;
|
||||
|
||||
himl->item_flags = Alloc( himl->cMaxImage * sizeof(*himl->item_flags) );
|
||||
|
||||
/* create blending brushes */
|
||||
hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend25);
|
||||
himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
|
||||
DeleteObject (hbmTemp);
|
||||
|
||||
hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend50);
|
||||
himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
|
||||
DeleteObject (hbmTemp);
|
||||
|
||||
TRACE("created imagelist %p\n", himl);
|
||||
return himl;
|
||||
|
||||
cleanup:
|
||||
ImageList_Destroy(himl);
|
||||
IImageList2_Release(himl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3721,8 +3633,99 @@ static HRESULT WINAPI ImageListImpl_GetStatistics(IImageList2 *iface, IMAGELISTS
|
|||
|
||||
static HRESULT WINAPI ImageListImpl_Initialize(IImageList2 *iface, INT cx, INT cy, UINT flags, INT initial, INT grow)
|
||||
{
|
||||
FIXME("(%p)->(%d %d %d %d %d): stub\n", iface, cx, cy, flags, initial, grow);
|
||||
return E_NOTIMPL;
|
||||
HIMAGELIST himl = impl_from_IImageList2(iface);
|
||||
INT nCount;
|
||||
HBITMAP hbmTemp;
|
||||
UINT ilc = (flags & 0xFE);
|
||||
static const WORD aBitBlend25[] =
|
||||
{0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
|
||||
static const WORD aBitBlend50[] =
|
||||
{0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
|
||||
|
||||
TRACE("(%p)->(%d %d %d %d %d)\n", iface, cx, cy, flags, initial, grow);
|
||||
|
||||
if (cx < 0 || cy < 0) return E_INVALIDARG;
|
||||
if (!((flags&ILC_COLORDDB) == ILC_COLORDDB) && (cx == 0 || cy == 0)) return E_INVALIDARG;
|
||||
|
||||
grow = (WORD)((max( grow, 1 ) + 3) & ~3);
|
||||
|
||||
if (grow > 256)
|
||||
{
|
||||
/* Windows doesn't limit the size here, but X11 doesn't let us allocate such huge bitmaps */
|
||||
WARN( "grow %d too large, limiting to 256\n", grow );
|
||||
grow = 256;
|
||||
}
|
||||
|
||||
himl->cx = cx;
|
||||
himl->cy = cy;
|
||||
himl->flags = flags;
|
||||
himl->cMaxImage = initial + 1;
|
||||
himl->cInitial = initial;
|
||||
himl->cGrow = grow;
|
||||
himl->clrFg = CLR_DEFAULT;
|
||||
himl->clrBk = CLR_NONE;
|
||||
himl->color_table_set = FALSE;
|
||||
|
||||
/* initialize overlay mask indices */
|
||||
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
|
||||
himl->nOvlIdx[nCount] = -1;
|
||||
|
||||
/* Create Image & Mask DCs */
|
||||
himl->hdcImage = CreateCompatibleDC (0);
|
||||
if (!himl->hdcImage)
|
||||
return E_FAIL;
|
||||
if (himl->flags & ILC_MASK){
|
||||
himl->hdcMask = CreateCompatibleDC(0);
|
||||
if (!himl->hdcMask)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* Default to ILC_COLOR4 if none of the ILC_COLOR* flags are specified */
|
||||
if (ilc == ILC_COLOR)
|
||||
{
|
||||
ilc = ILC_COLOR4;
|
||||
himl->flags |= ILC_COLOR4;
|
||||
}
|
||||
|
||||
if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
|
||||
himl->uBitsPixel = ilc;
|
||||
else
|
||||
himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
|
||||
|
||||
if (himl->cMaxImage > 0) {
|
||||
himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage);
|
||||
SelectObject(himl->hdcImage, himl->hbmImage);
|
||||
} else
|
||||
himl->hbmImage = 0;
|
||||
|
||||
if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
|
||||
SIZE sz;
|
||||
|
||||
imagelist_get_bitmap_size(himl, himl->cMaxImage, &sz);
|
||||
himl->hbmMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
|
||||
if (himl->hbmMask == 0) {
|
||||
ERR("Error creating mask bitmap!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
SelectObject(himl->hdcMask, himl->hbmMask);
|
||||
}
|
||||
else
|
||||
himl->hbmMask = 0;
|
||||
|
||||
himl->item_flags = Alloc( himl->cMaxImage * sizeof(*himl->item_flags) );
|
||||
|
||||
/* create blending brushes */
|
||||
hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend25);
|
||||
himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
|
||||
DeleteObject (hbmTemp);
|
||||
|
||||
hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend50);
|
||||
himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
|
||||
DeleteObject (hbmTemp);
|
||||
|
||||
TRACE("created imagelist %p\n", himl);
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ImageListImpl_Replace2(IImageList2 *iface, INT i, HBITMAP image, HBITMAP mask, IUnknown *unk, DWORD flags)
|
||||
|
|
|
@ -1672,6 +1672,8 @@ static void test_iimagelist(void)
|
|||
HIMAGELIST himl;
|
||||
HRESULT hr;
|
||||
ULONG ret;
|
||||
HBITMAP hbm;
|
||||
int ret2;
|
||||
|
||||
if (!pHIMAGELIST_QueryInterface)
|
||||
{
|
||||
|
@ -1741,7 +1743,48 @@ static void test_iimagelist(void)
|
|||
win_skip("IImageList2 is not supported.\n");
|
||||
return;
|
||||
}
|
||||
ok(hr == S_OK, "got 0x%08lx\n", hr);
|
||||
|
||||
hr = IImageList2_Initialize(imagelist, BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
|
||||
check_iml_data((HIMAGELIST)imagelist, BMP_CX, BMP_CX, 0, 2, 1, ILC_COLOR24, "IImageList2 0");
|
||||
|
||||
hr = IImageList2_Remove(imagelist, 0);
|
||||
ok(hr == E_INVALIDARG, "got %#lx\n", hr);
|
||||
hr = IImageList2_Remove(imagelist, -1);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
|
||||
hbm = CreateBitmap(BMP_CX, BMP_CX, 1, 1, NULL);
|
||||
|
||||
ret2 = -1;
|
||||
hr = IImageList2_Add(imagelist, hbm, 0, &ret2);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
ok(ret2 == 0, "got %d\n", ret2);
|
||||
|
||||
check_iml_data((HIMAGELIST)imagelist, BMP_CX, BMP_CX, 1, 2, 4, ILC_COLOR24, "IImageList2 1");
|
||||
|
||||
ret2 = -1;
|
||||
hr = IImageList2_Add(imagelist, hbm, 0, &ret2);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
ok(ret2 == 1, "got %d\n", ret2);
|
||||
|
||||
check_iml_data((HIMAGELIST)imagelist, BMP_CX, BMP_CX, 2, 7, 4, ILC_COLOR24, "IImageList2 2");
|
||||
|
||||
hr = IImageList2_Remove(imagelist, 0);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
|
||||
check_iml_data((HIMAGELIST)imagelist, BMP_CX, BMP_CX, 1, 7, 4, ILC_COLOR24, "IImageList2 1");
|
||||
|
||||
hr = IImageList2_Remove(imagelist, -1);
|
||||
ok(hr == S_OK, "got %#lx\n", hr);
|
||||
|
||||
check_iml_data((HIMAGELIST)imagelist, BMP_CX, BMP_CX, 0, 4, 1, ILC_COLOR24, "IImageList2 0");
|
||||
|
||||
hr = IImageList2_Remove(imagelist, 0);
|
||||
ok(hr == E_INVALIDARG, "got %#lx\n", hr);
|
||||
|
||||
DeleteObject(hbm);
|
||||
|
||||
IImageList2_Release(imagelist);
|
||||
}
|
||||
|
||||
|
|
|
@ -469,6 +469,7 @@ static void test_monthcal(void)
|
|||
ok(limits == GDTR_MIN, "got 0x%08lx\n", limits);
|
||||
|
||||
GetSystemTime(st);
|
||||
st[0].wDay = 25;
|
||||
st[1] = st[0];
|
||||
st[1].wYear++;
|
||||
r = SendMessageA(hwnd, MCM_SETRANGE, 0, (LPARAM)st);
|
||||
|
@ -480,6 +481,7 @@ static void test_monthcal(void)
|
|||
|
||||
/* flags are 0, set min limit */
|
||||
GetSystemTime(st);
|
||||
st[0].wDay = 25;
|
||||
st[1] = st[0];
|
||||
st[1].wYear++;
|
||||
|
||||
|
|
|
@ -978,10 +978,11 @@ static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg,
|
|||
/***********************************************************************
|
||||
* PRINTDLG_UpdatePrinterInfoTexts [internal]
|
||||
*/
|
||||
static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *pi)
|
||||
static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, DWORD flags, const PRINTER_INFO_2A *pi)
|
||||
{
|
||||
char StatusMsg[256];
|
||||
char ResourceString[256];
|
||||
char printer_name[256];
|
||||
int i;
|
||||
|
||||
/* Status Message */
|
||||
|
@ -1004,6 +1005,17 @@ static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *p
|
|||
SetDlgItemTextA(hDlg, stc12, StatusMsg);
|
||||
|
||||
/* set all other printer info texts */
|
||||
if (flags & PD_PRINTSETUP)
|
||||
{
|
||||
DWORD dwBufLen = ARRAY_SIZE(printer_name);
|
||||
GetDefaultPrinterA(printer_name, &dwBufLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Windows decorates the printer name with text like 'System Printer' or 'on <port>'. */
|
||||
lstrcpynA(printer_name, pi->pPrinterName, ARRAY_SIZE(printer_name));
|
||||
}
|
||||
SetDlgItemTextA(hDlg, stc1, printer_name);
|
||||
SetDlgItemTextA(hDlg, stc11, pi->pDriverName);
|
||||
|
||||
if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
|
||||
|
@ -1014,11 +1026,12 @@ static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *p
|
|||
return;
|
||||
}
|
||||
|
||||
static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *pi)
|
||||
static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, DWORD flags, const PRINTER_INFO_2W *pi)
|
||||
{
|
||||
WCHAR StatusMsg[256];
|
||||
WCHAR ResourceString[256];
|
||||
int i;
|
||||
WCHAR printer_name[256];
|
||||
int i;
|
||||
|
||||
/* Status Message */
|
||||
StatusMsg[0]='\0';
|
||||
|
@ -1040,6 +1053,17 @@ static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *p
|
|||
SetDlgItemTextW(hDlg, stc12, StatusMsg);
|
||||
|
||||
/* set all other printer info texts */
|
||||
if (flags & PD_PRINTSETUP)
|
||||
{
|
||||
DWORD dwBufLen = ARRAY_SIZE(printer_name);
|
||||
GetDefaultPrinterW(printer_name, &dwBufLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Windows decorates the printer name with text like 'System Printer' or 'on <port>'. */
|
||||
lstrcpynW(printer_name, pi->pPrinterName, ARRAY_SIZE(printer_name));
|
||||
}
|
||||
SetDlgItemTextW(hDlg, stc1, printer_name);
|
||||
SetDlgItemTextW(hDlg, stc11, pi->pDriverName);
|
||||
if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
|
||||
SetDlgItemTextW(hDlg, stc14, pi->pLocation);
|
||||
|
@ -1081,7 +1105,7 @@ static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStru
|
|||
}
|
||||
ClosePrinter(hprn);
|
||||
|
||||
PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo);
|
||||
PRINTDLG_UpdatePrinterInfoTextsA(hDlg, lppd->Flags, PrintStructures->lpPrinterInfo);
|
||||
|
||||
free(PrintStructures->lpDevMode);
|
||||
PrintStructures->lpDevMode = NULL;
|
||||
|
@ -1229,7 +1253,7 @@ static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStru
|
|||
if(IsDefault)
|
||||
SendMessageA(hQuality, CB_SETCURSEL, Index, 0);
|
||||
|
||||
SendMessageA(hQuality, CB_SETITEMDATA, Index, MAKELONG(dpiX,dpiY));
|
||||
SendMessageA(hQuality, CB_SETITEMDATA, Index, MAKELONG(Resolutions[i], Resolutions[i+1]));
|
||||
}
|
||||
free(Resolutions);
|
||||
}
|
||||
|
@ -1288,7 +1312,7 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
|
|||
}
|
||||
ClosePrinter(hprn);
|
||||
|
||||
PRINTDLG_UpdatePrinterInfoTextsW(hDlg, PrintStructures->lpPrinterInfo);
|
||||
PRINTDLG_UpdatePrinterInfoTextsW(hDlg, lppd->Flags, PrintStructures->lpPrinterInfo);
|
||||
|
||||
free(PrintStructures->lpDevMode);
|
||||
PrintStructures->lpDevMode = NULL;
|
||||
|
@ -1386,6 +1410,61 @@ static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
|
|||
if (lppd->Flags & PD_HIDEPRINTTOFILE)
|
||||
ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
|
||||
|
||||
/* Fill print quality combo, PrintDlg16 */
|
||||
if (GetDlgItem(hDlg, cmb1))
|
||||
{
|
||||
DWORD num_resolutions = DeviceCapabilitiesW(PrintStructures->lpPrinterInfo->pPrinterName,
|
||||
PrintStructures->lpPrinterInfo->pPortName,
|
||||
DC_ENUMRESOLUTIONS, NULL, lpdm);
|
||||
|
||||
if (num_resolutions != -1)
|
||||
{
|
||||
HWND quality = GetDlgItem(hDlg, cmb1);
|
||||
LONG* resolutions;
|
||||
WCHAR buf[255];
|
||||
DWORD i;
|
||||
int dpiX, dpiY;
|
||||
HDC printer = CreateDCW(PrintStructures->lpPrinterInfo->pDriverName,
|
||||
PrintStructures->lpPrinterInfo->pPrinterName,
|
||||
0, lpdm);
|
||||
|
||||
resolutions = malloc(num_resolutions * sizeof(LONG) * 2);
|
||||
DeviceCapabilitiesW(PrintStructures->lpPrinterInfo->pPrinterName,
|
||||
PrintStructures->lpPrinterInfo->pPortName,
|
||||
DC_ENUMRESOLUTIONS, (LPWSTR)resolutions, lpdm);
|
||||
|
||||
dpiX = GetDeviceCaps(printer, LOGPIXELSX);
|
||||
dpiY = GetDeviceCaps(printer, LOGPIXELSY);
|
||||
DeleteDC(printer);
|
||||
|
||||
SendMessageW(quality, CB_RESETCONTENT, 0, 0);
|
||||
for (i = 0; i < (num_resolutions * 2); i += 2)
|
||||
{
|
||||
BOOL is_default = FALSE;
|
||||
LRESULT index;
|
||||
|
||||
if (resolutions[i] == resolutions[i+1])
|
||||
{
|
||||
if (dpiX == resolutions[i])
|
||||
is_default = TRUE;
|
||||
swprintf(buf, sizeof(buf), L"%ld dpi", resolutions[i]);
|
||||
} else
|
||||
{
|
||||
if (dpiX == resolutions[i] && dpiY == resolutions[i+1])
|
||||
is_default = TRUE;
|
||||
swprintf(buf, sizeof(buf), L"%ld dpi x %ld dpi", resolutions[i], resolutions[i+1]);
|
||||
}
|
||||
|
||||
index = SendMessageW(quality, CB_ADDSTRING, 0, (LPARAM)buf);
|
||||
|
||||
if (is_default)
|
||||
SendMessageW(quality, CB_SETCURSEL, index, 0);
|
||||
|
||||
SendMessageW(quality, CB_SETITEMDATA, index, MAKELONG(resolutions[i], resolutions[i+1]));
|
||||
}
|
||||
free(resolutions);
|
||||
}
|
||||
}
|
||||
} else { /* PD_PRINTSETUP */
|
||||
BOOL bPortrait = (lpdm->dmOrientation == DMORIENT_PORTRAIT);
|
||||
|
||||
|
@ -1761,8 +1840,8 @@ static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam,
|
|||
case cmb4: /* Printer combobox */
|
||||
if (HIWORD(wParam)==CBN_SELCHANGE) {
|
||||
char *PrinterName;
|
||||
INT index = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0);
|
||||
INT length = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0);
|
||||
INT index = SendDlgItemMessageA(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0);
|
||||
INT length = SendDlgItemMessageA(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0);
|
||||
PrinterName = malloc(length + 1);
|
||||
SendDlgItemMessageA(hDlg, LOWORD(wParam), CB_GETLBTEXT, index, (LPARAM)PrinterName);
|
||||
PRINTDLG_ChangePrinterA(hDlg, PrinterName, PrintStructures);
|
||||
|
@ -1909,7 +1988,10 @@ static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam,
|
|||
}
|
||||
break;
|
||||
|
||||
case cmb1: /* Printer Combobox in PRINT SETUP */
|
||||
case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
|
||||
if (PrinterComboID != LOWORD(wParam)) {
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case cmb4: /* Printer combobox */
|
||||
if (HIWORD(wParam)==CBN_SELCHANGE) {
|
||||
|
|
|
@ -268,7 +268,7 @@
|
|||
@ cdecl _scalb(double long)
|
||||
@ cdecl _searchenv(str str ptr)
|
||||
@ cdecl _seterrormode(long)
|
||||
@ cdecl -norelay _setjmp(ptr) MSVCRT__setjmp
|
||||
@ cdecl -norelay _setjmp(ptr)
|
||||
@ cdecl _setmode(long long)
|
||||
@ stub _setsystime(ptr long)
|
||||
@ cdecl _sleep(long)
|
||||
|
@ -434,7 +434,7 @@
|
|||
@ cdecl -arch=win64 localtime(ptr) _localtime64
|
||||
@ cdecl log(double)
|
||||
@ cdecl log10(double)
|
||||
@ cdecl longjmp(ptr long) MSVCRT_longjmp
|
||||
@ cdecl longjmp(ptr long)
|
||||
@ cdecl malloc(long)
|
||||
@ cdecl mblen(ptr long)
|
||||
@ cdecl mbstowcs(ptr str long)
|
||||
|
|
|
@ -111,8 +111,6 @@ static DWORD encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
|
|||
i = 0;
|
||||
while (div > 0 && ptr < end)
|
||||
{
|
||||
if (i && i % 64 == 0)
|
||||
ptr += stradd(ptr, end, sep, strlen(sep));
|
||||
/* first char is the first 6 bits of the first byte*/
|
||||
chunk[0] = b64[ ( d[0] >> 2) & 0x3f ];
|
||||
/* second char is the last 2 bits of the first byte and the first 4
|
||||
|
@ -127,6 +125,9 @@ static DWORD encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
|
|||
i += 4;
|
||||
d += 3;
|
||||
div--;
|
||||
|
||||
if (i && i % 64 == 0)
|
||||
ptr += stradd(ptr, end, sep, strlen(sep));
|
||||
}
|
||||
|
||||
switch(pad_bytes)
|
||||
|
@ -393,11 +394,6 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
|
|||
i = 0;
|
||||
while (div > 0)
|
||||
{
|
||||
if (i && i % 64 == 0)
|
||||
{
|
||||
lstrcpyW(ptr, sep);
|
||||
ptr += lstrlenW(sep);
|
||||
}
|
||||
/* first char is the first 6 bits of the first byte*/
|
||||
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
|
||||
/* second char is the last 2 bits of the first byte and the first 4
|
||||
|
@ -411,6 +407,12 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
|
|||
i += 4;
|
||||
d += 3;
|
||||
div--;
|
||||
|
||||
if (i && i % 64 == 0)
|
||||
{
|
||||
lstrcpyW(ptr, sep);
|
||||
ptr += lstrlenW(sep);
|
||||
}
|
||||
}
|
||||
|
||||
switch(pad_bytes)
|
||||
|
|
|
@ -478,7 +478,7 @@ WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
|||
{
|
||||
memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection, &CollectionStoreVtbl);
|
||||
InitializeCriticalSection(&store->cs);
|
||||
InitializeCriticalSectionEx(&store->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
|
||||
list_init(&store->stores);
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
|
|||
ret->name = CryptMemAlloc(strlen(pszFuncName) + 1);
|
||||
if (ret->name)
|
||||
{
|
||||
InitializeCriticalSection(&ret->cs);
|
||||
InitializeCriticalSectionEx(&ret->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs");
|
||||
list_init(&ret->functions);
|
||||
strcpy(ret->name, pszFuncName);
|
||||
|
|
|
@ -46,7 +46,7 @@ CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void)
|
|||
|
||||
if (list)
|
||||
{
|
||||
InitializeCriticalSection(&list->cs);
|
||||
InitializeCriticalSectionEx(&list->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs");
|
||||
list_init(&list->properties);
|
||||
}
|
||||
|
|
|
@ -545,7 +545,7 @@ WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
|||
regInfo->dwOpenFlags = dwFlags;
|
||||
regInfo->memStore = memStore;
|
||||
regInfo->key = key;
|
||||
InitializeCriticalSection(®Info->cs);
|
||||
InitializeCriticalSectionEx(®Info->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
|
||||
list_init(®Info->certsToDelete);
|
||||
list_init(®Info->crlsToDelete);
|
||||
|
|
|
@ -388,7 +388,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
|||
{
|
||||
memset(store, 0, sizeof(WINE_MEMSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem, &MemStoreVtbl);
|
||||
InitializeCriticalSection(&store->cs);
|
||||
InitializeCriticalSectionEx(&store->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
|
||||
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
|
||||
list_init(&store->certs);
|
||||
list_init(&store->crls);
|
||||
|
|
|
@ -57,6 +57,8 @@ static const BYTE toEncode4[] =
|
|||
static const BYTE toEncode5[] =
|
||||
"abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHI";
|
||||
|
||||
static const BYTE toEncode6[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
|
||||
static const struct BinTests tests[] = {
|
||||
{ toEncode1, sizeof(toEncode1), "AA==\r\n", },
|
||||
{ toEncode2, sizeof(toEncode2), "AQI=\r\n", },
|
||||
|
@ -69,6 +71,9 @@ static const struct BinTests tests[] = {
|
|||
"SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\r\n" },
|
||||
{ toEncode5, sizeof(toEncode5),
|
||||
"YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\r\n" },
|
||||
{ toEncode6, sizeof(toEncode6),
|
||||
"YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\r\n"
|
||||
"YQA=\r\n" },
|
||||
};
|
||||
|
||||
static const struct BinTests testsNoCR[] = {
|
||||
|
@ -83,6 +88,9 @@ static const struct BinTests testsNoCR[] = {
|
|||
"SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\n" },
|
||||
{ toEncode5, sizeof(toEncode5),
|
||||
"YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\n" },
|
||||
{ toEncode6, sizeof(toEncode6),
|
||||
"YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\n"
|
||||
"YQA=\n" },
|
||||
};
|
||||
|
||||
static WCHAR *strdupAtoW(const char *str)
|
||||
|
|
|
@ -355,7 +355,7 @@ static HRESULT async_info_create( IUnknown *invoker, IUnknown *param, async_oper
|
|||
if ((impl->invoker = invoker)) IUnknown_AddRef( impl->invoker );
|
||||
if ((impl->param = param)) IUnknown_AddRef( impl->param );
|
||||
|
||||
InitializeCriticalSection( &impl->cs );
|
||||
InitializeCriticalSectionEx( &impl->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO );
|
||||
impl->cs.DebugInfo->Spare[0] = (DWORD_PTR)( __FILE__ ": async_info.cs" );
|
||||
|
||||
*out = &impl->IWineAsyncInfoImpl_iface;
|
||||
|
|
|
@ -3204,6 +3204,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
|
|||
D3D11_RASTERIZER_DESC rs_desc;
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
struct d2d_factory *factory;
|
||||
ID3D10Blob *compiled;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -3472,468 +3473,208 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
|
|||
" * float2(transform_rtx.w, transform_rty.w);\n"
|
||||
" o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);\n"
|
||||
"}\n";
|
||||
static const DWORD ps_code[] =
|
||||
{
|
||||
#if 0
|
||||
#define BRUSH_TYPE_SOLID 0
|
||||
#define BRUSH_TYPE_LINEAR 1
|
||||
#define BRUSH_TYPE_RADIAL 2
|
||||
#define BRUSH_TYPE_BITMAP 3
|
||||
#define BRUSH_TYPE_COUNT 4
|
||||
|
||||
bool outline;
|
||||
bool is_arc;
|
||||
struct brush
|
||||
{
|
||||
uint type;
|
||||
float opacity;
|
||||
float4 data[3];
|
||||
} colour_brush, opacity_brush;
|
||||
|
||||
SamplerState s0, s1;
|
||||
Texture2D t0, t1;
|
||||
Buffer<float4> b0, b1;
|
||||
|
||||
struct input
|
||||
{
|
||||
float2 p : WORLD_POSITION;
|
||||
float4 b : BEZIER;
|
||||
nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
|
||||
};
|
||||
|
||||
float4 sample_gradient(Buffer<float4> gradient, uint stop_count, float position)
|
||||
{
|
||||
float4 c_low, c_high;
|
||||
float p_low, p_high;
|
||||
uint i;
|
||||
|
||||
p_low = gradient.Load(0).x;
|
||||
c_low = gradient.Load(1);
|
||||
c_high = c_low;
|
||||
|
||||
if (position < p_low)
|
||||
return c_low;
|
||||
|
||||
for (i = 1; i < stop_count; ++i)
|
||||
{
|
||||
p_high = gradient.Load(i * 2).x;
|
||||
c_high = gradient.Load(i * 2 + 1);
|
||||
|
||||
if (position >= p_low && position <= p_high)
|
||||
return lerp(c_low, c_high, (position - p_low) / (p_high - p_low));
|
||||
|
||||
p_low = p_high;
|
||||
c_low = c_high;
|
||||
}
|
||||
|
||||
return c_high;
|
||||
}
|
||||
|
||||
float4 brush_linear(struct brush brush, Buffer<float4> gradient, float2 position)
|
||||
{
|
||||
float2 start, end, v_p, v_q;
|
||||
uint stop_count;
|
||||
float p;
|
||||
|
||||
start = brush.data[0].xy;
|
||||
end = brush.data[0].zw;
|
||||
stop_count = asuint(brush.data[1].x);
|
||||
|
||||
v_p = position - start;
|
||||
v_q = end - start;
|
||||
p = dot(v_q, v_p) / dot(v_q, v_q);
|
||||
|
||||
return sample_gradient(gradient, stop_count, p);
|
||||
}
|
||||
|
||||
float4 brush_radial(struct brush brush, Buffer<float4> gradient, float2 position)
|
||||
{
|
||||
float2 centre, offset, ra, rb, v_p, v_q, r;
|
||||
float b, c, l, t;
|
||||
uint stop_count;
|
||||
|
||||
centre = brush.data[0].xy;
|
||||
offset = brush.data[0].zw;
|
||||
ra = brush.data[1].xy;
|
||||
rb = brush.data[1].zw;
|
||||
stop_count = asuint(brush.data[2].x);
|
||||
|
||||
/* Project onto ra, rb. */
|
||||
r = float2(dot(ra, ra), dot(rb, rb));
|
||||
v_p = position - (centre + offset);
|
||||
v_p = float2(dot(v_p, ra), dot(v_p, rb)) / r;
|
||||
v_q = float2(dot(offset, ra), dot(offset, rb)) / r;
|
||||
|
||||
/* ‖t·p̂ + q⃑‖ = 1
|
||||
* (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1
|
||||
* t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1
|
||||
*
|
||||
* b = p̂·q⃑
|
||||
* c = q⃑·q⃑ - 1
|
||||
* t = -b + √(b² - c) */
|
||||
l = length(v_p);
|
||||
b = dot(v_p, v_q) / l;
|
||||
c = dot(v_q, v_q) - 1.0;
|
||||
t = -b + sqrt(b * b - c);
|
||||
|
||||
return sample_gradient(gradient, stop_count, l / t);
|
||||
}
|
||||
|
||||
float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position)
|
||||
{
|
||||
float3 transform[2];
|
||||
bool ignore_alpha;
|
||||
float2 texcoord;
|
||||
float4 colour;
|
||||
|
||||
transform[0] = brush.data[0].xyz;
|
||||
transform[1] = brush.data[1].xyz;
|
||||
ignore_alpha = asuint(brush.data[1].w);
|
||||
|
||||
texcoord.x = dot(position.xy, transform[0].xy) + transform[0].z;
|
||||
texcoord.y = dot(position.xy, transform[1].xy) + transform[1].z;
|
||||
colour = t.Sample(s, texcoord);
|
||||
if (ignore_alpha)
|
||||
colour.a = 1.0;
|
||||
return colour;
|
||||
}
|
||||
|
||||
float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer<float4> b, float2 position)
|
||||
{
|
||||
if (brush.type == BRUSH_TYPE_SOLID)
|
||||
return brush.data[0] * brush.opacity;
|
||||
if (brush.type == BRUSH_TYPE_LINEAR)
|
||||
return brush_linear(brush, b, position) * brush.opacity;
|
||||
if (brush.type == BRUSH_TYPE_RADIAL)
|
||||
return brush_radial(brush, b, position) * brush.opacity;
|
||||
if (brush.type == BRUSH_TYPE_BITMAP)
|
||||
return brush_bitmap(brush, t, s, position) * brush.opacity;
|
||||
return float4(0.0, 0.0, 0.0, brush.opacity);
|
||||
}
|
||||
|
||||
float4 main(struct input i) : SV_Target
|
||||
{
|
||||
float4 colour;
|
||||
|
||||
colour = sample_brush(colour_brush, t0, s0, b0, i.p);
|
||||
if (opacity_brush.type < BRUSH_TYPE_COUNT)
|
||||
colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a;
|
||||
|
||||
if (outline)
|
||||
{
|
||||
float2 du, dv, df;
|
||||
float4 uv;
|
||||
|
||||
/* Evaluate the implicit form of the curve (u² - v = 0
|
||||
* for Béziers, u² + v² - 1 = 0 for arcs) in texture
|
||||
* space, using the screen-space partial derivatives
|
||||
* to convert the calculated distance to object space.
|
||||
*
|
||||
* d(x, y) = |f(x, y)| / ‖∇f(x, y)‖
|
||||
* = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²)
|
||||
*
|
||||
* For Béziers:
|
||||
* f(x, y) = u(x, y)² - v(x, y)
|
||||
* ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x
|
||||
* ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y
|
||||
*
|
||||
* For arcs:
|
||||
* f(x, y) = u(x, y)² + v(x, y)² - 1
|
||||
* ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x
|
||||
* ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */
|
||||
uv = i.b;
|
||||
du = float2(ddx(uv.x), ddy(uv.x));
|
||||
dv = float2(ddx(uv.y), ddy(uv.y));
|
||||
|
||||
if (!is_arc)
|
||||
{
|
||||
df = 2.0f * uv.x * du - dv;
|
||||
|
||||
clip(dot(df, uv.zw));
|
||||
clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
df = 2.0f * uv.x * du + 2.0f * uv.y * dv;
|
||||
|
||||
clip(dot(df, uv.zw));
|
||||
clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Evaluate the implicit form of the curve in texture space.
|
||||
* "i.b.z" determines which side of the curve is shaded. */
|
||||
if (!is_arc)
|
||||
{
|
||||
clip((i.b.x * i.b.x - i.b.y) * i.b.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z);
|
||||
}
|
||||
}
|
||||
|
||||
return colour;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xa8fee730, 0x92fa2196, 0xaf9f3eff, 0x888d4048, 0x00000001, 0x00002000, 0x00000003,
|
||||
0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000,
|
||||
0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
|
||||
0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57,
|
||||
0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e,
|
||||
0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
|
||||
0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001f00,
|
||||
0x00000040, 0x000007c0, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000,
|
||||
0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
|
||||
0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555,
|
||||
0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062,
|
||||
0x001010f2, 0x00000001, 0x03000862, 0x00101032, 0x00000002, 0x03000862, 0x00101032, 0x00000003,
|
||||
0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x0000000a, 0x09000038, 0x001000f2, 0x00000000,
|
||||
0x00208556, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0404001f, 0x0020800a,
|
||||
0x00000000, 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001,
|
||||
0x00004001, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x09000000, 0x00100062, 0x00000001,
|
||||
0x00101106, 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000002, 0x0a000000, 0x00100032,
|
||||
0x00000002, 0x80208046, 0x00000041, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000002,
|
||||
0x0700000f, 0x00100022, 0x00000001, 0x00100046, 0x00000002, 0x00100596, 0x00000001, 0x0700000f,
|
||||
0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100022,
|
||||
0x00000001, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
|
||||
0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
|
||||
0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
|
||||
0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
|
||||
0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
|
||||
0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
|
||||
0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
|
||||
0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
|
||||
0x00000000, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
|
||||
0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
|
||||
0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
|
||||
0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
|
||||
0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
|
||||
0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
|
||||
0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
|
||||
0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
|
||||
0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
|
||||
0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
|
||||
0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
|
||||
0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
|
||||
0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
|
||||
0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
|
||||
0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
|
||||
0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
|
||||
0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
|
||||
0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
|
||||
0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
|
||||
0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
|
||||
0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
|
||||
0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
|
||||
0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0900000f, 0x00100012, 0x00000002, 0x00208046,
|
||||
0x00000000, 0x00000003, 0x00208046, 0x00000000, 0x00000003, 0x0900000f, 0x00100022, 0x00000002,
|
||||
0x00208ae6, 0x00000000, 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000000, 0x00100062,
|
||||
0x00000001, 0x00208ba6, 0x00000000, 0x00000002, 0x00208106, 0x00000000, 0x00000002, 0x08000000,
|
||||
0x00100062, 0x00000001, 0x80100656, 0x00000041, 0x00000001, 0x00101106, 0x00000000, 0x0800000f,
|
||||
0x00100012, 0x00000003, 0x00100596, 0x00000001, 0x00208046, 0x00000000, 0x00000003, 0x0800000f,
|
||||
0x00100022, 0x00000003, 0x00100596, 0x00000001, 0x00208ae6, 0x00000000, 0x00000003, 0x0700000e,
|
||||
0x00100062, 0x00000001, 0x00100106, 0x00000003, 0x00100106, 0x00000002, 0x0900000f, 0x00100012,
|
||||
0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x0900000f,
|
||||
0x00100022, 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000003,
|
||||
0x0700000e, 0x00100032, 0x00000002, 0x00100046, 0x00000003, 0x00100046, 0x00000002, 0x0700000f,
|
||||
0x00100082, 0x00000001, 0x00100596, 0x00000001, 0x00100596, 0x00000001, 0x0500004b, 0x00100082,
|
||||
0x00000001, 0x0010003a, 0x00000001, 0x0700000f, 0x00100022, 0x00000001, 0x00100596, 0x00000001,
|
||||
0x00100046, 0x00000002, 0x0700000e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001, 0x0010003a,
|
||||
0x00000001, 0x0700000f, 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002,
|
||||
0x07000000, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x00004001, 0xbf800000, 0x0a000032,
|
||||
0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010001a, 0x00000001, 0x8010002a, 0x00000041,
|
||||
0x00000001, 0x0500004b, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100022,
|
||||
0x00000001, 0x0010002a, 0x00000001, 0x8010001a, 0x00000041, 0x00000001, 0x0700000e, 0x00100022,
|
||||
0x00000001, 0x0010003a, 0x00000001, 0x0010001a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
|
||||
0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
|
||||
0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
|
||||
0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
|
||||
0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
|
||||
0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
|
||||
0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
|
||||
0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
|
||||
0x00000000, 0x00000004, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
|
||||
0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
|
||||
0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
|
||||
0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
|
||||
0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
|
||||
0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
|
||||
0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
|
||||
0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
|
||||
0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
|
||||
0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
|
||||
0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
|
||||
0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
|
||||
0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
|
||||
0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
|
||||
0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
|
||||
0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
|
||||
0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
|
||||
0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
|
||||
0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
|
||||
0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
|
||||
0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
|
||||
0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
|
||||
0x00000003, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
|
||||
0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002, 0x0010001a,
|
||||
0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
|
||||
0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002, 0x0010001a,
|
||||
0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046,
|
||||
0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082, 0x00000002,
|
||||
0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038,
|
||||
0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001, 0x01000015,
|
||||
0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082, 0x00000002,
|
||||
0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000001,
|
||||
0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x01000015, 0x01000015, 0x0800004f,
|
||||
0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000004, 0x0304001f,
|
||||
0x0010000a, 0x00000001, 0x09000038, 0x00100012, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
|
||||
0x0020803a, 0x00000000, 0x00000006, 0x0404001f, 0x0020800a, 0x00000000, 0x00000005, 0x08000020,
|
||||
0x00100022, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000001, 0x0304001f,
|
||||
0x0010001a, 0x00000001, 0x09000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000000, 0x80208406,
|
||||
0x00000041, 0x00000000, 0x00000006, 0x0a000000, 0x00100032, 0x00000002, 0x80208046, 0x00000041,
|
||||
0x00000000, 0x00000006, 0x00208ae6, 0x00000000, 0x00000006, 0x0700000f, 0x00100042, 0x00000001,
|
||||
0x00100046, 0x00000002, 0x00100ae6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100046,
|
||||
0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000001,
|
||||
0x0010003a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002,
|
||||
0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082,
|
||||
0x00000001, 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001,
|
||||
0x05000036, 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002,
|
||||
0x00100ff6, 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036,
|
||||
0x00100032, 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030,
|
||||
0x08000050, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000007,
|
||||
0x05000036, 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003,
|
||||
0x07000029, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d,
|
||||
0x001000f2, 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042,
|
||||
0x00000003, 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005,
|
||||
0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a,
|
||||
0x00000001, 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004,
|
||||
0x0010002a, 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a,
|
||||
0x00000004, 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a,
|
||||
0x00000001, 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a,
|
||||
0x00000041, 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a,
|
||||
0x00000004, 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041,
|
||||
0x00000002, 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
|
||||
0x0010002a, 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a,
|
||||
0x00000005, 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082,
|
||||
0x00000001, 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002,
|
||||
0x0010003a, 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e,
|
||||
0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042,
|
||||
0x00000002, 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003,
|
||||
0x01000016, 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001,
|
||||
0x0010002a, 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003,
|
||||
0x01000015, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000,
|
||||
0x00000005, 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001,
|
||||
0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001,
|
||||
0x0900000f, 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000007, 0x00208046, 0x00000000,
|
||||
0x00000007, 0x0900000f, 0x00100022, 0x00000002, 0x00208ae6, 0x00000000, 0x00000007, 0x00208ae6,
|
||||
0x00000000, 0x00000007, 0x09000000, 0x001000c2, 0x00000001, 0x00208ea6, 0x00000000, 0x00000006,
|
||||
0x00208406, 0x00000000, 0x00000006, 0x08000000, 0x001000c2, 0x00000001, 0x80100ea6, 0x00000041,
|
||||
0x00000001, 0x00101406, 0x00000000, 0x0800000f, 0x00100012, 0x00000003, 0x00100ae6, 0x00000001,
|
||||
0x00208046, 0x00000000, 0x00000007, 0x0800000f, 0x00100022, 0x00000003, 0x00100ae6, 0x00000001,
|
||||
0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x001000c2, 0x00000001, 0x00100406, 0x00000003,
|
||||
0x00100406, 0x00000002, 0x0900000f, 0x00100012, 0x00000003, 0x00208ae6, 0x00000000, 0x00000006,
|
||||
0x00208046, 0x00000000, 0x00000007, 0x0900000f, 0x00100022, 0x00000003, 0x00208ae6, 0x00000000,
|
||||
0x00000006, 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x00100032, 0x00000002, 0x00100046,
|
||||
0x00000003, 0x00100046, 0x00000002, 0x0700000f, 0x00100042, 0x00000002, 0x00100ae6, 0x00000001,
|
||||
0x00100ae6, 0x00000001, 0x0500004b, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x0700000f,
|
||||
0x00100042, 0x00000001, 0x00100ae6, 0x00000001, 0x00100046, 0x00000002, 0x0700000e, 0x00100042,
|
||||
0x00000001, 0x0010002a, 0x00000001, 0x0010002a, 0x00000002, 0x0700000f, 0x00100082, 0x00000001,
|
||||
0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x07000000, 0x00100082, 0x00000001, 0x0010003a,
|
||||
0x00000001, 0x00004001, 0xbf800000, 0x0a000032, 0x00100082, 0x00000001, 0x0010002a, 0x00000001,
|
||||
0x0010002a, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, 0x0500004b, 0x00100082, 0x00000001,
|
||||
0x0010003a, 0x00000001, 0x08000000, 0x00100042, 0x00000001, 0x0010003a, 0x00000001, 0x8010002a,
|
||||
0x00000041, 0x00000001, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000002, 0x0010002a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, 0x00000001,
|
||||
0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, 0x00000001,
|
||||
0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, 0x05000036,
|
||||
0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002, 0x00100ff6,
|
||||
0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036, 0x00100032,
|
||||
0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050,
|
||||
0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000008, 0x05000036,
|
||||
0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, 0x07000029,
|
||||
0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2,
|
||||
0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, 0x00000003,
|
||||
0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, 0x00100aa6,
|
||||
0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, 0x00000001,
|
||||
0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, 0x0010002a,
|
||||
0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, 0x00000004,
|
||||
0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, 0x00000001,
|
||||
0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a, 0x00000041,
|
||||
0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
|
||||
0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041, 0x00000002,
|
||||
0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, 0x0010002a,
|
||||
0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, 0x00000005,
|
||||
0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, 0x00000001,
|
||||
0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, 0x0010003a,
|
||||
0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e, 0x00100012,
|
||||
0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042, 0x00000002,
|
||||
0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, 0x01000016,
|
||||
0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, 0x0010002a,
|
||||
0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, 0x01000015,
|
||||
0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
|
||||
0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, 0x0020800a,
|
||||
0x00000000, 0x00000005, 0x00004001, 0x00000003, 0x0304001f, 0x0010001a, 0x00000001, 0x0800000f,
|
||||
0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000006, 0x08000000,
|
||||
0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000006, 0x0800000f,
|
||||
0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000007, 0x08000000,
|
||||
0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000007, 0x09000045,
|
||||
0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001,
|
||||
0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000007, 0x00004001, 0x3f800000,
|
||||
0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a,
|
||||
0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001,
|
||||
0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015,
|
||||
0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012,
|
||||
0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0404001f, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x0500000b, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0500000c,
|
||||
0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x08000027, 0x00100012, 0x00000001, 0x0020801a,
|
||||
0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000001, 0x0010000a,
|
||||
0x00000001, 0x07000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x00101406, 0x00000001,
|
||||
0x07000038, 0x001000f2, 0x00000002, 0x00100d86, 0x00000000, 0x00100fa6, 0x00000001, 0x0a000032,
|
||||
0x00100032, 0x00000000, 0x00100aa6, 0x00000001, 0x00100086, 0x00000000, 0x801005d6, 0x00000041,
|
||||
0x00000000, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00101ae6, 0x00000001,
|
||||
0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
|
||||
0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x0010002a, 0x00000000, 0x0304000d, 0x0010002a,
|
||||
0x00000000, 0x07000038, 0x00100062, 0x00000000, 0x00100556, 0x00000000, 0x00101106, 0x00000003,
|
||||
0x09000032, 0x00100032, 0x00000000, 0x00101046, 0x00000002, 0x00100006, 0x00000000, 0x00100596,
|
||||
0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000,
|
||||
0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100062, 0x00000000,
|
||||
0x00101106, 0x00000001, 0x00101106, 0x00000001, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a,
|
||||
0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100012,
|
||||
0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000,
|
||||
0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000000,
|
||||
0x00100092, 0x00000000, 0x00100ea6, 0x00000002, 0x00100406, 0x00000002, 0x0700000f, 0x00100022,
|
||||
0x00000001, 0x001000c6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100022, 0x00000001,
|
||||
0x0010001a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000001, 0x0010000a,
|
||||
0x00000001, 0x0010001a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000001, 0x07000038, 0x00100062,
|
||||
0x00000001, 0x00100ff6, 0x00000000, 0x00101106, 0x00000003, 0x09000032, 0x00100092, 0x00000000,
|
||||
0x00101406, 0x00000002, 0x00100006, 0x00000000, 0x00100956, 0x00000001, 0x0700000f, 0x00100012,
|
||||
0x00000000, 0x001000c6, 0x00000000, 0x001000c6, 0x00000000, 0x0500004b, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
|
||||
0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000,
|
||||
0x08000000, 0x00100012, 0x00000000, 0x8010001a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a,
|
||||
0x00000000, 0x01000012, 0x08000027, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
|
||||
0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x07000038,
|
||||
0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x00101406, 0x00000001, 0x0a000032, 0x00100012,
|
||||
0x00000001, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001,
|
||||
0x07000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x0010102a, 0x00000001, 0x07000031,
|
||||
0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022,
|
||||
0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000000,
|
||||
0x07000000, 0x00100022, 0x00000000, 0x0010003a, 0x00000000, 0x0010002a, 0x00000000, 0x07000000,
|
||||
0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022,
|
||||
0x00000000, 0x0010001a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000,
|
||||
0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010001a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e,
|
||||
};
|
||||
static const char ps_code[] =
|
||||
"#define BRUSH_TYPE_SOLID 0\n"
|
||||
"#define BRUSH_TYPE_LINEAR 1\n"
|
||||
"#define BRUSH_TYPE_RADIAL 2\n"
|
||||
"#define BRUSH_TYPE_BITMAP 3\n"
|
||||
"#define BRUSH_TYPE_COUNT 4\n"
|
||||
"\n"
|
||||
"bool outline;\n"
|
||||
"bool is_arc;\n"
|
||||
"struct brush\n"
|
||||
"{\n"
|
||||
" uint type;\n"
|
||||
" float opacity;\n"
|
||||
" float4 data[3];\n"
|
||||
"} colour_brush, opacity_brush;\n"
|
||||
"\n"
|
||||
"SamplerState s0, s1;\n"
|
||||
"Texture2D t0, t1;\n"
|
||||
"Buffer<float4> b0, b1;\n"
|
||||
"\n"
|
||||
"struct input\n"
|
||||
"{\n"
|
||||
" float2 p : WORLD_POSITION;\n"
|
||||
" float4 b : BEZIER;\n"
|
||||
" nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 sample_gradient(Buffer<float4> gradient, uint stop_count, float position)\n"
|
||||
"{\n"
|
||||
" float4 c_low, c_high;\n"
|
||||
" float p_low, p_high;\n"
|
||||
" uint i;\n"
|
||||
"\n"
|
||||
" p_low = gradient.Load(0).x;\n"
|
||||
" c_low = gradient.Load(1);\n"
|
||||
" c_high = c_low;\n"
|
||||
"\n"
|
||||
" if (position < p_low)\n"
|
||||
" return c_low;\n"
|
||||
"\n"
|
||||
" for (i = 1; i < stop_count; ++i)\n"
|
||||
" {\n"
|
||||
" p_high = gradient.Load(i * 2).x;\n"
|
||||
" c_high = gradient.Load(i * 2 + 1);\n"
|
||||
"\n"
|
||||
" if (position >= p_low && position <= p_high)\n"
|
||||
" return lerp(c_low, c_high, (position - p_low) / (p_high - p_low));\n"
|
||||
"\n"
|
||||
" p_low = p_high;\n"
|
||||
" c_low = c_high;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return c_high;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 brush_linear(struct brush brush, Buffer<float4> gradient, float2 position)\n"
|
||||
"{\n"
|
||||
" float2 start, end, v_p, v_q;\n"
|
||||
" uint stop_count;\n"
|
||||
" float p;\n"
|
||||
"\n"
|
||||
" start = brush.data[0].xy;\n"
|
||||
" end = brush.data[0].zw;\n"
|
||||
" stop_count = asuint(brush.data[1].x);\n"
|
||||
"\n"
|
||||
" v_p = position - start;\n"
|
||||
" v_q = end - start;\n"
|
||||
" p = dot(v_q, v_p) / dot(v_q, v_q);\n"
|
||||
"\n"
|
||||
" return sample_gradient(gradient, stop_count, p);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 brush_radial(struct brush brush, Buffer<float4> gradient, float2 position)\n"
|
||||
"{\n"
|
||||
" float2 centre, offset, ra, rb, v_p, v_q, r;\n"
|
||||
" float b, c, l, t;\n"
|
||||
" uint stop_count;\n"
|
||||
"\n"
|
||||
" centre = brush.data[0].xy;\n"
|
||||
" offset = brush.data[0].zw;\n"
|
||||
" ra = brush.data[1].xy;\n"
|
||||
" rb = brush.data[1].zw;\n"
|
||||
" stop_count = asuint(brush.data[2].x);\n"
|
||||
"\n"
|
||||
" /* Project onto ra, rb. */\n"
|
||||
" r = float2(dot(ra, ra), dot(rb, rb));\n"
|
||||
" v_p = position - (centre + offset);\n"
|
||||
" v_p = float2(dot(v_p, ra), dot(v_p, rb)) / r;\n"
|
||||
" v_q = float2(dot(offset, ra), dot(offset, rb)) / r;\n"
|
||||
"\n"
|
||||
" /* ‖t·p̂ + q⃑‖ = 1\n"
|
||||
" * (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1\n"
|
||||
" * t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1\n"
|
||||
" *\n"
|
||||
" * b = p̂·q⃑\n"
|
||||
" * c = q⃑·q⃑ - 1\n"
|
||||
" * t = -b + √(b² - c) */\n"
|
||||
" l = length(v_p);\n"
|
||||
" b = dot(v_p, v_q) / l;\n"
|
||||
" c = dot(v_q, v_q) - 1.0;\n"
|
||||
" t = -b + sqrt(b * b - c);\n"
|
||||
"\n"
|
||||
" return sample_gradient(gradient, stop_count, l / t);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position)\n"
|
||||
"{\n"
|
||||
" float3 transform[2];\n"
|
||||
" bool ignore_alpha;\n"
|
||||
" float2 texcoord;\n"
|
||||
" float4 colour;\n"
|
||||
"\n"
|
||||
" transform[0] = brush.data[0].xyz;\n"
|
||||
" transform[1] = brush.data[1].xyz;\n"
|
||||
" ignore_alpha = asuint(brush.data[1].w);\n"
|
||||
"\n"
|
||||
" texcoord.x = dot(position.xy, transform[0].xy) + transform[0].z;\n"
|
||||
" texcoord.y = dot(position.xy, transform[1].xy) + transform[1].z;\n"
|
||||
" colour = t.Sample(s, texcoord);\n"
|
||||
" if (ignore_alpha)\n"
|
||||
" colour.a = 1.0;\n"
|
||||
" return colour;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer<float4> b, float2 position)\n"
|
||||
"{\n"
|
||||
" if (brush.type == BRUSH_TYPE_SOLID)\n"
|
||||
" return brush.data[0] * brush.opacity;\n"
|
||||
" if (brush.type == BRUSH_TYPE_LINEAR)\n"
|
||||
" return brush_linear(brush, b, position) * brush.opacity;\n"
|
||||
" if (brush.type == BRUSH_TYPE_RADIAL)\n"
|
||||
" return brush_radial(brush, b, position) * brush.opacity;\n"
|
||||
" if (brush.type == BRUSH_TYPE_BITMAP)\n"
|
||||
" return brush_bitmap(brush, t, s, position) * brush.opacity;\n"
|
||||
" return float4(0.0, 0.0, 0.0, brush.opacity);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"float4 main(struct input i) : SV_Target\n"
|
||||
"{\n"
|
||||
" float4 colour;\n"
|
||||
"\n"
|
||||
" colour = sample_brush(colour_brush, t0, s0, b0, i.p);\n"
|
||||
" if (opacity_brush.type < BRUSH_TYPE_COUNT)\n"
|
||||
" colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a;\n"
|
||||
"\n"
|
||||
" if (outline)\n"
|
||||
" {\n"
|
||||
" float2 du, dv, df;\n"
|
||||
" float4 uv;\n"
|
||||
"\n"
|
||||
" /* Evaluate the implicit form of the curve (u² - v = 0\n"
|
||||
" * for Béziers, u² + v² - 1 = 0 for arcs) in texture\n"
|
||||
" * space, using the screen-space partial derivatives\n"
|
||||
" * to convert the calculated distance to object space.\n"
|
||||
" *\n"
|
||||
" * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖\n"
|
||||
" * = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²)\n"
|
||||
" *\n"
|
||||
" * For Béziers:\n"
|
||||
" * f(x, y) = u(x, y)² - v(x, y)\n"
|
||||
" * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x\n"
|
||||
" * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y\n"
|
||||
" *\n"
|
||||
" * For arcs:\n"
|
||||
" * f(x, y) = u(x, y)² + v(x, y)² - 1\n"
|
||||
" * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x\n"
|
||||
" * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */\n"
|
||||
" uv = i.b;\n"
|
||||
" du = float2(ddx(uv.x), ddy(uv.x));\n"
|
||||
" dv = float2(ddx(uv.y), ddy(uv.y));\n"
|
||||
"\n"
|
||||
" if (!is_arc)\n"
|
||||
" {\n"
|
||||
" df = 2.0f * uv.x * du - dv;\n"
|
||||
"\n"
|
||||
" clip(dot(df, uv.zw));\n"
|
||||
" clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" df = 2.0f * uv.x * du + 2.0f * uv.y * dv;\n"
|
||||
"\n"
|
||||
" clip(dot(df, uv.zw));\n"
|
||||
" clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f));\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" /* Evaluate the implicit form of the curve in texture space.\n"
|
||||
" * \"i.b.z\" determines which side of the curve is shaded. */\n"
|
||||
" if (!is_arc)\n"
|
||||
" {\n"
|
||||
" clip((i.b.x * i.b.x - i.b.y) * i.b.z);\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return colour;\n"
|
||||
"}\n";
|
||||
static const struct shape_info
|
||||
{
|
||||
enum d2d_shape_type shape_type;
|
||||
|
@ -4005,7 +3746,6 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
|
|||
for (i = 0; i < ARRAY_SIZE(shape_info); ++i)
|
||||
{
|
||||
const struct shape_info *si = &shape_info[i];
|
||||
ID3D10Blob *compiled;
|
||||
|
||||
if (FAILED(hr = D3DCompile(si->vs_code, si->vs_code_size, si->name, NULL, NULL,
|
||||
"main", "vs_4_0", 0, 0, &compiled, NULL)))
|
||||
|
@ -4048,13 +3788,23 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (FAILED(hr = ID3D11Device1_CreatePixelShader(render_target->d3d_device,
|
||||
ps_code, sizeof(ps_code), NULL, &render_target->ps)))
|
||||
if (FAILED(hr = D3DCompile(ps_code, sizeof(ps_code) - 1, "ps", NULL, NULL, "main", "ps_4_0", 0, 0, &compiled, NULL)))
|
||||
{
|
||||
WARN("Failed to create pixel shader, hr %#lx.\n", hr);
|
||||
WARN("Failed to compile the pixel shader, hr %#lx.\n", hr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (FAILED(hr = ID3D11Device1_CreatePixelShader(render_target->d3d_device,
|
||||
ID3D10Blob_GetBufferPointer(compiled), ID3D10Blob_GetBufferSize(compiled),
|
||||
NULL, &render_target->ps)))
|
||||
{
|
||||
WARN("Failed to create pixel shader, hr %#lx.\n", hr);
|
||||
ID3D10Blob_Release(compiled);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ID3D10Blob_Release(compiled);
|
||||
|
||||
buffer_desc.ByteWidth = sizeof(struct d2d_ps_cb);
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
|
@ -4224,7 +3974,6 @@ HRESULT d2d_d3d_create_render_target(struct d2d_device *device, IDXGISurface *su
|
|||
{
|
||||
WARN("Failed to create target bitmap, hr %#lx.\n", hr);
|
||||
IUnknown_Release(&object->IUnknown_iface);
|
||||
free(object);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ static HRESULT STDMETHODCALLTYPE builtin_factory_stub(IUnknown **effect_impl)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static const WCHAR * const _2d_affine_transform_description =
|
||||
static const WCHAR _2d_affine_transform_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='2D Affine Transform'/> \
|
||||
|
@ -223,7 +223,7 @@ L"<?xml version='1.0'?> \
|
|||
</Inputs> \
|
||||
</Effect>";
|
||||
|
||||
static const WCHAR * const _3d_perspective_transform_description =
|
||||
static const WCHAR _3d_perspective_transform_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='3D Perspective Transform'/> \
|
||||
|
@ -235,7 +235,7 @@ L"<?xml version='1.0'?>
|
|||
</Inputs> \
|
||||
</Effect>";
|
||||
|
||||
static const WCHAR * const composite_description =
|
||||
static const WCHAR composite_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='Composite'/> \
|
||||
|
@ -248,7 +248,7 @@ L"<?xml version='1.0'?> \
|
|||
</Inputs> \
|
||||
</Effect>";
|
||||
|
||||
static const WCHAR * const crop_description =
|
||||
static const WCHAR crop_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='Crop'/> \
|
||||
|
@ -260,7 +260,7 @@ L"<?xml version='1.0'?> \
|
|||
</Inputs> \
|
||||
</Effect>";
|
||||
|
||||
static const WCHAR * const shadow_description =
|
||||
static const WCHAR shadow_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='Shadow'/> \
|
||||
|
@ -272,7 +272,7 @@ L"<?xml version='1.0'?> \
|
|||
</Inputs> \
|
||||
</Effect>";
|
||||
|
||||
static const WCHAR * const grayscale_description =
|
||||
static const WCHAR grayscale_description[] =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='Grayscale'/> \
|
||||
|
@ -361,25 +361,25 @@ static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties *
|
|||
{
|
||||
static const UINT32 sizes[] =
|
||||
{
|
||||
0, /* D2D1_PROPERTY_TYPE_UNKNOWN */
|
||||
0, /* D2D1_PROPERTY_TYPE_STRING */
|
||||
sizeof(BOOL), /* D2D1_PROPERTY_TYPE_BOOL */
|
||||
sizeof(UINT32), /* D2D1_PROPERTY_TYPE_UINT32 */
|
||||
sizeof(INT32), /* D2D1_PROPERTY_TYPE_INT32 */
|
||||
sizeof(float), /* D2D1_PROPERTY_TYPE_FLOAT */
|
||||
2 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR2 */
|
||||
3 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR3 */
|
||||
4 * sizeof(float), /* D2D1_PROPERTY_TYPE_VECTOR4 */
|
||||
0, /* FIXME: D2D1_PROPERTY_TYPE_BLOB */
|
||||
sizeof(void *), /* D2D1_PROPERTY_TYPE_IUNKNOWN */
|
||||
sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ENUM */
|
||||
sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ARRAY */
|
||||
sizeof(CLSID), /* D2D1_PROPERTY_TYPE_CLSID */
|
||||
6 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */
|
||||
12 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */
|
||||
16 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X4 */
|
||||
20 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_5X4 */
|
||||
sizeof(void *), /* D2D1_PROPERTY_TYPE_COLOR_CONTEXT */
|
||||
[D2D1_PROPERTY_TYPE_UNKNOWN] = 0,
|
||||
[D2D1_PROPERTY_TYPE_STRING] = 0,
|
||||
[D2D1_PROPERTY_TYPE_BOOL] = sizeof(BOOL),
|
||||
[D2D1_PROPERTY_TYPE_UINT32] = sizeof(UINT32),
|
||||
[D2D1_PROPERTY_TYPE_INT32] = sizeof(INT32),
|
||||
[D2D1_PROPERTY_TYPE_FLOAT] = sizeof(float),
|
||||
[D2D1_PROPERTY_TYPE_VECTOR2] = sizeof(D2D_VECTOR_2F),
|
||||
[D2D1_PROPERTY_TYPE_VECTOR3] = sizeof(D2D_VECTOR_3F),
|
||||
[D2D1_PROPERTY_TYPE_VECTOR4] = sizeof(D2D_VECTOR_4F),
|
||||
[D2D1_PROPERTY_TYPE_BLOB] = 0 /* FIXME */,
|
||||
[D2D1_PROPERTY_TYPE_IUNKNOWN] = sizeof(IUnknown *),
|
||||
[D2D1_PROPERTY_TYPE_ENUM] = sizeof(UINT32),
|
||||
[D2D1_PROPERTY_TYPE_ARRAY] = sizeof(UINT32),
|
||||
[D2D1_PROPERTY_TYPE_CLSID] = sizeof(CLSID),
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_3X2] = sizeof(D2D_MATRIX_3X2_F),
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_4X3] = sizeof(D2D_MATRIX_4X3_F),
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_4X4] = sizeof(D2D_MATRIX_4X4_F),
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_5X4] = sizeof(D2D_MATRIX_5X4_F),
|
||||
[D2D1_PROPERTY_TYPE_COLOR_CONTEXT] = sizeof(ID2D1ColorContext *),
|
||||
};
|
||||
struct d2d_effect_property *p;
|
||||
HRESULT hr;
|
||||
|
@ -813,7 +813,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadPixelShader(ID2D1EffectC
|
|||
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
|
||||
iface, debugstr_guid(shader_id), buffer, buffer_size);
|
||||
|
||||
if (ID2D1EffectContext_IsShaderLoaded(iface, shader_id))
|
||||
if (d2d_device_is_shader_loaded(effect_context->device_context->device, shader_id))
|
||||
return S_OK;
|
||||
|
||||
if (FAILED(hr = ID3D11Device1_CreatePixelShader(effect_context->device_context->d3d_device,
|
||||
|
@ -839,7 +839,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadVertexShader(ID2D1Effect
|
|||
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
|
||||
iface, debugstr_guid(shader_id), buffer, buffer_size);
|
||||
|
||||
if (ID2D1EffectContext_IsShaderLoaded(iface, shader_id))
|
||||
if (d2d_device_is_shader_loaded(effect_context->device_context->device, shader_id))
|
||||
return S_OK;
|
||||
|
||||
if (FAILED(hr = ID3D11Device1_CreateVertexShader(effect_context->device_context->d3d_device,
|
||||
|
@ -865,7 +865,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadComputeShader(ID2D1Effec
|
|||
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
|
||||
iface, debugstr_guid(shader_id), buffer, buffer_size);
|
||||
|
||||
if (ID2D1EffectContext_IsShaderLoaded(iface, shader_id))
|
||||
if (d2d_device_is_shader_loaded(effect_context->device_context->device, shader_id))
|
||||
return S_OK;
|
||||
|
||||
if (FAILED(hr = ID3D11Device1_CreateComputeShader(effect_context->device_context->d3d_device,
|
||||
|
|
|
@ -677,25 +677,25 @@ static HRESULT parse_effect_get_property_type(IXmlReader *reader, D2D1_PROPERTY_
|
|||
{
|
||||
static const WCHAR *types[] =
|
||||
{
|
||||
L"", /* D2D1_PROPERTY_TYPE_UNKNOWN */
|
||||
L"string", /* D2D1_PROPERTY_TYPE_STRING */
|
||||
L"bool", /* D2D1_PROPERTY_TYPE_BOOL */
|
||||
L"uint32", /* D2D1_PROPERTY_TYPE_UINT32 */
|
||||
L"int32", /* D2D1_PROPERTY_TYPE_INT32 */
|
||||
L"float", /* D2D1_PROPERTY_TYPE_FLOAT */
|
||||
L"vector2", /* D2D1_PROPERTY_TYPE_VECTOR2 */
|
||||
L"vector3", /* D2D1_PROPERTY_TYPE_VECTOR3 */
|
||||
L"vector4", /* D2D1_PROPERTY_TYPE_VECTOR4 */
|
||||
L"blob", /* D2D1_PROPERTY_TYPE_BLOB */
|
||||
L"iunknown", /* D2D1_PROPERTY_TYPE_IUNKNOWN */
|
||||
L"enum", /* D2D1_PROPERTY_TYPE_ENUM */
|
||||
L"array", /* D2D1_PROPERTY_TYPE_ARRAY */
|
||||
L"clsid", /* D2D1_PROPERTY_TYPE_CLSID */
|
||||
L"matrix3x2", /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */
|
||||
L"matrix4x3", /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */
|
||||
L"matrix4x4", /* D2D1_PROPERTY_TYPE_MATRIX_4X4 */
|
||||
L"matrix5x4", /* D2D1_PROPERTY_TYPE_MATRIX_5X4 */
|
||||
L"colorcontext", /* D2D1_PROPERTY_TYPE_COLOR_CONTEXT */
|
||||
[D2D1_PROPERTY_TYPE_UNKNOWN] = L"",
|
||||
[D2D1_PROPERTY_TYPE_STRING] = L"string",
|
||||
[D2D1_PROPERTY_TYPE_BOOL] = L"bool",
|
||||
[D2D1_PROPERTY_TYPE_UINT32] = L"uint32",
|
||||
[D2D1_PROPERTY_TYPE_INT32] = L"int32",
|
||||
[D2D1_PROPERTY_TYPE_FLOAT] = L"float",
|
||||
[D2D1_PROPERTY_TYPE_VECTOR2] = L"vector2",
|
||||
[D2D1_PROPERTY_TYPE_VECTOR3] = L"vector3",
|
||||
[D2D1_PROPERTY_TYPE_VECTOR4] = L"vector4",
|
||||
[D2D1_PROPERTY_TYPE_BLOB] = L"blob",
|
||||
[D2D1_PROPERTY_TYPE_IUNKNOWN] = L"iunknown",
|
||||
[D2D1_PROPERTY_TYPE_ENUM] = L"enum",
|
||||
[D2D1_PROPERTY_TYPE_ARRAY] = L"array",
|
||||
[D2D1_PROPERTY_TYPE_CLSID] = L"clsid",
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_3X2] = L"matrix3x2",
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_4X3] = L"matrix4x3",
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_4X4] = L"matrix4x4",
|
||||
[D2D1_PROPERTY_TYPE_MATRIX_5X4] = L"matrix5x4",
|
||||
[D2D1_PROPERTY_TYPE_COLOR_CONTEXT] = L"colorcontext",
|
||||
};
|
||||
unsigned int i;
|
||||
WCHAR *value;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
TESTDLL = d2d1.dll
|
||||
IMPORTS = d2d1 d3d10_1 d3d11 dwrite dxguid uuid user32 advapi32 ole32 gdi32
|
||||
IMPORTS = d2d1 d3d10_1 d3d11 dwrite dxguid uuid user32 advapi32 ole32 gdi32 d3dcompiler
|
||||
|
||||
SOURCES = \
|
||||
d2d1.c
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include "d3dcompiler.h"
|
||||
#include "d2d1_3.h"
|
||||
#include "d2d1effectauthor.h"
|
||||
#include "d3d11.h"
|
||||
|
@ -247,38 +248,17 @@ L"<?xml version='1.0'?> \
|
|||
</Effect> \
|
||||
";
|
||||
|
||||
static const DWORD test_vs[] =
|
||||
{
|
||||
#if 0
|
||||
void main(float4 pos : Position, out float4 output : SV_Position)
|
||||
{
|
||||
output = pos;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xa84b398b, 0xc4047d32, 0xc19c67bb, 0x4644285e, 0x00000001, 0x000000d8, 0x00000003,
|
||||
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
|
||||
0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x69736f50, 0x6e6f6974, 0xababab00,
|
||||
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
|
||||
0x00000000, 0x0000000f, 0x505f5653, 0x7469736f, 0x006e6f69, 0x52444853, 0x0000003c, 0x00010040,
|
||||
0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
|
||||
0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
|
||||
};
|
||||
static const char test_vs_code[] =
|
||||
"void main(float4 pos : Position, out float4 output : SV_Position)\n"
|
||||
"{\n"
|
||||
" output = pos;\n"
|
||||
"}";
|
||||
|
||||
static const DWORD test_ps[] =
|
||||
{
|
||||
#if 0
|
||||
float4 main() : SV_Target
|
||||
{
|
||||
return float4(0.1, 0.2, 0.3, 0.4);
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xf34300ae, 0x22fc6d56, 0x5cca66fa, 0x86ae3266, 0x00000001, 0x000000b0, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
|
||||
0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000038, 0x00000040, 0x0000000e,
|
||||
0x03000065, 0x001020f2, 0x00000000, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x3dcccccd,
|
||||
0x3e4ccccd, 0x3e99999a, 0x3ecccccd, 0x0100003e,
|
||||
};
|
||||
static const char test_ps_code[] =
|
||||
"float4 main() : SV_Target\n"
|
||||
"{\n"
|
||||
" return float4(0.1, 0.2, 0.3, 0.4);\n"
|
||||
"}";
|
||||
|
||||
static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device,
|
||||
const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device);
|
||||
|
@ -377,10 +357,12 @@ struct expected_geometry_figure
|
|||
struct effect_impl
|
||||
{
|
||||
ID2D1EffectImpl ID2D1EffectImpl_iface;
|
||||
ID2D1DrawTransform ID2D1DrawTransform_iface;
|
||||
LONG refcount;
|
||||
UINT integer;
|
||||
ID2D1EffectContext *effect_context;
|
||||
ID2D1TransformGraph *transform_graph;
|
||||
ID2D1DrawInfo *draw_info;
|
||||
};
|
||||
|
||||
static void queue_d3d1x_test(void (*test)(BOOL d3d11), BOOL d3d11)
|
||||
|
@ -10822,7 +10804,7 @@ static void test_mt_factory(BOOL d3d11)
|
|||
ID2D1Multithread_Enter(multithread);
|
||||
thread = CreateThread(NULL, 0, mt_factory_test_thread_draw_func, ctx.rt, 0, NULL);
|
||||
ok(!!thread, "Failed to create a thread.\n");
|
||||
ret = WaitForSingleObject(thread, 1000);
|
||||
ret = WaitForSingleObject(thread, 5000);
|
||||
ok(ret == WAIT_OBJECT_0, "Didn't expect timeout.\n");
|
||||
ID2D1Multithread_Leave(multithread);
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
|
@ -11114,8 +11096,15 @@ static inline struct effect_impl *impl_from_ID2D1EffectImpl(ID2D1EffectImpl *ifa
|
|||
return CONTAINING_RECORD(iface, struct effect_impl, ID2D1EffectImpl_iface);
|
||||
}
|
||||
|
||||
static inline struct effect_impl *impl_from_ID2D1DrawTransform(ID2D1DrawTransform *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct effect_impl, ID2D1DrawTransform_iface);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_QueryInterface(ID2D1EffectImpl *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_ID2D1EffectImpl)
|
||||
|| IsEqualGUID(iid, &IID_IUnknown))
|
||||
{
|
||||
|
@ -11123,6 +11112,14 @@ static HRESULT STDMETHODCALLTYPE effect_impl_QueryInterface(ID2D1EffectImpl *ifa
|
|||
*out = iface;
|
||||
return S_OK;
|
||||
}
|
||||
else if (IsEqualGUID(iid, &IID_ID2D1DrawTransform)
|
||||
|| IsEqualGUID(iid, &IID_ID2D1Transform)
|
||||
|| IsEqualGUID(iid, &IID_ID2D1TransformNode))
|
||||
{
|
||||
ID2D1EffectImpl_AddRef(iface);
|
||||
*out = &effect_impl->ID2D1DrawTransform_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*out = NULL;
|
||||
return E_NOINTERFACE;
|
||||
|
@ -11144,6 +11141,8 @@ static ULONG STDMETHODCALLTYPE effect_impl_Release(ID2D1EffectImpl *iface)
|
|||
{
|
||||
if (effect_impl->effect_context)
|
||||
ID2D1EffectContext_Release(effect_impl->effect_context);
|
||||
if (effect_impl->draw_info)
|
||||
ID2D1DrawInfo_Release(effect_impl->draw_info);
|
||||
free(effect_impl);
|
||||
}
|
||||
|
||||
|
@ -11525,6 +11524,7 @@ static void test_effect_context(BOOL d3d11)
|
|||
struct d2d1_test_context ctx;
|
||||
ID2D1Factory1 *factory;
|
||||
ID2D1Device *device;
|
||||
ID3D10Blob *vs, *ps;
|
||||
ULONG refcount;
|
||||
BOOL loaded;
|
||||
HRESULT hr;
|
||||
|
@ -11540,6 +11540,14 @@ static void test_effect_context(BOOL d3d11)
|
|||
return;
|
||||
}
|
||||
|
||||
hr = D3DCompile(test_vs_code, sizeof(test_vs_code) - 1, "test_vs", NULL, NULL,
|
||||
"main", "vs_4_0", 0, 0, &vs, NULL);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = D3DCompile(test_ps_code, sizeof(test_ps_code) - 1, "test_ps", NULL, NULL,
|
||||
"main", "ps_4_0", 0, 0, &ps, NULL);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
binding.propertyName = L"Context";
|
||||
binding.setFunction = NULL;
|
||||
binding.getFunction = effect_impl_get_context;
|
||||
|
@ -11562,26 +11570,26 @@ static void test_effect_context(BOOL d3d11)
|
|||
ok(!loaded, "Unexpected shader loaded state.\n");
|
||||
|
||||
hr = ID2D1EffectContext_LoadVertexShader(effect_context,
|
||||
&GUID_TestVertexShader, (const BYTE *)test_ps, sizeof(test_ps));
|
||||
&GUID_TestVertexShader, ID3D10Blob_GetBufferPointer(ps), ID3D10Blob_GetBufferSize(ps));
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = ID2D1EffectContext_LoadVertexShader(effect_context,
|
||||
&GUID_TestVertexShader, (const BYTE *)test_vs, sizeof(test_vs));
|
||||
&GUID_TestVertexShader, ID3D10Blob_GetBufferPointer(vs), ID3D10Blob_GetBufferSize(vs));
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
loaded = ID2D1EffectContext_IsShaderLoaded(effect_context, &GUID_TestVertexShader);
|
||||
ok(loaded, "Unexpected shader loaded state.\n");
|
||||
|
||||
hr = ID2D1EffectContext_LoadVertexShader(effect_context,
|
||||
&GUID_TestVertexShader, (const BYTE *)test_ps, sizeof(test_ps));
|
||||
&GUID_TestVertexShader, ID3D10Blob_GetBufferPointer(ps), ID3D10Blob_GetBufferSize(ps));
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = ID2D1EffectContext_LoadVertexShader(effect_context,
|
||||
&GUID_TestVertexShader, (const BYTE *)test_vs, sizeof(test_vs));
|
||||
&GUID_TestVertexShader, ID3D10Blob_GetBufferPointer(vs), ID3D10Blob_GetBufferSize(vs));
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = ID2D1EffectContext_LoadPixelShader(effect_context,
|
||||
&GUID_TestPixelShader, (const BYTE *)test_vs, sizeof(test_vs));
|
||||
&GUID_TestPixelShader, ID3D10Blob_GetBufferPointer(vs), ID3D10Blob_GetBufferSize(vs));
|
||||
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = ID2D1EffectContext_LoadPixelShader(effect_context,
|
||||
&GUID_TestPixelShader, (const BYTE *)test_ps, sizeof(test_ps));
|
||||
&GUID_TestPixelShader, ID3D10Blob_GetBufferPointer(ps), ID3D10Blob_GetBufferSize(ps));
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
loaded = ID2D1EffectContext_IsShaderLoaded(effect_context, &GUID_TestPixelShader);
|
||||
ok(loaded, "Unexpected shader loaded state.\n");
|
||||
|
@ -11642,6 +11650,10 @@ static void test_effect_context(BOOL d3d11)
|
|||
|
||||
hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
ID3D10Blob_Release(vs);
|
||||
ID3D10Blob_Release(ps);
|
||||
|
||||
release_test_context(&ctx);
|
||||
}
|
||||
|
||||
|
@ -14254,6 +14266,224 @@ static void test_dc_target_is_supported(BOOL d3d11)
|
|||
release_test_context(&ctx);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE ps_effect_impl_Initialize(ID2D1EffectImpl *iface,
|
||||
ID2D1EffectContext *context, ID2D1TransformGraph *graph)
|
||||
{
|
||||
static const char ps_code[] =
|
||||
"float4 main() : sv_target\n"
|
||||
"{\n"
|
||||
" return float4(0.1, 0.2, 0.3, 0.4);\n"
|
||||
"}";
|
||||
|
||||
struct effect_impl *effect_impl = impl_from_ID2D1EffectImpl(iface);
|
||||
ID3D10Blob *blob;
|
||||
HRESULT hr;
|
||||
|
||||
effect_impl->effect_context = context;
|
||||
ID2D1EffectContext_AddRef(effect_impl->effect_context);
|
||||
|
||||
hr = D3DCompile(ps_code, strlen(ps_code), "test_ps", NULL, NULL, "main",
|
||||
"ps_4_0", 0, 0, &blob, NULL);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr = ID2D1EffectContext_LoadPixelShader(context, &GUID_TestPixelShader,
|
||||
ID3D10Blob_GetBufferPointer(blob), ID3D10Blob_GetBufferSize(blob))))
|
||||
{
|
||||
hr = ID2D1TransformGraph_SetSingleTransformNode(graph,
|
||||
(ID2D1TransformNode *)&effect_impl->ID2D1DrawTransform_iface);
|
||||
}
|
||||
|
||||
ID3D10Blob_Release(blob);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const ID2D1EffectImplVtbl ps_effect_impl_vtbl =
|
||||
{
|
||||
effect_impl_QueryInterface,
|
||||
effect_impl_AddRef,
|
||||
effect_impl_Release,
|
||||
ps_effect_impl_Initialize,
|
||||
effect_impl_PrepareForRender,
|
||||
effect_impl_SetGraph,
|
||||
};
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_QueryInterface(
|
||||
ID2D1DrawTransform *iface, REFIID iid, void **out)
|
||||
{
|
||||
struct effect_impl *effect_impl = impl_from_ID2D1DrawTransform(iface);
|
||||
return ID2D1EffectImpl_QueryInterface(&effect_impl->ID2D1EffectImpl_iface, iid, out);
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE effect_impl_draw_transform_AddRef(ID2D1DrawTransform *iface)
|
||||
{
|
||||
struct effect_impl *effect_impl = impl_from_ID2D1DrawTransform(iface);
|
||||
return ID2D1EffectImpl_AddRef(&effect_impl->ID2D1EffectImpl_iface);
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE effect_impl_draw_transform_Release(ID2D1DrawTransform *iface)
|
||||
{
|
||||
struct effect_impl *effect_impl = impl_from_ID2D1DrawTransform(iface);
|
||||
return ID2D1EffectImpl_Release(&effect_impl->ID2D1EffectImpl_iface);
|
||||
}
|
||||
|
||||
static UINT32 STDMETHODCALLTYPE effect_impl_draw_transform_GetInputCount(ID2D1DrawTransform *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_MapOutputRectToInputRects(
|
||||
ID2D1DrawTransform *iface, const D2D1_RECT_L *output_rect, D2D1_RECT_L *input_rects,
|
||||
UINT32 input_rect_count)
|
||||
{
|
||||
if (input_rect_count != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
input_rects[0] = *output_rect;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_MapInputRectsToOutputRect(
|
||||
ID2D1DrawTransform *iface, const D2D1_RECT_L *input_rects, const D2D1_RECT_L *input_opaque_rects,
|
||||
UINT32 input_rect_count, D2D1_RECT_L *output_rect, D2D1_RECT_L *output_opaque_rect)
|
||||
{
|
||||
if (input_rect_count != 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*output_rect = input_rects[0];
|
||||
memset(output_opaque_rect, 0, sizeof(*output_opaque_rect));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_MapInvalidRect(
|
||||
ID2D1DrawTransform *iface, UINT32 index, D2D1_RECT_L input_rect, D2D1_RECT_L *output_rect)
|
||||
{
|
||||
ok(0, "Unexpected call.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE effect_impl_draw_transform_SetDrawInfo(ID2D1DrawTransform *iface,
|
||||
ID2D1DrawInfo *info)
|
||||
{
|
||||
return ID2D1DrawInfo_SetPixelShader(info, &GUID_TestPixelShader, 0);
|
||||
}
|
||||
|
||||
static const ID2D1DrawTransformVtbl ps_effect_draw_transform_vtbl =
|
||||
{
|
||||
effect_impl_draw_transform_QueryInterface,
|
||||
effect_impl_draw_transform_AddRef,
|
||||
effect_impl_draw_transform_Release,
|
||||
effect_impl_draw_transform_GetInputCount,
|
||||
effect_impl_draw_transform_MapOutputRectToInputRects,
|
||||
effect_impl_draw_transform_MapInputRectsToOutputRect,
|
||||
effect_impl_draw_transform_MapInvalidRect,
|
||||
effect_impl_draw_transform_SetDrawInfo,
|
||||
};
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE ps_effect_impl_create(IUnknown **effect_impl)
|
||||
{
|
||||
struct effect_impl *object;
|
||||
|
||||
if (!(object = calloc(1, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->ID2D1EffectImpl_iface.lpVtbl = &ps_effect_impl_vtbl;
|
||||
object->ID2D1DrawTransform_iface.lpVtbl = &ps_effect_draw_transform_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
*effect_impl = (IUnknown *)&object->ID2D1EffectImpl_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void test_effect_custom_pixel_shader(BOOL d3d11)
|
||||
{
|
||||
static const WCHAR *description =
|
||||
L"<?xml version='1.0'?> \
|
||||
<Effect> \
|
||||
<Property name='DisplayName' type='string' value='PSEffect'/> \
|
||||
<Property name='Author' type='string' value='The Wine Project'/> \
|
||||
<Property name='Category' type='string' value='Test'/> \
|
||||
<Property name='Description' type='string' value='Test effect.'/> \
|
||||
<Inputs> \
|
||||
<Input name='Source'/> \
|
||||
</Inputs> \
|
||||
</Effect> \
|
||||
";
|
||||
|
||||
D2D1_BITMAP_PROPERTIES1 bitmap_desc;
|
||||
DWORD colour, expected_colour;
|
||||
struct d2d1_test_context ctx;
|
||||
struct resource_readback rb;
|
||||
ID2D1DeviceContext *context;
|
||||
D2D1_SIZE_U input_size;
|
||||
ID2D1Factory1 *factory;
|
||||
ID2D1Bitmap1 *bitmap;
|
||||
ID2D1Effect *effect;
|
||||
ID2D1Image *output;
|
||||
DWORD pixel;
|
||||
HRESULT hr;
|
||||
|
||||
if (!init_test_context(&ctx, d3d11))
|
||||
return;
|
||||
|
||||
context = ctx.context;
|
||||
factory = ctx.factory1;
|
||||
if (!factory)
|
||||
{
|
||||
win_skip("ID2D1Factory1 is not supported.\n");
|
||||
release_test_context(&ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, description, NULL,
|
||||
0, ps_effect_impl_create);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_TestEffect, &effect);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
release_test_context(&ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
set_size_u(&input_size, 1, 1);
|
||||
pixel = 0xabcd00ff;
|
||||
bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
|
||||
bitmap_desc.dpiX = 96.0f;
|
||||
bitmap_desc.dpiY = 96.0f;
|
||||
bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE;
|
||||
bitmap_desc.colorContext = NULL;
|
||||
hr = ID2D1DeviceContext_CreateBitmap(context, input_size, &pixel, sizeof(pixel),
|
||||
&bitmap_desc, &bitmap);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
ID2D1Effect_SetInput(effect, 0, (ID2D1Image *)bitmap, FALSE);
|
||||
ID2D1Effect_GetOutput(effect, &output);
|
||||
|
||||
ID2D1DeviceContext_BeginDraw(context);
|
||||
ID2D1DeviceContext_Clear(context, 0);
|
||||
ID2D1DeviceContext_DrawImage(context, output, NULL, NULL, 0, 0);
|
||||
hr = ID2D1DeviceContext_EndDraw(context, NULL, NULL);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
get_surface_readback(&ctx, &rb);
|
||||
colour = get_readback_colour(&rb, 0, 0);
|
||||
expected_colour = 0x661a334c;
|
||||
todo_wine ok(compare_colour(colour, expected_colour, 1),
|
||||
"Got unexpected colour %#lx, expected %#lx.\n", colour, expected_colour);
|
||||
release_resource_readback(&rb);
|
||||
|
||||
ID2D1Image_Release(output);
|
||||
ID2D1Bitmap1_Release(bitmap);
|
||||
|
||||
ID2D1Effect_Release(effect);
|
||||
|
||||
release_test_context(&ctx);
|
||||
}
|
||||
|
||||
START_TEST(d2d1)
|
||||
{
|
||||
HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll");
|
||||
|
@ -14343,6 +14573,7 @@ START_TEST(d2d1)
|
|||
queue_test(test_image_bounds);
|
||||
queue_test(test_bitmap_map);
|
||||
queue_test(test_bitmap_create);
|
||||
queue_test(test_effect_custom_pixel_shader);
|
||||
|
||||
run_queued_tests();
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
MODULE = d3d10.dll
|
||||
IMPORTLIB = d3d10
|
||||
IMPORTS = uuid d3d10core d3dcompiler dxgi wined3d
|
||||
IMPORTS = uuid d3d10core d3dcompiler_39 dxgi wined3d
|
||||
EXTRADEFS = -DD3D_COMPILER_VERSION=0
|
||||
PARENTSRC = ../d3dcompiler_43
|
||||
EXTRAINCL = $(VKD3D_PE_CFLAGS)
|
||||
|
||||
SOURCES = \
|
||||
blob.c \
|
||||
d3d10_main.c \
|
||||
effect.c \
|
||||
reflection.c \
|
||||
|
|
|
@ -239,7 +239,7 @@ HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const
|
|||
data, data_size, wine_dbgstr_a(filename), defines, include,
|
||||
hlsl_flags, fx_flags, effect, errors);
|
||||
|
||||
return D3DCompile(data, data_size, filename, defines, include,
|
||||
return D3DCompileFromMemory(data, data_size, filename, defines, include,
|
||||
NULL, "fx_4_0", hlsl_flags, fx_flags, effect, errors);
|
||||
}
|
||||
|
||||
|
|
|
@ -315,4 +315,12 @@ HRESULT d3d10_effect_parse(struct d3d10_effect *effect, const void *data, SIZE_T
|
|||
HRESULT WINAPI D3D10CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapter,
|
||||
unsigned int flags, D3D_FEATURE_LEVEL feature_level, ID3D10Device **device);
|
||||
|
||||
/* d3dcompiler_39 function prototypes */
|
||||
HRESULT WINAPI D3DCompileFromMemory(const void *data, SIZE_T data_size, const char *filename,
|
||||
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
|
||||
const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
|
||||
|
||||
HRESULT WINAPI D3DDisassembleCode(const void *data, SIZE_T data_size,
|
||||
UINT flags, const char *comments, ID3DBlob **disassembly);
|
||||
|
||||
#endif /* __WINE_D3D10_PRIVATE_H */
|
||||
|
|
|
@ -26,8 +26,7 @@ HRESULT WINAPI D3D10CompileShader(const char *data, SIZE_T data_size, const char
|
|||
const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entrypoint,
|
||||
const char *profile, UINT flags, ID3D10Blob **shader, ID3D10Blob **error_messages)
|
||||
{
|
||||
/* Forward to d3dcompiler */
|
||||
return D3DCompile(data, data_size, filename, defines, include,
|
||||
return D3DCompileFromMemory(data, data_size, filename, defines, include,
|
||||
entrypoint, profile, flags, 0, shader, error_messages);
|
||||
}
|
||||
|
||||
|
@ -37,5 +36,5 @@ HRESULT WINAPI D3D10DisassembleShader(const void *data, SIZE_T data_size,
|
|||
TRACE("data %p, data_size %#Ix, color_code %#x, comments %p, disassembly %p.\n",
|
||||
data, data_size, color_code, comments, disassembly);
|
||||
|
||||
return D3DDisassemble(data, data_size, color_code ? D3D_DISASM_ENABLE_COLOR_CODE : 0, comments, disassembly);
|
||||
return D3DDisassembleCode(data, data_size, color_code ? D3D_DISASM_ENABLE_COLOR_CODE : 0, comments, disassembly);
|
||||
}
|
||||
|
|
|
@ -9875,6 +9875,90 @@ static void test_effect_fx_4_1_blend_state(void)
|
|||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
}
|
||||
|
||||
static void test_effect_compiler(void)
|
||||
{
|
||||
static char empty_effect[] =
|
||||
"technique10 {};";
|
||||
static char empty_buffer[] =
|
||||
"cbuffer cb1 { float4 m1; }\n"
|
||||
"cbuffer cb2 { }\n"
|
||||
"technique10 {};";
|
||||
|
||||
D3D10_EFFECT_VARIABLE_DESC var_desc;
|
||||
ID3D10EffectConstantBuffer *cb;
|
||||
D3D10_EFFECT_DESC desc;
|
||||
ID3D10Device *device;
|
||||
ID3D10Effect *effect;
|
||||
ID3D10Blob *blob;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(device = create_device()))
|
||||
{
|
||||
skip("Failed to create device, skipping tests.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = D3D10CompileEffectFromMemory(empty_effect, sizeof(empty_effect), NULL, NULL, NULL, 0, 0,
|
||||
&blob, NULL);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = create_effect(ID3D10Blob_GetBufferPointer(blob), 0, device, NULL, &effect);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
hr = ID3D10Effect_GetDesc(effect, &desc);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(desc.Techniques == 1, "Unexpected technique count %u.\n", desc.Techniques);
|
||||
todo_wine
|
||||
ok(desc.ConstantBuffers == 1, "Unexpected buffer count %u.\n", desc.ConstantBuffers);
|
||||
|
||||
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 0);
|
||||
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
if (hr == S_OK)
|
||||
ok(!strcmp(var_desc.Name, "$Globals"), "Unexpected variable name %s.\n", var_desc.Name);
|
||||
|
||||
ID3D10Effect_Release(effect);
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
/* Empty user buffers. */
|
||||
hr = D3D10CompileEffectFromMemory(empty_buffer, sizeof(empty_buffer), NULL, NULL, NULL, 0, 0,
|
||||
&blob, NULL);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = create_effect(ID3D10Blob_GetBufferPointer(blob), 0, device, NULL, &effect);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
hr = ID3D10Effect_GetDesc(effect, &desc);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(desc.Techniques == 1, "Unexpected technique count %u.\n", desc.Techniques);
|
||||
todo_wine
|
||||
ok(desc.ConstantBuffers == 3, "Unexpected buffer count %u.\n", desc.ConstantBuffers);
|
||||
|
||||
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 0);
|
||||
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
todo_wine
|
||||
ok(!strcmp(var_desc.Name, "$Globals"), "Unexpected variable name %s.\n", var_desc.Name);
|
||||
|
||||
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 1);
|
||||
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
if (hr == S_OK)
|
||||
ok(!strcmp(var_desc.Name, "cb1"), "Unexpected variable name %s.\n", var_desc.Name);
|
||||
|
||||
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 2);
|
||||
hr = cb->lpVtbl->GetDesc(cb, &var_desc);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
if (hr == S_OK)
|
||||
ok(!strcmp(var_desc.Name, "cb2"), "Unexpected variable name %s.\n", var_desc.Name);
|
||||
|
||||
ID3D10Effect_Release(effect);
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
ID3D10Device_Release(device);
|
||||
}
|
||||
|
||||
START_TEST(effect)
|
||||
{
|
||||
test_effect_constant_buffer_type();
|
||||
|
@ -9903,4 +9987,5 @@ START_TEST(effect)
|
|||
test_effect_value_expression();
|
||||
test_effect_fx_4_1();
|
||||
test_effect_fx_4_1_blend_state();
|
||||
test_effect_compiler();
|
||||
}
|
||||
|
|
|
@ -1039,6 +1039,44 @@ static void test_fx_4_1_blend_state(void)
|
|||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
}
|
||||
|
||||
static void test_shader_profiles(void)
|
||||
{
|
||||
const char *profile;
|
||||
|
||||
profile = D3D10GetVertexShaderProfile(NULL);
|
||||
ok(!strcmp(profile, "vs_4_0"), "Unexpected profile %s.\n", profile);
|
||||
|
||||
profile = D3D10GetGeometryShaderProfile(NULL);
|
||||
ok(!strcmp(profile, "gs_4_0"), "Unexpected profile %s.\n", profile);
|
||||
|
||||
profile = D3D10GetPixelShaderProfile(NULL);
|
||||
ok(!strcmp(profile, "ps_4_0"), "Unexpected profile %s.\n", profile);
|
||||
}
|
||||
|
||||
static void test_compile_effect(void)
|
||||
{
|
||||
char default_bs_source[] = "BlendState default_blend_state {};";
|
||||
char bs_source2[] =
|
||||
"BlendState blend_state\n"
|
||||
"{\n"
|
||||
" srcblend[0] = zero;\n"
|
||||
"};";
|
||||
ID3D10Blob *blob;
|
||||
HRESULT hr;
|
||||
|
||||
hr = D3D10CompileEffectFromMemory(default_bs_source, strlen(default_bs_source),
|
||||
NULL, NULL, NULL, 0, 0, &blob, NULL);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
ID3D10Blob_Release(blob);
|
||||
|
||||
/* Compilation fails due to 10.1 feature incompatibility with fx_4_0 profile. */
|
||||
hr = D3D10CompileEffectFromMemory(bs_source2, strlen(bs_source2), NULL, NULL, NULL,
|
||||
0, 0, &blob, NULL);
|
||||
ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
START_TEST(d3d10_1)
|
||||
{
|
||||
test_create_device();
|
||||
|
@ -1047,4 +1085,6 @@ START_TEST(d3d10_1)
|
|||
test_create_blend_state();
|
||||
test_getdc();
|
||||
test_fx_4_1_blend_state();
|
||||
test_shader_profiles();
|
||||
test_compile_effect();
|
||||
}
|
||||
|
|
|
@ -35611,6 +35611,559 @@ static void test_stencil_export(void)
|
|||
release_test_context(&test_context);
|
||||
}
|
||||
|
||||
static void test_high_resource_count(void)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC texture_desc = {0};
|
||||
struct d3d11_test_context test_context;
|
||||
D3D11_SAMPLER_DESC sampler_desc = {0};
|
||||
D3D11_BUFFER_DESC buffer_desc = {0};
|
||||
ID3D11ShaderResourceView *srvs[100];
|
||||
ID3D11Texture2D *textures[50], *rt;
|
||||
D3D11_MAPPED_SUBRESOURCE map_desc;
|
||||
ID3D11SamplerState *samplers[2];
|
||||
ID3D11DeviceContext *context;
|
||||
ID3D11RenderTargetView *rtv;
|
||||
ID3D11Buffer *buffers[50];
|
||||
ID3D11PixelShader *ps;
|
||||
ID3D11Device *device;
|
||||
float *data_ptr;
|
||||
HRESULT hr;
|
||||
|
||||
static const struct vec4 expect = {1274.0f, 637.0f, 1225.0f, 0.0f};
|
||||
static const struct vec4 expect2 = {1274.0f, 637.0f, 1325.0f, 0.0f};
|
||||
|
||||
static const DWORD ps_code[] =
|
||||
{
|
||||
#if 0
|
||||
Texture2D<float> tex[50];
|
||||
Buffer<float> buf[50];
|
||||
|
||||
SamplerState point_sampler, linear_sampler;
|
||||
|
||||
float4 main() : SV_Target
|
||||
{
|
||||
float4 ret = 0;
|
||||
|
||||
for (uint i = 0; i < 50; ++i)
|
||||
{
|
||||
ret.x += tex[i].Sample(point_sampler, 0.5);
|
||||
ret.y += tex[i].Sample(linear_sampler, 0.5);
|
||||
ret.z += buf[i].Load(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0xa909dad8, 0x13f3f278, 0x34767ac9, 0x7c08344c, 0x00000001, 0x000031a8, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
|
||||
0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00003130, 0x00000040, 0x00000c4c,
|
||||
0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000,
|
||||
0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000002, 0x00005555, 0x04001858, 0x00107000, 0x00000003, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000004, 0x00005555, 0x04001858, 0x00107000, 0x00000005, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000006, 0x00005555, 0x04001858, 0x00107000, 0x00000007, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000008, 0x00005555, 0x04001858, 0x00107000, 0x00000009, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000000a, 0x00005555, 0x04001858, 0x00107000, 0x0000000b, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000000c, 0x00005555, 0x04001858, 0x00107000, 0x0000000d, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000000e, 0x00005555, 0x04001858, 0x00107000, 0x0000000f, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000010, 0x00005555, 0x04001858, 0x00107000, 0x00000011, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000012, 0x00005555, 0x04001858, 0x00107000, 0x00000013, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000014, 0x00005555, 0x04001858, 0x00107000, 0x00000015, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000016, 0x00005555, 0x04001858, 0x00107000, 0x00000017, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000018, 0x00005555, 0x04001858, 0x00107000, 0x00000019, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000001a, 0x00005555, 0x04001858, 0x00107000, 0x0000001b, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000001c, 0x00005555, 0x04001858, 0x00107000, 0x0000001d, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000001e, 0x00005555, 0x04001858, 0x00107000, 0x0000001f, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000020, 0x00005555, 0x04001858, 0x00107000, 0x00000021, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000022, 0x00005555, 0x04001858, 0x00107000, 0x00000023, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000024, 0x00005555, 0x04001858, 0x00107000, 0x00000025, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000026, 0x00005555, 0x04001858, 0x00107000, 0x00000027, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000028, 0x00005555, 0x04001858, 0x00107000, 0x00000029, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000002a, 0x00005555, 0x04001858, 0x00107000, 0x0000002b, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000002c, 0x00005555, 0x04001858, 0x00107000, 0x0000002d, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x0000002e, 0x00005555, 0x04001858, 0x00107000, 0x0000002f, 0x00005555, 0x04001858, 0x00107000,
|
||||
0x00000030, 0x00005555, 0x04001858, 0x00107000, 0x00000031, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000032, 0x00005555, 0x04000858, 0x00107000, 0x00000033, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000034, 0x00005555, 0x04000858, 0x00107000, 0x00000035, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000036, 0x00005555, 0x04000858, 0x00107000, 0x00000037, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000038, 0x00005555, 0x04000858, 0x00107000, 0x00000039, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000003a, 0x00005555, 0x04000858, 0x00107000, 0x0000003b, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000003c, 0x00005555, 0x04000858, 0x00107000, 0x0000003d, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000003e, 0x00005555, 0x04000858, 0x00107000, 0x0000003f, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000040, 0x00005555, 0x04000858, 0x00107000, 0x00000041, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000042, 0x00005555, 0x04000858, 0x00107000, 0x00000043, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000044, 0x00005555, 0x04000858, 0x00107000, 0x00000045, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000046, 0x00005555, 0x04000858, 0x00107000, 0x00000047, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000048, 0x00005555, 0x04000858, 0x00107000, 0x00000049, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000004a, 0x00005555, 0x04000858, 0x00107000, 0x0000004b, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000004c, 0x00005555, 0x04000858, 0x00107000, 0x0000004d, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000004e, 0x00005555, 0x04000858, 0x00107000, 0x0000004f, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000050, 0x00005555, 0x04000858, 0x00107000, 0x00000051, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000052, 0x00005555, 0x04000858, 0x00107000, 0x00000053, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000054, 0x00005555, 0x04000858, 0x00107000, 0x00000055, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000056, 0x00005555, 0x04000858, 0x00107000, 0x00000057, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000058, 0x00005555, 0x04000858, 0x00107000, 0x00000059, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000005a, 0x00005555, 0x04000858, 0x00107000, 0x0000005b, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000005c, 0x00005555, 0x04000858, 0x00107000, 0x0000005d, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x0000005e, 0x00005555, 0x04000858, 0x00107000, 0x0000005f, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000060, 0x00005555, 0x04000858, 0x00107000, 0x00000061, 0x00005555, 0x04000858, 0x00107000,
|
||||
0x00000062, 0x00005555, 0x04000858, 0x00107000, 0x00000063, 0x00005555, 0x03000065, 0x001020f2,
|
||||
0x00000000, 0x02000068, 0x00000002, 0x0c000045, 0x001000f2, 0x00000000, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000001, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000004, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000005, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000006,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000007, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000008, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000009, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000000a, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000000b, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000000c, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000000d, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000000e,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000000f, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000010, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000011, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000012, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000013, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000014, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000015, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000016,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000017, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000018, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000019, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000001a, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000001b, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000001c, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000001d, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000001e,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000001f, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000020, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000021, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000022, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000023, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000024, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000025, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000026,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000027, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000028, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000029, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000002a, 0x00106000, 0x00000000, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000002b, 0x00106000,
|
||||
0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000002c, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000002d, 0x00106000, 0x00000000, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000002e,
|
||||
0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000002f, 0x00106000, 0x00000000, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000030, 0x00106000, 0x00000000,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000031, 0x00106000, 0x00000000, 0x07000000, 0x00102012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000001,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000002, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000004, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000005, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000006, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000007, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000008, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000009,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000000a, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000000b, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000000c, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000000d, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000000e, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000000f, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000010, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000011,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000012, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000013, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000014, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000015, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000016, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000017, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000018, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000019,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000001a, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000001b, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000001c, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000001d, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000001e, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000001f, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000020, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000021,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000022, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000023, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000024, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000025, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000026, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000027, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000028, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000029,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x0000002a, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000002b, 0x00106000, 0x00000001,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000002c, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000002d, 0x00106000, 0x00000001, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000002e, 0x00106000,
|
||||
0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x0000002f, 0x00106000, 0x00000001, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2, 0x00000001, 0x00004002, 0x3f000000,
|
||||
0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000030, 0x00106000, 0x00000001, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0c000045, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000031,
|
||||
0x00106000, 0x00000001, 0x07000000, 0x00102022, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000032, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000033, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000034, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000035, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000036,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000037, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000038, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000039, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000003a, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000003b, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000003c, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000003d, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000003e,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000003f, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000040, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000041, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000042, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000043, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000044, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000045, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000046,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000047, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000048, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000049, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000004a, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000004b, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000004c, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000004d, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000004e,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000004f, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000050, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000051, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000052, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000053, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000054, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000055, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000056,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x00000057, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000058, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000059, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x0000005a, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000005b, 0x07000000, 0x00100012, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000005c, 0x07000000, 0x00100012,
|
||||
0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001,
|
||||
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000005d, 0x07000000,
|
||||
0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2,
|
||||
0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x0000005e,
|
||||
0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x0a00002d,
|
||||
0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46,
|
||||
0x0000005f, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a, 0x00000001,
|
||||
0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00107e46, 0x00000060, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010000a,
|
||||
0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00107e46, 0x00000061, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000,
|
||||
0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00107e46, 0x00000062, 0x07000000, 0x00100012, 0x00000000, 0x0010000a,
|
||||
0x00000000, 0x0010000a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000001, 0x00004002, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000063, 0x07000000, 0x00102042, 0x00000000,
|
||||
0x0010000a, 0x00000000, 0x0010000a, 0x00000001, 0x05000036, 0x00102082, 0x00000000, 0x00004001,
|
||||
0x00000000, 0x0100003e,
|
||||
};
|
||||
|
||||
if (!init_test_context(&test_context, NULL))
|
||||
return;
|
||||
device = test_context.device;
|
||||
context = test_context.immediate_context;
|
||||
|
||||
hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps);
|
||||
ok(hr == S_OK, "Failed to create pixel shader, hr %#lx.\n", hr);
|
||||
|
||||
texture_desc.Width = 16;
|
||||
texture_desc.Height = 16;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
texture_desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &rt);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)rt, NULL, &rtv);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(textures); ++i)
|
||||
{
|
||||
float data[2] = {0.0f, i + 1};
|
||||
D3D11_SUBRESOURCE_DATA data_desc = {data, sizeof(data), sizeof(data)};
|
||||
|
||||
texture_desc.Width = 2;
|
||||
texture_desc.Height = 1;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
hr = ID3D11Device_CreateTexture2D(device, &texture_desc, &data_desc, &textures[i]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)textures[i], NULL, &srvs[i]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(buffers); ++i)
|
||||
{
|
||||
float data[2] = {i + 1, 0.0f};
|
||||
D3D11_SUBRESOURCE_DATA data_desc = {data, sizeof(data), sizeof(data)};
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
|
||||
buffer_desc.ByteWidth = sizeof(data);
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
hr = ID3D11Device_CreateBuffer(device, &buffer_desc, &data_desc, &buffers[i]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srv_desc.Buffer.FirstElement = 0;
|
||||
srv_desc.Buffer.NumElements = 2;
|
||||
hr = ID3D11Device_CreateShaderResourceView(device,
|
||||
(ID3D11Resource *)buffers[i], &srv_desc, &srvs[ARRAY_SIZE(textures) + i]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
sampler_desc.MaxLOD = FLT_MAX;
|
||||
hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &samplers[0]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &samplers[1]);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rtv, NULL);
|
||||
ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
|
||||
/* Deliberately make the bindings mismatch, to test that we handle NULL
|
||||
* and unrelated bindings correctly. */
|
||||
ID3D11DeviceContext_PSSetShaderResources(context, 1, ARRAY_SIZE(srvs) - 2, &srvs[1]);
|
||||
ID3D11DeviceContext_PSSetShaderResources(context, ARRAY_SIZE(srvs) + 1, 1, &srvs[0]);
|
||||
ID3D11DeviceContext_PSSetShaderResources(context, ARRAY_SIZE(srvs) + 2, 1, &srvs[ARRAY_SIZE(srvs) - 1]);
|
||||
ID3D11DeviceContext_PSSetSamplers(context, 0, 2, samplers);
|
||||
draw_quad(&test_context);
|
||||
|
||||
check_texture_vec4(rt, &expect, 0);
|
||||
|
||||
/* Discard the data in one of the buffers and draw again. */
|
||||
|
||||
hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)buffers[1], 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc);
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
data_ptr = map_desc.pData;
|
||||
data_ptr[0] = 102.0f;
|
||||
data_ptr[1] = 0.0f;
|
||||
ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)buffers[1], 0);
|
||||
draw_quad(&test_context);
|
||||
|
||||
check_texture_vec4(rt, &expect2, 0);
|
||||
|
||||
ID3D11Texture2D_Release(rt);
|
||||
ID3D11RenderTargetView_Release(rtv);
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(srvs); ++i)
|
||||
ID3D11ShaderResourceView_Release(srvs[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(buffers); ++i)
|
||||
ID3D11Buffer_Release(buffers[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(textures); ++i)
|
||||
ID3D11Texture2D_Release(textures[i]);
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(samplers); ++i)
|
||||
ID3D11SamplerState_Release(samplers[i]);
|
||||
ID3D11PixelShader_Release(ps);
|
||||
release_test_context(&test_context);
|
||||
}
|
||||
|
||||
START_TEST(d3d11)
|
||||
{
|
||||
unsigned int argc, i;
|
||||
|
@ -35809,6 +36362,7 @@ START_TEST(d3d11)
|
|||
queue_test(test_keyed_mutex);
|
||||
queue_test(test_clear_during_render);
|
||||
queue_test(test_stencil_export);
|
||||
queue_test(test_high_resource_count);
|
||||
|
||||
run_queued_tests();
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
@ -107,6 +108,18 @@ static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, floa
|
|||
&& compare_float(vec->w, w, ulps);
|
||||
}
|
||||
|
||||
static uint32_t float_to_int(float f)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t u;
|
||||
float f;
|
||||
} u;
|
||||
|
||||
u.f = f;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
|
||||
{
|
||||
return !strcmp(identifier->Driver, "d3d10warp.dll");
|
||||
|
@ -1667,16 +1680,17 @@ static void color_fill_test(void)
|
|||
{D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
|
||||
{D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
|
||||
};
|
||||
enum format_flags
|
||||
{
|
||||
CHECK_FILL_VALUE = 0x1,
|
||||
BLOCKS = 0x2,
|
||||
FLOAT_VALUES = 0x4,
|
||||
};
|
||||
static const struct
|
||||
{
|
||||
D3DFORMAT format;
|
||||
const char *name;
|
||||
enum
|
||||
{
|
||||
CHECK_FILL_VALUE = 0x1,
|
||||
BLOCKS = 0x2,
|
||||
FLOAT_VALUES = 0x4,
|
||||
} flags;
|
||||
enum format_flags flags;
|
||||
unsigned int fill_i[4];
|
||||
float fill_f[4];
|
||||
}
|
||||
|
@ -3366,7 +3380,7 @@ static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
|
|||
for (y = 0; y < 128; ++y)
|
||||
{
|
||||
if(i)
|
||||
{ /* Set up black texture with 2x2 texel white spot in the middle */
|
||||
{
|
||||
DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
|
||||
for (x = 0; x < 128; ++x)
|
||||
{
|
||||
|
@ -3510,10 +3524,10 @@ static void texbem_test(void)
|
|||
|
||||
generate_bumpmap_textures(device);
|
||||
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
|
||||
IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetVertexShader(device, NULL);
|
||||
|
@ -3664,24 +3678,24 @@ static void texbem_test(void)
|
|||
|
||||
bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
|
||||
bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
|
||||
bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
|
@ -11027,13 +11041,13 @@ static void fixed_function_bumpmap_test(void)
|
|||
/* Generate the textures */
|
||||
generate_bumpmap_textures(device);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
|
||||
|
@ -23249,16 +23263,17 @@ static void test_texture_blending(void)
|
|||
DWORD value;
|
||||
};
|
||||
|
||||
enum texture_stage_texture
|
||||
{
|
||||
TEXTURE_INVALID,
|
||||
TEXTURE_NONE,
|
||||
TEXTURE_BUMPMAP,
|
||||
TEXTURE_RED,
|
||||
};
|
||||
|
||||
struct texture_stage
|
||||
{
|
||||
enum
|
||||
{
|
||||
TEXTURE_INVALID,
|
||||
TEXTURE_NONE,
|
||||
TEXTURE_BUMPMAP,
|
||||
TEXTURE_RED,
|
||||
}
|
||||
texture;
|
||||
enum texture_stage_texture texture;
|
||||
struct texture_stage_state state[20];
|
||||
};
|
||||
|
||||
|
@ -26438,16 +26453,23 @@ static void test_desktop_window(void)
|
|||
device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
|
||||
ok(!!device, "Failed to create a D3D device.\n");
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
|
||||
color = getPixelColor(device, 1, 1);
|
||||
ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
|
||||
if (device)
|
||||
{
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
|
||||
color = getPixelColor(device, 1, 1);
|
||||
ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
|
||||
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
|
||||
|
||||
refcount = IDirect3DDevice9_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice9_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Failed to create a D3D device for the desktop window, skipping tests.\n");
|
||||
}
|
||||
|
||||
/* test device with NULL HWND */
|
||||
device = create_device(d3d, NULL, NULL, TRUE);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
MODULE = d3dcompiler_39.dll
|
||||
IMPORTLIB = d3dcompiler_39
|
||||
IMPORTS = wined3d
|
||||
EXTRADEFS = -DD3D_COMPILER_VERSION=39
|
||||
PARENTSRC = ../d3dcompiler_43
|
||||
|
|
|
@ -397,29 +397,12 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
|
||||
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point,
|
||||
const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags,
|
||||
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob,
|
||||
ID3DBlob **messages_blob)
|
||||
static enum vkd3d_shader_target_type get_target_for_profile(const char *profile)
|
||||
{
|
||||
struct d3dcompiler_include_from_file include_from_file;
|
||||
struct vkd3d_shader_preprocess_info preprocess_info;
|
||||
struct vkd3d_shader_hlsl_source_info hlsl_info;
|
||||
struct vkd3d_shader_compile_option options[3];
|
||||
struct vkd3d_shader_compile_info compile_info;
|
||||
struct vkd3d_shader_compile_option *option;
|
||||
struct vkd3d_shader_code byte_code;
|
||||
const D3D_SHADER_MACRO *macro;
|
||||
size_t profile_len, i;
|
||||
char *messages;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
static const char * const d3dbc_profiles[] =
|
||||
{
|
||||
"fx_2_",
|
||||
|
||||
"ps.1.",
|
||||
"ps.2.",
|
||||
"ps.3.",
|
||||
|
@ -439,6 +422,50 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
|||
"tx_1_",
|
||||
};
|
||||
|
||||
static const char * const fx_profiles[] =
|
||||
{
|
||||
"fx_2_0",
|
||||
"fx_4_0",
|
||||
"fx_4_1",
|
||||
"fx_5_0",
|
||||
};
|
||||
|
||||
profile_len = strlen(profile);
|
||||
for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i)
|
||||
{
|
||||
size_t len = strlen(d3dbc_profiles[i]);
|
||||
|
||||
if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len))
|
||||
return VKD3D_SHADER_TARGET_D3D_BYTECODE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fx_profiles); ++i)
|
||||
{
|
||||
if (!strcmp(profile, fx_profiles[i]))
|
||||
return VKD3D_SHADER_TARGET_FX;
|
||||
}
|
||||
|
||||
return VKD3D_SHADER_TARGET_DXBC_TPF;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename,
|
||||
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point,
|
||||
const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags,
|
||||
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob,
|
||||
ID3DBlob **messages_blob)
|
||||
{
|
||||
struct d3dcompiler_include_from_file include_from_file;
|
||||
struct vkd3d_shader_preprocess_info preprocess_info;
|
||||
struct vkd3d_shader_hlsl_source_info hlsl_info;
|
||||
struct vkd3d_shader_compile_option options[4];
|
||||
struct vkd3d_shader_compile_info compile_info;
|
||||
struct vkd3d_shader_compile_option *option;
|
||||
struct vkd3d_shader_code byte_code;
|
||||
const D3D_SHADER_MACRO *macro;
|
||||
char *messages;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
TRACE("data %p, data_size %Iu, filename %s, macros %p, include %p, entry_point %s, "
|
||||
"profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, "
|
||||
"secondary_data_size %Iu, shader_blob %p, messages_blob %p.\n",
|
||||
|
@ -453,8 +480,11 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
|||
include = &include_from_file.ID3DInclude_iface;
|
||||
}
|
||||
|
||||
if (flags & ~(D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR))
|
||||
if (flags & ~(D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR
|
||||
| D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY))
|
||||
{
|
||||
FIXME("Ignoring flags %#x.\n", flags);
|
||||
}
|
||||
if (effect_flags)
|
||||
FIXME("Ignoring effect flags %#x.\n", effect_flags);
|
||||
if (secondary_flags)
|
||||
|
@ -474,24 +504,12 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
|||
compile_info.source.code = data;
|
||||
compile_info.source.size = data_size;
|
||||
compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL;
|
||||
compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
|
||||
compile_info.target_type = get_target_for_profile(profile);
|
||||
compile_info.options = options;
|
||||
compile_info.option_count = 1;
|
||||
compile_info.log_level = VKD3D_SHADER_LOG_INFO;
|
||||
compile_info.source_name = filename;
|
||||
|
||||
profile_len = strlen(profile);
|
||||
for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i)
|
||||
{
|
||||
size_t len = strlen(d3dbc_profiles[i]);
|
||||
|
||||
if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len))
|
||||
{
|
||||
compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO;
|
||||
preprocess_info.next = &hlsl_info;
|
||||
preprocess_info.macros = (const struct vkd3d_shader_macro *)macros;
|
||||
|
@ -532,6 +550,13 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
|||
option->value = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR;
|
||||
}
|
||||
|
||||
if (flags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY)
|
||||
{
|
||||
option = &options[compile_info.option_count++];
|
||||
option->name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY;
|
||||
option->value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
|
||||
}
|
||||
|
||||
ret = vkd3d_shader_compile(&compile_info, &byte_code, &messages);
|
||||
|
||||
if (ret)
|
||||
|
@ -576,6 +601,20 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* Unlike other effect profiles fx_4_x is using DXBC container. */
|
||||
if (!strcmp(profile, "fx_4_0") || !strcmp(profile, "fx_4_1"))
|
||||
{
|
||||
struct vkd3d_shader_dxbc_section_desc section = { .tag = TAG_FX10, .data = byte_code };
|
||||
struct vkd3d_shader_code dxbc;
|
||||
|
||||
ret = vkd3d_shader_serialize_dxbc(1, §ion, &dxbc, NULL);
|
||||
vkd3d_shader_free_shader_code(&byte_code);
|
||||
if (ret)
|
||||
return hresult_from_vkd3d_result(ret);
|
||||
|
||||
byte_code = dxbc;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr = D3DCreateBlob(byte_code.size, shader_blob)))
|
||||
memcpy(ID3D10Blob_GetBufferPointer(*shader_blob), byte_code.code, byte_code.size);
|
||||
|
||||
|
@ -735,6 +774,12 @@ end:
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DCreateLinker(ID3D11Linker **linker)
|
||||
{
|
||||
FIXME("linker %p stub!\n", linker);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DLoadModule(const void *data, SIZE_T size, ID3D11Module **module)
|
||||
{
|
||||
FIXME("data %p, size %Iu, module %p stub!\n", data, size, module);
|
||||
|
|
|
@ -523,6 +523,7 @@ void SlDeleteShader(struct bwriter_shader *shader);
|
|||
((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
|
||||
#define TAG_Aon9 MAKE_TAG('A', 'o', 'n', '9')
|
||||
#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C')
|
||||
#define TAG_FX10 MAKE_TAG('F', 'X', '1', '0')
|
||||
#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N')
|
||||
#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N')
|
||||
#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5')
|
||||
|
|
|
@ -622,7 +622,7 @@ static void test_sampling(void)
|
|||
draw_quad(&test_context, ps_code);
|
||||
|
||||
v = get_color_vec4(&test_context, 0, 0);
|
||||
todo_wine ok(compare_vec4(&v, 0.25f, 0.0f, 0.25f, 0.0f, 0),
|
||||
ok(compare_vec4(&v, 0.25f, 0.0f, 0.25f, 0.0f, 0),
|
||||
"Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
|
||||
|
||||
ID3D10Blob_Release(ps_code);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@ stub D3DCompressShaders
|
||||
@ stdcall D3DCreateBlob(long ptr)
|
||||
@ stub D3DCreateFunctionLinkingGraph
|
||||
@ stub D3DCreateLinker
|
||||
@ stdcall D3DCreateLinker(ptr)
|
||||
@ stub D3DDecompressShaders
|
||||
@ stdcall D3DDisassemble(ptr long long ptr ptr)
|
||||
@ stub D3DDisassemble10Effect(ptr long ptr)
|
||||
|
|
|
@ -4375,11 +4375,10 @@ static void test_create_effect_from_memory(void)
|
|||
effect = (ID3D10Effect *)0xdeadbeef;
|
||||
hr = D3DX10CreateEffectFromMemory(test_fx_source, strlen(test_fx_source) + 1, NULL, NULL, NULL, "fx_4_0",
|
||||
0x0, 0x0, device, NULL, NULL, &effect, &errors, NULL);
|
||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
todo_wine ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
todo_wine ok(!!effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
if (hr == S_OK)
|
||||
effect->lpVtbl->Release(effect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
ok(!!effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
refcount = ID3D10Device_Release(device);
|
||||
ok(!refcount, "Got unexpected refcount %lu.\n", refcount);
|
||||
|
@ -4465,21 +4464,19 @@ static void test_create_effect_from_file(void)
|
|||
effect = (ID3D10Effect *)0xdeadbeef;
|
||||
hr = D3DX10CreateEffectFromFileW(path, NULL, NULL, "fx_4_0", 0x0, 0x0,
|
||||
device, NULL, NULL, &effect, &errors, NULL);
|
||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
todo_wine ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
todo_wine ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
if (hr == S_OK)
|
||||
effect->lpVtbl->Release(effect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
errors = (ID3D10Blob *)0xdeadbeef;
|
||||
effect = (ID3D10Effect *)0xdeadbeef;
|
||||
hr = D3DX10CreateEffectFromFileA(get_str_a(path), NULL, NULL, "fx_4_0", 0x0, 0x0,
|
||||
device, NULL, NULL, &effect, &errors, NULL);
|
||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
todo_wine ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
todo_wine ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
if (hr == S_OK)
|
||||
effect->lpVtbl->Release(effect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
delete_file(test_file_name);
|
||||
|
||||
|
@ -4584,21 +4581,19 @@ static void test_create_effect_from_resource(void)
|
|||
effect = (ID3D10Effect *)0xdeadbeef;
|
||||
hr = D3DX10CreateEffectFromResourceW(resource_module, test_resource_name, NULL, NULL, NULL, "fx_4_0",
|
||||
0, 0, device, NULL, NULL, &effect, &errors, NULL);
|
||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
todo_wine ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
todo_wine ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
if (hr == S_OK)
|
||||
effect->lpVtbl->Release(effect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
errors = (ID3D10Blob *)0xdeadbeef;
|
||||
effect = (ID3D10Effect *)0xdeadbeef;
|
||||
hr = D3DX10CreateEffectFromResourceA(resource_module, get_str_a(test_resource_name), NULL, NULL, NULL, "fx_4_0",
|
||||
0, 0, device, NULL, NULL, &effect, &errors, NULL);
|
||||
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
todo_wine ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
todo_wine ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
if (hr == S_OK)
|
||||
effect->lpVtbl->Release(effect);
|
||||
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!errors, "Got unexpected errors %p.\n", errors);
|
||||
ok(effect && effect != (ID3D10Effect *)0xdeadbeef, "Got unexpected effect %p.\n", effect);
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
delete_resource_module(test_resource_name, resource_module);
|
||||
|
||||
|
|
|
@ -1875,6 +1875,210 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT d3dx_image_decompress(const void *memory, uint32_t row_pitch, const RECT *rect,
|
||||
const RECT *unaligned_rect, const struct volume *size, const struct pixel_format_desc *desc,
|
||||
void **out_memory, uint32_t *out_row_pitch, RECT *out_rect, const struct pixel_format_desc **out_desc)
|
||||
{
|
||||
void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);
|
||||
const struct pixel_format_desc *uncompressed_desc = NULL;
|
||||
uint32_t x, y, tmp_pitch;
|
||||
BYTE *uncompressed_mem;
|
||||
|
||||
switch (desc->format)
|
||||
{
|
||||
case D3DFMT_DXT1:
|
||||
uncompressed_desc = get_format_info(D3DFMT_A8B8G8R8);
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt1;
|
||||
break;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
uncompressed_desc = get_format_info(D3DFMT_A8B8G8R8);
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt3;
|
||||
break;
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
uncompressed_desc = get_format_info(D3DFMT_A8B8G8R8);
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt5;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected compressed texture format %u.\n", desc->format);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (!(uncompressed_mem = malloc(size->width * size->height * size->depth * uncompressed_desc->bytes_per_pixel)))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (unaligned_rect && EqualRect(rect, unaligned_rect))
|
||||
goto exit;
|
||||
|
||||
TRACE("Decompressing image.\n");
|
||||
tmp_pitch = row_pitch * desc->block_width / desc->block_byte_count;
|
||||
for (y = 0; y < size->height; ++y)
|
||||
{
|
||||
BYTE *ptr = &uncompressed_mem[y * size->width * uncompressed_desc->bytes_per_pixel];
|
||||
for (x = 0; x < size->width; ++x)
|
||||
{
|
||||
const POINT pt = { x, y };
|
||||
|
||||
if (!PtInRect(unaligned_rect, pt))
|
||||
fetch_dxt_texel(tmp_pitch, (BYTE *)memory, x + rect->left, y + rect->top, ptr);
|
||||
ptr += uncompressed_desc->bytes_per_pixel;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
*out_memory = uncompressed_mem;
|
||||
*out_row_pitch = size->width * uncompressed_desc->bytes_per_pixel;
|
||||
if (unaligned_rect)
|
||||
*out_rect = *unaligned_rect;
|
||||
else
|
||||
SetRect(out_rect, 0, 0, size->width, size->height);
|
||||
*out_desc = uncompressed_desc;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void set_volume_struct(struct volume *volume, uint32_t width, uint32_t height, uint32_t depth)
|
||||
{
|
||||
volume->width = width;
|
||||
volume->height = height;
|
||||
volume->depth = depth;
|
||||
}
|
||||
|
||||
static HRESULT d3dx_load_image_from_memory(void *dst_memory, uint32_t dst_row_pitch, const struct pixel_format_desc *dst_desc,
|
||||
const PALETTEENTRY *dst_palette, const RECT *dst_rect, const RECT *dst_rect_aligned, const void *src_memory,
|
||||
uint32_t src_row_pitch, const struct pixel_format_desc *src_desc, const PALETTEENTRY *src_palette, const RECT *src_rect,
|
||||
uint32_t filter_flags, uint32_t color_key)
|
||||
{
|
||||
struct volume src_size, dst_size, dst_size_aligned;
|
||||
const BYTE *src_memory_offset = src_memory;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("dst_memory %p, dst_row_pitch %d, dst_desc %p, dst_palette %p, dst_rect %s, dst_rect_aligned %s, src_memory %p, "
|
||||
"src_row_pitch %d, src_desc %p, src_palette %p, src_rect %s, filter %#x, color_key 0x%08x.\n",
|
||||
dst_memory, dst_row_pitch, dst_desc, dst_palette, wine_dbgstr_rect(dst_rect), wine_dbgstr_rect(dst_rect_aligned),
|
||||
src_memory, src_row_pitch, src_desc, src_palette, wine_dbgstr_rect(src_rect), filter_flags, color_key);
|
||||
|
||||
set_volume_struct(&src_size, (src_rect->right - src_rect->left), (src_rect->bottom - src_rect->top), 1);
|
||||
set_volume_struct(&dst_size, (dst_rect->right - dst_rect->left), (dst_rect->bottom - dst_rect->top), 1);
|
||||
set_volume_struct(&dst_size_aligned, (dst_rect_aligned->right - dst_rect_aligned->left),
|
||||
(dst_rect_aligned->bottom - dst_rect_aligned->top), 1);
|
||||
|
||||
src_memory_offset += (src_rect->top / src_desc->block_height) * src_row_pitch;
|
||||
src_memory_offset += (src_rect->left / src_desc->block_width) * src_desc->block_byte_count;
|
||||
|
||||
/* Everything matches, simply copy the pixels. */
|
||||
if (src_desc->format == dst_desc->format
|
||||
&& dst_size.width == src_size.width
|
||||
&& dst_size.height == src_size.height
|
||||
&& color_key == 0
|
||||
&& !(src_rect->left & (src_desc->block_width - 1))
|
||||
&& !(src_rect->top & (src_desc->block_height - 1))
|
||||
&& !(dst_rect->left & (dst_desc->block_width - 1))
|
||||
&& !(dst_rect->top & (dst_desc->block_height - 1)))
|
||||
{
|
||||
TRACE("Simple copy.\n");
|
||||
copy_pixels(src_memory_offset, src_row_pitch, 0, dst_memory, dst_row_pitch, 0, &src_size, src_desc);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Stretching or format conversion. */
|
||||
if (!is_conversion_from_supported(src_desc)
|
||||
|| !is_conversion_to_supported(dst_desc))
|
||||
{
|
||||
FIXME("Unsupported format conversion %#x -> %#x.\n", src_desc->format, dst_desc->format);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the source is a compressed image, we need to decompress it first
|
||||
* before doing any modifications.
|
||||
*/
|
||||
if (src_desc->type == FORMAT_DXT)
|
||||
{
|
||||
const struct pixel_format_desc *uncompressed_desc;
|
||||
uint32_t uncompressed_row_pitch;
|
||||
void *uncompressed_mem = NULL;
|
||||
RECT uncompressed_rect;
|
||||
|
||||
hr = d3dx_image_decompress(src_memory, src_row_pitch, src_rect, NULL, &src_size, src_desc,
|
||||
&uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d3dx_load_image_from_memory(dst_memory, dst_row_pitch, dst_desc, dst_palette, dst_rect, dst_rect_aligned,
|
||||
uncompressed_mem, uncompressed_row_pitch, uncompressed_desc, src_palette, &uncompressed_rect,
|
||||
filter_flags, color_key);
|
||||
}
|
||||
free(uncompressed_mem);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Same as the above, need to decompress the destination prior to modifying. */
|
||||
if (dst_desc->type == FORMAT_DXT)
|
||||
{
|
||||
const struct pixel_format_desc *uncompressed_desc;
|
||||
uint32_t uncompressed_row_pitch;
|
||||
void *uncompressed_mem = NULL;
|
||||
BYTE *uncompressed_mem_offset;
|
||||
RECT uncompressed_rect;
|
||||
|
||||
hr = d3dx_image_decompress(dst_memory, dst_row_pitch, dst_rect_aligned, dst_rect, &dst_size_aligned, dst_desc,
|
||||
&uncompressed_mem, &uncompressed_row_pitch, &uncompressed_rect, &uncompressed_desc);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
uncompressed_mem_offset = (BYTE *)uncompressed_mem + (dst_rect->top - dst_rect_aligned->top) * uncompressed_row_pitch
|
||||
+ (dst_rect->left - dst_rect_aligned->left) * uncompressed_desc->bytes_per_pixel;
|
||||
hr = d3dx_load_image_from_memory(uncompressed_mem_offset, uncompressed_row_pitch, uncompressed_desc, dst_palette,
|
||||
&uncompressed_rect, &uncompressed_rect, src_memory, src_row_pitch, src_desc, src_palette,
|
||||
src_rect, filter_flags, color_key);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
GLenum gl_format = 0;
|
||||
|
||||
TRACE("Compressing DXTn surface.\n");
|
||||
switch (dst_desc->format)
|
||||
{
|
||||
case D3DFMT_DXT1:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
default:
|
||||
ERR("Unexpected destination compressed format %u.\n", dst_desc->format);
|
||||
}
|
||||
tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height, uncompressed_mem, gl_format,
|
||||
dst_memory, dst_row_pitch);
|
||||
}
|
||||
free(uncompressed_mem);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if ((filter_flags & 0xf) == D3DX_FILTER_NONE)
|
||||
{
|
||||
convert_argb_pixels(src_memory_offset, src_row_pitch, 0, &src_size, src_desc,
|
||||
dst_memory, dst_row_pitch, 0, &dst_size, dst_desc, color_key, src_palette);
|
||||
}
|
||||
else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */
|
||||
{
|
||||
if ((filter_flags & 0xf) != D3DX_FILTER_POINT)
|
||||
FIXME("Unhandled filter %#x.\n", filter_flags);
|
||||
|
||||
/* Always apply a point filter until D3DX_FILTER_LINEAR,
|
||||
* D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */
|
||||
point_filter_argb_pixels(src_memory_offset, src_row_pitch, 0, &src_size, src_desc, dst_memory, dst_row_pitch, 0,
|
||||
&dst_size, dst_desc, color_key, src_palette);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* D3DXLoadSurfaceFromMemory
|
||||
*
|
||||
|
@ -1913,7 +2117,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
|||
DWORD filter, D3DCOLOR color_key)
|
||||
{
|
||||
const struct pixel_format_desc *srcformatdesc, *destformatdesc;
|
||||
struct volume src_size, dst_size, dst_size_aligned;
|
||||
RECT dst_rect_temp, dst_rect_aligned;
|
||||
IDirect3DSurface9 *surface;
|
||||
D3DSURFACE_DESC surfdesc;
|
||||
|
@ -1945,10 +2148,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
src_size.width = src_rect->right - src_rect->left;
|
||||
src_size.height = src_rect->bottom - src_rect->top;
|
||||
src_size.depth = 1;
|
||||
|
||||
IDirect3DSurface9_GetDesc(dst_surface, &surfdesc);
|
||||
destformatdesc = get_format_info(surfdesc.Format);
|
||||
if (!dst_rect)
|
||||
|
@ -1987,172 +2186,16 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
|
|||
dst_rect_aligned.bottom = min((dst_rect_aligned.bottom + destformatdesc->block_height - 1)
|
||||
& ~(destformatdesc->block_height - 1), surfdesc.Height);
|
||||
|
||||
dst_size.width = dst_rect->right - dst_rect->left;
|
||||
dst_size.height = dst_rect->bottom - dst_rect->top;
|
||||
dst_size.depth = 1;
|
||||
dst_size_aligned.width = dst_rect_aligned.right - dst_rect_aligned.left;
|
||||
dst_size_aligned.height = dst_rect_aligned.bottom - dst_rect_aligned.top;
|
||||
dst_size_aligned.depth = 1;
|
||||
|
||||
if (filter == D3DX_DEFAULT)
|
||||
filter = D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER;
|
||||
|
||||
if (FAILED(hr = lock_surface(dst_surface, &dst_rect_aligned, &lockrect, &surface, TRUE)))
|
||||
return hr;
|
||||
|
||||
src_memory = (BYTE *)src_memory + src_rect->top / srcformatdesc->block_height * src_pitch
|
||||
+ src_rect->left / srcformatdesc->block_width * srcformatdesc->block_byte_count;
|
||||
|
||||
if (src_format == surfdesc.Format
|
||||
&& dst_size.width == src_size.width
|
||||
&& dst_size.height == src_size.height
|
||||
&& color_key == 0
|
||||
&& !(src_rect->left & (srcformatdesc->block_width - 1))
|
||||
&& !(src_rect->top & (srcformatdesc->block_height - 1))
|
||||
&& !(dst_rect->left & (destformatdesc->block_width - 1))
|
||||
&& !(dst_rect->top & (destformatdesc->block_height - 1)))
|
||||
{
|
||||
TRACE("Simple copy.\n");
|
||||
copy_pixels(src_memory, src_pitch, 0, lockrect.pBits, lockrect.Pitch, 0,
|
||||
&src_size, srcformatdesc);
|
||||
}
|
||||
else /* Stretching or format conversion. */
|
||||
{
|
||||
const struct pixel_format_desc *dst_format;
|
||||
DWORD *src_uncompressed = NULL;
|
||||
BYTE *dst_uncompressed = NULL;
|
||||
unsigned int dst_pitch;
|
||||
BYTE *dst_mem;
|
||||
|
||||
if (!is_conversion_from_supported(srcformatdesc)
|
||||
|| !is_conversion_to_supported(destformatdesc))
|
||||
{
|
||||
FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format);
|
||||
unlock_surface(dst_surface, &dst_rect_aligned, surface, FALSE);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (srcformatdesc->type == FORMAT_DXT)
|
||||
{
|
||||
void (*fetch_dxt_texel)(int srcRowStride, const BYTE *pixdata,
|
||||
int i, int j, void *texel);
|
||||
unsigned int x, y;
|
||||
|
||||
src_pitch = src_pitch * srcformatdesc->block_width / srcformatdesc->block_byte_count;
|
||||
|
||||
src_uncompressed = malloc(src_size.width * src_size.height * sizeof(DWORD));
|
||||
if (!src_uncompressed)
|
||||
{
|
||||
unlock_surface(dst_surface, &dst_rect_aligned, surface, FALSE);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
switch(src_format)
|
||||
{
|
||||
case D3DFMT_DXT1:
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt1;
|
||||
break;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt3;
|
||||
break;
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
fetch_dxt_texel = fetch_2d_texel_rgba_dxt5;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unexpected compressed texture format %u.\n", src_format);
|
||||
fetch_dxt_texel = NULL;
|
||||
}
|
||||
|
||||
TRACE("Uncompressing DXTn surface.\n");
|
||||
for (y = 0; y < src_size.height; ++y)
|
||||
{
|
||||
DWORD *ptr = &src_uncompressed[y * src_size.width];
|
||||
for (x = 0; x < src_size.width; ++x)
|
||||
{
|
||||
fetch_dxt_texel(src_pitch, src_memory, x + src_rect->left, y + src_rect->top, ptr);
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
src_memory = src_uncompressed;
|
||||
src_pitch = src_size.width * sizeof(DWORD);
|
||||
srcformatdesc = get_format_info(D3DFMT_A8B8G8R8);
|
||||
}
|
||||
|
||||
if (destformatdesc->type == FORMAT_DXT)
|
||||
{
|
||||
BOOL dst_misaligned = dst_rect->left != dst_rect_aligned.left
|
||||
|| dst_rect->top != dst_rect_aligned.top
|
||||
|| dst_rect->right != dst_rect_aligned.right
|
||||
|| dst_rect->bottom != dst_rect_aligned.bottom;
|
||||
size_t dst_uncompressed_size = dst_size_aligned.width * dst_size_aligned.height * sizeof(DWORD);
|
||||
|
||||
dst_uncompressed = malloc(dst_uncompressed_size);
|
||||
if (!dst_uncompressed)
|
||||
{
|
||||
free(src_uncompressed);
|
||||
unlock_surface(dst_surface, &dst_rect_aligned, surface, FALSE);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (dst_misaligned) memset(dst_uncompressed, 0, dst_uncompressed_size);
|
||||
dst_pitch = dst_size_aligned.width * sizeof(DWORD);
|
||||
dst_format = get_format_info(D3DFMT_A8B8G8R8);
|
||||
dst_mem = dst_uncompressed + (dst_rect->top - dst_rect_aligned.top) * dst_pitch
|
||||
+ (dst_rect->left - dst_rect_aligned.left) * sizeof(DWORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_mem = lockrect.pBits;
|
||||
dst_pitch = lockrect.Pitch;
|
||||
dst_format = destformatdesc;
|
||||
}
|
||||
|
||||
if ((filter & 0xf) == D3DX_FILTER_NONE)
|
||||
{
|
||||
convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
|
||||
dst_mem, dst_pitch, 0, &dst_size, dst_format, color_key, src_palette);
|
||||
}
|
||||
else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */
|
||||
{
|
||||
if ((filter & 0xf) != D3DX_FILTER_POINT)
|
||||
FIXME("Unhandled filter %#lx.\n", filter);
|
||||
|
||||
/* Always apply a point filter until D3DX_FILTER_LINEAR,
|
||||
* D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */
|
||||
point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc,
|
||||
dst_mem, dst_pitch, 0, &dst_size, dst_format, color_key, src_palette);
|
||||
}
|
||||
|
||||
free(src_uncompressed);
|
||||
|
||||
if (dst_uncompressed)
|
||||
{
|
||||
GLenum gl_format = 0;
|
||||
|
||||
TRACE("Compressing DXTn surface.\n");
|
||||
switch(surfdesc.Format)
|
||||
{
|
||||
case D3DFMT_DXT1:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case D3DFMT_DXT2:
|
||||
case D3DFMT_DXT3:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case D3DFMT_DXT4:
|
||||
case D3DFMT_DXT5:
|
||||
gl_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
default:
|
||||
ERR("Unexpected destination compressed format %u.\n", surfdesc.Format);
|
||||
}
|
||||
tx_compress_dxtn(4, dst_size_aligned.width, dst_size_aligned.height,
|
||||
dst_uncompressed, gl_format, lockrect.pBits,
|
||||
lockrect.Pitch);
|
||||
free(dst_uncompressed);
|
||||
}
|
||||
}
|
||||
hr = d3dx_load_image_from_memory(lockrect.pBits, lockrect.Pitch, destformatdesc, dst_palette, dst_rect,
|
||||
&dst_rect_aligned, src_memory, src_pitch, srcformatdesc, src_palette, src_rect, filter, color_key);
|
||||
if (FAILED(hr))
|
||||
WARN("d3dx_load_image_from_memory failed with hr %#lx\n", hr);
|
||||
|
||||
return unlock_surface(dst_surface, &dst_rect_aligned, surface, TRUE);
|
||||
}
|
||||
|
|
|
@ -257,12 +257,7 @@ static void test_create_effect_and_pool(IDirect3DDevice9 *device)
|
|||
ok(hr == D3D_OK, "Got result %lx, expected 0 (D3D_OK)\n", hr);
|
||||
|
||||
hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, &effect, NULL);
|
||||
todo_wine ok(hr == D3D_OK, "Got result %lx, expected 0 (D3D_OK)\n", hr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
skip("Failed to compile effect, skipping test.\n");
|
||||
return;
|
||||
}
|
||||
ok(hr == D3D_OK, "Got result %lx, expected 0 (D3D_OK)\n", hr);
|
||||
|
||||
hr = effect->lpVtbl->QueryInterface(effect, &IID_ID3DXBaseEffect, (void **)&base);
|
||||
ok(hr == E_NOINTERFACE, "QueryInterface failed, got %lx, expected %lx (E_NOINTERFACE)\n", hr, E_NOINTERFACE);
|
||||
|
@ -8047,8 +8042,6 @@ static void test_create_effect_from_file(void)
|
|||
trace("D3DXCreateEffectFromFileExW messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
|
||||
ID3DXBuffer_Release(messages);
|
||||
}
|
||||
if (effect)
|
||||
effect->lpVtbl->Release(effect);
|
||||
|
||||
delete_file("effect1.fx");
|
||||
delete_file("effect2.fx");
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "wine/test.h"
|
||||
#include "d3dx9tex.h"
|
||||
#include "resources.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define check_release(obj, exp) _check_release(__LINE__, obj, exp)
|
||||
static inline void _check_release(unsigned int line, IUnknown *obj, int exp)
|
||||
|
@ -279,6 +280,87 @@ static const BYTE dds_dxt5_8_8[] =
|
|||
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x05,0x05,0x50,0x50,
|
||||
};
|
||||
|
||||
/*
|
||||
* 8x8 dxt5 image data, four 4x4 blocks:
|
||||
* +-----+-----+
|
||||
* |Blue |Green|
|
||||
* | | |
|
||||
* +-----+-----+
|
||||
* |Red |Black|
|
||||
* | | |
|
||||
* +-----+-----+
|
||||
*/
|
||||
static const BYTE dxt5_8_8[] =
|
||||
{
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x07,0xe0,0x07,0x00,0x00,0x00,0x00,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,0x00,
|
||||
0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
struct surface_readback
|
||||
{
|
||||
IDirect3DSurface9 *surface;
|
||||
D3DLOCKED_RECT locked_rect;
|
||||
};
|
||||
|
||||
static uint32_t get_readback_color(struct surface_readback *rb, uint32_t x, uint32_t y)
|
||||
{
|
||||
return rb->locked_rect.pBits
|
||||
? ((uint32_t *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(uint32_t) + x] : 0xdeadbeef;
|
||||
}
|
||||
|
||||
static void release_surface_readback(struct surface_readback *rb)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!rb->surface)
|
||||
return;
|
||||
if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
|
||||
trace("Can't unlock the offscreen surface, hr %#lx.\n", hr);
|
||||
IDirect3DSurface9_Release(rb->surface);
|
||||
}
|
||||
|
||||
static void get_surface_decompressed_readback(IDirect3DDevice9 *device, IDirect3DSurface9 *compressed_surface,
|
||||
struct surface_readback *rb)
|
||||
{
|
||||
D3DSURFACE_DESC desc;
|
||||
HRESULT hr;
|
||||
|
||||
memset(rb, 0, sizeof(*rb));
|
||||
hr = IDirect3DSurface9_GetDesc(compressed_surface, &desc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
trace("Failed to get compressed surface description, hr %#lx.\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
|
||||
&rb->surface, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
trace("Can't create the decompressed surface, hr %#lx.\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = D3DXLoadSurfaceFromSurface(rb->surface, NULL, NULL, compressed_surface, NULL, NULL, D3DX_FILTER_NONE, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
trace("Can't load the decompressed surface, hr %#lx.\n", hr);
|
||||
IDirect3DSurface9_Release(rb->surface);
|
||||
rb->surface = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
trace("Can't lock the offscreen surface, hr %#lx.\n", hr);
|
||||
IDirect3DSurface9_Release(rb->surface);
|
||||
rb->surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT create_file(const char *filename, const unsigned char *data, const unsigned int size)
|
||||
{
|
||||
DWORD received;
|
||||
|
@ -832,6 +914,14 @@ static inline void _check_pixel_4bpp(unsigned int line, const D3DLOCKED_RECT *lo
|
|||
ok_(__FILE__, line)(color == expected_color, "Got color 0x%08lx, expected 0x%08lx\n", color, expected_color);
|
||||
}
|
||||
|
||||
#define check_readback_pixel_4bpp(rb, x, y, color, todo) _check_readback_pixel_4bpp(__LINE__, rb, x, y, color, todo)
|
||||
static inline void _check_readback_pixel_4bpp(unsigned int line, struct surface_readback *rb, uint32_t x,
|
||||
uint32_t y, uint32_t expected_color, BOOL todo)
|
||||
{
|
||||
uint32_t color = get_readback_color(rb, x, y);
|
||||
todo_wine_if(todo) ok_(__FILE__, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x.\n", color, expected_color);
|
||||
}
|
||||
|
||||
static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -1450,6 +1540,8 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
|
|||
skip("Failed to create DXT5 texture, hr %#lx.\n", hr);
|
||||
else
|
||||
{
|
||||
struct surface_readback surface_rb;
|
||||
|
||||
hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
|
||||
ok(SUCCEEDED(hr), "Failed to get the surface, hr %#lx.\n", hr);
|
||||
hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
|
||||
|
@ -1521,6 +1613,57 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
|
|||
|
||||
check_release((IUnknown *)newsurf, 1);
|
||||
check_release((IUnknown *)tex, 0);
|
||||
|
||||
/* Misalignment tests but check the resulting image. */
|
||||
hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_DXT5, D3DPOOL_SYSTEMMEM, &tex, NULL);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
SetRect(&rect, 0, 0, 8, 8);
|
||||
hr = D3DXLoadSurfaceFromMemory(newsurf, NULL, NULL, dxt5_8_8,
|
||||
D3DFMT_DXT5, 16 * 2, NULL, &rect, D3DX_FILTER_NONE, 0);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
get_surface_decompressed_readback(device, newsurf, &surface_rb);
|
||||
|
||||
check_readback_pixel_4bpp(&surface_rb, 0, 0, 0xff0000ff, FALSE); /* Blue block, top left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 3, 3, 0xff0000ff, FALSE); /* Blue block, bottom right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 7, 0, 0xff00ff00, FALSE); /* Green block, top right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 4, 3, 0xff00ff00, FALSE); /* Green block, bottom left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 3, 4, 0xffff0000, FALSE); /* Red block, top right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 0, 7, 0xffff0000, FALSE); /* Red block, bottom left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 4, 4, 0xff000000, FALSE); /* Black block, top left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 7, 7, 0xff000000, FALSE); /* Black block, bottom right. */
|
||||
|
||||
release_surface_readback(&surface_rb);
|
||||
|
||||
/*
|
||||
* Load our surface into a destination rectangle that overlaps
|
||||
* multiple blocks. Original data in the blocks should be
|
||||
* preserved.
|
||||
*/
|
||||
SetRect(&rect, 4, 4, 8, 8);
|
||||
SetRect(&destrect, 2, 2, 6, 6);
|
||||
hr = D3DXLoadSurfaceFromMemory(newsurf, NULL, &destrect, dxt5_8_8,
|
||||
D3DFMT_DXT5, 16 * 2, NULL, &rect, D3DX_FILTER_NONE, 0);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
get_surface_decompressed_readback(device, newsurf, &surface_rb);
|
||||
|
||||
check_readback_pixel_4bpp(&surface_rb, 0, 0, 0xff0000ff, FALSE); /* Blue block, top left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 3, 3, 0xff000000, FALSE); /* Blue block, bottom right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 7, 0, 0xff00ff00, FALSE); /* Green block, top right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 4, 3, 0xff000000, FALSE); /* Green block, bottom left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 3, 4, 0xff000000, FALSE); /* Red block, top right. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 0, 7, 0xffff0000, FALSE); /* Red block, bottom left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 4, 4, 0xff000000, FALSE); /* Black block, top left. */
|
||||
check_readback_pixel_4bpp(&surface_rb, 7, 7, 0xff000000, FALSE); /* Black block, bottom right. */
|
||||
|
||||
release_surface_readback(&surface_rb);
|
||||
|
||||
check_release((IUnknown *)newsurf, 1);
|
||||
check_release((IUnknown *)tex, 0);
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &tex, NULL);
|
||||
|
|
|
@ -279,6 +279,7 @@ static int get_opcode_size(UNWIND_CODE op)
|
|||
return 2 + (op.OpInfo != 0);
|
||||
case UWOP_SAVE_NONVOL:
|
||||
case UWOP_SAVE_XMM128:
|
||||
case UWOP_EPILOG:
|
||||
return 2;
|
||||
case UWOP_SAVE_NONVOL_FAR:
|
||||
case UWOP_SAVE_XMM128_FAR:
|
||||
|
@ -586,6 +587,9 @@ static BOOL interpret_function_table_entry(struct cpu_stack_walk* csw,
|
|||
if (!sw_read_mem(csw, context->Rsp + 24, &context->Rsp, sizeof(DWORD64))) return FALSE;
|
||||
mach_frame = TRUE;
|
||||
break;
|
||||
case UWOP_EPILOG:
|
||||
if (info->Version == 2)
|
||||
break; /* nothing to do */
|
||||
default:
|
||||
FIXME("unknown code %u\n", info->UnwindCode[i].UnwindOp);
|
||||
break;
|
||||
|
@ -729,31 +733,46 @@ static BOOL x86_64_stack_walk(struct cpu_stack_walk *csw, STACKFRAME64 *frame,
|
|||
static void* x86_64_find_runtime_function(struct module* module, DWORD64 addr)
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
RUNTIME_FUNCTION* rtf;
|
||||
ULONG size;
|
||||
int min, max;
|
||||
RUNTIME_FUNCTION *func = NULL;
|
||||
const RUNTIME_FUNCTION *rtf;
|
||||
ULONG size;
|
||||
|
||||
rtf = (RUNTIME_FUNCTION*)pe_map_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size);
|
||||
if (rtf) for (min = 0, max = size / sizeof(*rtf); min <= max; )
|
||||
rtf = (const RUNTIME_FUNCTION*)pe_map_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size);
|
||||
if (rtf)
|
||||
{
|
||||
int pos = (min + max) / 2;
|
||||
if (addr < module->module.BaseOfImage + rtf[pos].BeginAddress) max = pos - 1;
|
||||
else if (addr >= module->module.BaseOfImage + rtf[pos].EndAddress) min = pos + 1;
|
||||
else
|
||||
int lo, hi;
|
||||
|
||||
for (lo = 0, hi = size / sizeof(*rtf); lo <= hi; )
|
||||
{
|
||||
rtf += pos;
|
||||
while (rtf->UnwindData & 1) /* follow chained entry */
|
||||
int pos = (lo + hi) / 2;
|
||||
if (addr < module->module.BaseOfImage + rtf[pos].BeginAddress) hi = pos - 1;
|
||||
else if (addr >= module->module.BaseOfImage + rtf[pos].EndAddress) lo = pos + 1;
|
||||
else if ((func = fetch_buffer(module->process, sizeof(*func))))
|
||||
{
|
||||
FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
|
||||
return NULL;
|
||||
/* we need to read into the other process */
|
||||
/* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
|
||||
*func = rtf[pos];
|
||||
while (func && (func->UnwindData & 1))
|
||||
{
|
||||
const BYTE *next = pe_lock_region_from_rva(module, func->UnwindData & ~1, sizeof(*func), NULL);
|
||||
if (next)
|
||||
{
|
||||
*func = *(const RUNTIME_FUNCTION *)next;
|
||||
pe_unlock_region(module, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Couldn't find chained RUNTIME_FUNCTION\n");
|
||||
func = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return rtf;
|
||||
}
|
||||
pe_unmap_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, (const char*)rtf);
|
||||
}
|
||||
#endif
|
||||
return func;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned x86_64_map_dwarf_register(unsigned regno, const struct module* module, BOOL eh_frame)
|
||||
|
@ -951,44 +970,7 @@ static BOOL x86_64_fetch_minidump_thread(struct dump_context* dc, unsigned index
|
|||
|
||||
static BOOL x86_64_fetch_minidump_module(struct dump_context* dc, unsigned index, unsigned flags)
|
||||
{
|
||||
/* FIXME: not sure about the flags... */
|
||||
if (1)
|
||||
{
|
||||
/* FIXME: crop values across module boundaries, */
|
||||
#ifdef __x86_64__
|
||||
struct process* pcs;
|
||||
struct module* module;
|
||||
const RUNTIME_FUNCTION* rtf;
|
||||
ULONG size;
|
||||
|
||||
if (!(pcs = process_find_by_handle(dc->process->handle)) ||
|
||||
!(module = module_find_by_addr(pcs, dc->modules[index].base)))
|
||||
return FALSE;
|
||||
rtf = (const RUNTIME_FUNCTION*)pe_map_directory(module, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &size);
|
||||
if (rtf)
|
||||
{
|
||||
const RUNTIME_FUNCTION* end = (const RUNTIME_FUNCTION*)((const char*)rtf + size);
|
||||
UNWIND_INFO ui;
|
||||
|
||||
while (rtf + 1 < end)
|
||||
{
|
||||
while (rtf->UnwindData & 1) /* follow chained entry */
|
||||
{
|
||||
FIXME("RunTime_Function outside IMAGE_DIRECTORY_ENTRY_EXCEPTION unimplemented yet!\n");
|
||||
return FALSE;
|
||||
/* we need to read into the other process */
|
||||
/* rtf = (RUNTIME_FUNCTION*)(module->module.BaseOfImage + (rtf->UnwindData & ~1)); */
|
||||
}
|
||||
if (read_process_memory(dc->process, dc->modules[index].base + rtf->UnwindData, &ui, sizeof(ui)))
|
||||
minidump_add_memory_block(dc, dc->modules[index].base + rtf->UnwindData,
|
||||
FIELD_OFFSET(UNWIND_INFO, UnwindCode) + ui.CountOfCodes * sizeof(UNWIND_CODE), 0);
|
||||
rtf++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct cpu cpu_x86_64 = {
|
||||
|
|
|
@ -438,9 +438,11 @@ struct module
|
|||
struct process* process;
|
||||
IMAGEHLP_MODULEW64 module;
|
||||
WCHAR modulename[64]; /* used for enumeration */
|
||||
WCHAR* alt_modulename; /* used in symbol lookup */
|
||||
struct module* next;
|
||||
enum dhext_module_type type : 16;
|
||||
unsigned short is_virtual : 1,
|
||||
dont_load_symbols : 1,
|
||||
is_wine_builtin : 1,
|
||||
has_file_image : 1;
|
||||
struct cpu* cpu;
|
||||
|
@ -548,17 +550,6 @@ struct module_pair
|
|||
struct module* effective; /* out: module with debug info */
|
||||
};
|
||||
|
||||
enum pdb_kind {PDB_JG, PDB_DS};
|
||||
|
||||
struct pdb_lookup
|
||||
{
|
||||
const char* filename;
|
||||
enum pdb_kind kind;
|
||||
unsigned int age;
|
||||
unsigned int timestamp;
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
struct cpu_stack_walk
|
||||
{
|
||||
HANDLE hProcess;
|
||||
|
@ -627,7 +618,9 @@ struct dump_context
|
|||
struct dump_module* modules;
|
||||
unsigned num_modules;
|
||||
unsigned alloc_modules;
|
||||
/* exception information */
|
||||
/* outter information */
|
||||
MINIDUMP_EXCEPTION_INFORMATION *except_param;
|
||||
MINIDUMP_USER_STREAM_INFORMATION *user_stream;
|
||||
/* output information */
|
||||
MINIDUMP_TYPE type;
|
||||
HANDLE hFile;
|
||||
|
@ -759,7 +752,6 @@ extern BOOL pe_load_debug_directory(const struct process* pcs,
|
|||
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
|
||||
extern DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* dbgdir, DWORD size,
|
||||
SYMSRV_INDEX_INFOW* info);
|
||||
extern BOOL pdb_fetch_file_info(const struct pdb_lookup* pdb_lookup, unsigned* matched);
|
||||
struct pdb_cmd_pair {
|
||||
const char* name;
|
||||
DWORD* pvalue;
|
||||
|
@ -770,9 +762,9 @@ extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW*
|
|||
extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info);
|
||||
|
||||
/* path.c */
|
||||
extern BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
|
||||
extern BOOL path_find_symbol_file(const struct process *pcs, const struct module *module,
|
||||
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
||||
WCHAR *buffer, BOOL* is_unmatched);
|
||||
SYMSRV_INDEX_INFOW *info, BOOL *unmatched);
|
||||
extern WCHAR *get_dos_file_name(const WCHAR *filename) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
||||
extern BOOL search_dll_path(const struct process* process, const WCHAR *name, WORD machine,
|
||||
BOOL (*match)(void*, HANDLE, const WCHAR*), void *param);
|
||||
|
@ -791,7 +783,10 @@ extern struct module*
|
|||
extern BOOL pe_load_debug_info(const struct process* pcs,
|
||||
struct module* module);
|
||||
extern const char* pe_map_directory(struct module* module, int dirno, DWORD* size);
|
||||
extern BOOL pe_unmap_directory(struct module* module, int dirno, const char*);
|
||||
extern DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info);
|
||||
extern const BYTE* pe_lock_region_from_rva(struct module *module, DWORD rva, DWORD size, DWORD *length);
|
||||
extern BOOL pe_unlock_region(struct module *module, const BYTE* region);
|
||||
|
||||
/* source.c */
|
||||
extern unsigned source_new(struct module* module, const char* basedir, const char* source);
|
||||
|
|
|
@ -61,15 +61,19 @@ static BOOL fetch_process_info(struct dump_context* dc)
|
|||
{
|
||||
if (HandleToUlong(spi->UniqueProcessId) == dc->pid)
|
||||
{
|
||||
dc->num_threads = spi->dwThreadCount;
|
||||
dc->num_threads = 0;
|
||||
dc->threads = HeapAlloc(GetProcessHeap(), 0,
|
||||
dc->num_threads * sizeof(dc->threads[0]));
|
||||
if (!dc->threads) goto failed;
|
||||
for (i = 0; i < dc->num_threads; i++)
|
||||
spi->dwThreadCount * sizeof(dc->threads[0]));
|
||||
if (!dc->threads) break;
|
||||
for (i = 0; i < spi->dwThreadCount; i++)
|
||||
{
|
||||
dc->threads[i].tid = HandleToULong(spi->ti[i].ClientId.UniqueThread);
|
||||
dc->threads[i].prio_class = spi->ti[i].dwBasePriority; /* FIXME */
|
||||
dc->threads[i].curr_prio = spi->ti[i].dwCurrentPriority;
|
||||
/* don't include current thread */
|
||||
if (HandleToULong(spi->ti[i].ClientId.UniqueThread) == GetCurrentThreadId())
|
||||
continue;
|
||||
dc->threads[dc->num_threads].tid = HandleToULong(spi->ti[i].ClientId.UniqueThread);
|
||||
dc->threads[dc->num_threads].prio_class = spi->ti[i].dwBasePriority; /* FIXME */
|
||||
dc->threads[dc->num_threads].curr_prio = spi->ti[i].dwCurrentPriority;
|
||||
dc->num_threads++;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pcs_buffer);
|
||||
return TRUE;
|
||||
|
@ -78,7 +82,6 @@ static BOOL fetch_process_info(struct dump_context* dc)
|
|||
spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset);
|
||||
}
|
||||
}
|
||||
failed:
|
||||
HeapFree(GetProcessHeap(), 0, pcs_buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -116,7 +119,6 @@ static void fetch_thread_stack(struct dump_context* dc, const void* teb_addr,
|
|||
* fetches some information about thread of id 'tid'
|
||||
*/
|
||||
static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
|
||||
const MINIDUMP_EXCEPTION_INFORMATION* except,
|
||||
MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
|
||||
{
|
||||
DWORD tid = dc->threads[thd_idx].tid;
|
||||
|
@ -141,44 +143,22 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
|
|||
FIXME("Couldn't open thread %lu (%lu)\n", tid, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (NtQueryInformationThread(hThread, ThreadBasicInformation,
|
||||
&tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
|
||||
{
|
||||
mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
|
||||
if (tbi.ExitStatus == STILL_ACTIVE)
|
||||
{
|
||||
if (tid != GetCurrentThreadId() &&
|
||||
(mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
|
||||
{
|
||||
ctx->ContextFlags = CONTEXT_FULL;
|
||||
if (!GetThreadContext(hThread, ctx))
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
else if (tid == GetCurrentThreadId() && except)
|
||||
{
|
||||
CONTEXT lctx, *pctx;
|
||||
mdThd->SuspendCount = 1;
|
||||
if (except->ClientPointers)
|
||||
{
|
||||
EXCEPTION_POINTERS ep;
|
||||
|
||||
ReadProcessMemory(dc->process->handle, except->ExceptionPointers,
|
||||
&ep, sizeof(ep), NULL);
|
||||
ReadProcessMemory(dc->process->handle, ep.ContextRecord,
|
||||
&lctx, sizeof(lctx), NULL);
|
||||
pctx = &lctx;
|
||||
}
|
||||
else pctx = except->ExceptionPointers->ContextRecord;
|
||||
|
||||
*ctx = *pctx;
|
||||
fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
|
||||
}
|
||||
else mdThd->SuspendCount = 0;
|
||||
mdThd->SuspendCount = SuspendThread(hThread);
|
||||
ctx->ContextFlags = CONTEXT_ALL;
|
||||
if (!GetThreadContext(hThread, ctx))
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
else
|
||||
mdThd->SuspendCount = (DWORD)-1;
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
return TRUE;
|
||||
|
@ -397,22 +377,21 @@ static void append(struct dump_context* dc, const void* data, unsigned size)
|
|||
*
|
||||
* Write in File the exception information from pcs
|
||||
*/
|
||||
static unsigned dump_exception_info(struct dump_context* dc,
|
||||
const MINIDUMP_EXCEPTION_INFORMATION* except)
|
||||
static unsigned dump_exception_info(struct dump_context* dc)
|
||||
{
|
||||
MINIDUMP_EXCEPTION_STREAM mdExcpt;
|
||||
EXCEPTION_RECORD rec, *prec;
|
||||
CONTEXT ctx, *pctx;
|
||||
DWORD i;
|
||||
|
||||
mdExcpt.ThreadId = except->ThreadId;
|
||||
mdExcpt.ThreadId = dc->except_param->ThreadId;
|
||||
mdExcpt.__alignment = 0;
|
||||
if (except->ClientPointers)
|
||||
if (dc->except_param->ClientPointers)
|
||||
{
|
||||
EXCEPTION_POINTERS ep;
|
||||
|
||||
ReadProcessMemory(dc->process->handle,
|
||||
except->ExceptionPointers, &ep, sizeof(ep), NULL);
|
||||
dc->except_param->ExceptionPointers, &ep, sizeof(ep), NULL);
|
||||
ReadProcessMemory(dc->process->handle,
|
||||
ep.ExceptionRecord, &rec, sizeof(rec), NULL);
|
||||
ReadProcessMemory(dc->process->handle,
|
||||
|
@ -422,8 +401,8 @@ static unsigned dump_exception_info(struct dump_context* dc,
|
|||
}
|
||||
else
|
||||
{
|
||||
prec = except->ExceptionPointers->ExceptionRecord;
|
||||
pctx = except->ExceptionPointers->ContextRecord;
|
||||
prec = dc->except_param->ExceptionPointers->ExceptionRecord;
|
||||
pctx = dc->except_param->ExceptionPointers->ContextRecord;
|
||||
}
|
||||
mdExcpt.ExceptionRecord.ExceptionCode = prec->ExceptionCode;
|
||||
mdExcpt.ExceptionRecord.ExceptionFlags = prec->ExceptionFlags;
|
||||
|
@ -715,8 +694,7 @@ static unsigned dump_system_info(struct dump_context* dc)
|
|||
*
|
||||
* Dumps into File the information about running threads
|
||||
*/
|
||||
static unsigned dump_threads(struct dump_context* dc,
|
||||
const MINIDUMP_EXCEPTION_INFORMATION* except)
|
||||
static unsigned dump_threads(struct dump_context* dc)
|
||||
{
|
||||
MINIDUMP_THREAD mdThd;
|
||||
MINIDUMP_THREAD_LIST mdThdList;
|
||||
|
@ -732,7 +710,7 @@ static unsigned dump_threads(struct dump_context* dc,
|
|||
|
||||
for (i = 0; i < dc->num_threads; i++)
|
||||
{
|
||||
fetch_thread_info(dc, i, except, &mdThd, &ctx);
|
||||
fetch_thread_info(dc, i, &mdThd, &ctx);
|
||||
|
||||
flags_out = ThreadWriteThread | ThreadWriteStack | ThreadWriteContext |
|
||||
ThreadWriteInstructionWindow;
|
||||
|
@ -906,6 +884,126 @@ static unsigned dump_misc_info(struct dump_context* dc)
|
|||
return sizeof(mmi);
|
||||
}
|
||||
|
||||
static DWORD CALLBACK write_minidump(void *_args)
|
||||
{
|
||||
struct dump_context *dc = _args;
|
||||
static const MINIDUMP_DIRECTORY emptyDir = {UnusedStream, {0, 0}};
|
||||
MINIDUMP_HEADER mdHead;
|
||||
MINIDUMP_DIRECTORY mdDir;
|
||||
DWORD i, nStreams, idx_stream;
|
||||
|
||||
if (!fetch_process_info(dc)) return FALSE;
|
||||
fetch_modules_info(dc);
|
||||
|
||||
/* 1) init */
|
||||
nStreams = 6 + (dc->except_param ? 1 : 0) +
|
||||
(dc->user_stream ? dc->user_stream->UserStreamCount : 0);
|
||||
|
||||
/* pad the directory size to a multiple of 4 for alignment purposes */
|
||||
nStreams = (nStreams + 3) & ~3;
|
||||
|
||||
/* 2) write header */
|
||||
mdHead.Signature = MINIDUMP_SIGNATURE;
|
||||
mdHead.Version = MINIDUMP_VERSION; /* NOTE: native puts in an 'implementation specific' value in the high order word of this member */
|
||||
mdHead.NumberOfStreams = nStreams;
|
||||
mdHead.CheckSum = 0; /* native sets a 0 checksum in its files */
|
||||
mdHead.StreamDirectoryRva = sizeof(mdHead);
|
||||
mdHead.TimeDateStamp = time(NULL);
|
||||
mdHead.Flags = dc->type;
|
||||
append(dc, &mdHead, sizeof(mdHead));
|
||||
|
||||
/* 3) write stream directories */
|
||||
dc->rva += nStreams * sizeof(mdDir);
|
||||
idx_stream = 0;
|
||||
|
||||
/* 3.1) write data stream directories */
|
||||
|
||||
/* must be first in minidump */
|
||||
mdDir.StreamType = SystemInfoStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_system_info(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = ThreadListStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_threads(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = ModuleListStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_modules(dc, FALSE);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_modules(dc, TRUE);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
|
||||
if (!(dc->type & MiniDumpWithFullMemory))
|
||||
{
|
||||
mdDir.StreamType = MemoryListStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_memory_info(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
mdDir.StreamType = MiscInfoStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_misc_info(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
/* 3.2) write exception information (if any) */
|
||||
if (dc->except_param)
|
||||
{
|
||||
mdDir.StreamType = ExceptionStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_exception_info(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
/* 3.3) write user defined streams (if any) */
|
||||
if (dc->user_stream)
|
||||
{
|
||||
for (i = 0; i < dc->user_stream->UserStreamCount; i++)
|
||||
{
|
||||
mdDir.StreamType = dc->user_stream->UserStreamArray[i].Type;
|
||||
mdDir.Location.DataSize = dc->user_stream->UserStreamArray[i].BufferSize;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
append(dc, dc->user_stream->UserStreamArray[i].Buffer,
|
||||
dc->user_stream->UserStreamArray[i].BufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
/* 3.4) write full memory (if requested) */
|
||||
if (dc->type & MiniDumpWithFullMemory)
|
||||
{
|
||||
fetch_memory64_info(dc);
|
||||
|
||||
mdDir.StreamType = Memory64ListStream;
|
||||
mdDir.Location.Rva = dc->rva;
|
||||
mdDir.Location.DataSize = dump_memory64_info(dc);
|
||||
writeat(dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
/* fill the remaining directory entries with 0's (unused stream types) */
|
||||
/* NOTE: this should always come last in the dump! */
|
||||
for (i = idx_stream; i < nStreams; i++)
|
||||
writeat(dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir, sizeof(emptyDir));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* MiniDumpWriteDump (DEBUGHLP.@)
|
||||
*
|
||||
|
@ -916,12 +1014,9 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
|
|||
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
|
||||
{
|
||||
static const MINIDUMP_DIRECTORY emptyDir = {UnusedStream, {0, 0}};
|
||||
MINIDUMP_HEADER mdHead;
|
||||
MINIDUMP_DIRECTORY mdDir;
|
||||
DWORD i, nStreams, idx_stream;
|
||||
struct dump_context dc;
|
||||
BOOL sym_initialized = FALSE;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!(dc.process = process_find_by_handle(hProcess)))
|
||||
{
|
||||
|
@ -933,6 +1028,15 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
|
|||
dc.process = process_find_by_handle(hProcess);
|
||||
}
|
||||
|
||||
if (DumpType & MiniDumpWithDataSegs)
|
||||
FIXME("NIY MiniDumpWithDataSegs\n");
|
||||
if (DumpType & MiniDumpWithHandleData)
|
||||
FIXME("NIY MiniDumpWithHandleData\n");
|
||||
if (DumpType & MiniDumpFilterMemory)
|
||||
FIXME("NIY MiniDumpFilterMemory\n");
|
||||
if (DumpType & MiniDumpScanMemory)
|
||||
FIXME("NIY MiniDumpScanMemory\n");
|
||||
|
||||
dc.hFile = hFile;
|
||||
dc.pid = pid;
|
||||
dc.modules = NULL;
|
||||
|
@ -949,125 +1053,26 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
|
|||
dc.num_mem64 = 0;
|
||||
dc.alloc_mem64 = 0;
|
||||
dc.rva = 0;
|
||||
dc.except_param = ExceptionParam;
|
||||
dc.user_stream = UserStreamParam;
|
||||
|
||||
if (!fetch_process_info(&dc)) return FALSE;
|
||||
fetch_modules_info(&dc);
|
||||
|
||||
/* 1) init */
|
||||
nStreams = 6 + (ExceptionParam ? 1 : 0) +
|
||||
(UserStreamParam ? UserStreamParam->UserStreamCount : 0);
|
||||
|
||||
/* pad the directory size to a multiple of 4 for alignment purposes */
|
||||
nStreams = (nStreams + 3) & ~3;
|
||||
|
||||
if (DumpType & MiniDumpWithDataSegs)
|
||||
FIXME("NIY MiniDumpWithDataSegs\n");
|
||||
if (DumpType & MiniDumpWithHandleData)
|
||||
FIXME("NIY MiniDumpWithHandleData\n");
|
||||
if (DumpType & MiniDumpFilterMemory)
|
||||
FIXME("NIY MiniDumpFilterMemory\n");
|
||||
if (DumpType & MiniDumpScanMemory)
|
||||
FIXME("NIY MiniDumpScanMemory\n");
|
||||
|
||||
/* 2) write header */
|
||||
mdHead.Signature = MINIDUMP_SIGNATURE;
|
||||
mdHead.Version = MINIDUMP_VERSION; /* NOTE: native puts in an 'implementation specific' value in the high order word of this member */
|
||||
mdHead.NumberOfStreams = nStreams;
|
||||
mdHead.CheckSum = 0; /* native sets a 0 checksum in its files */
|
||||
mdHead.StreamDirectoryRva = sizeof(mdHead);
|
||||
mdHead.TimeDateStamp = time(NULL);
|
||||
mdHead.Flags = DumpType;
|
||||
append(&dc, &mdHead, sizeof(mdHead));
|
||||
|
||||
/* 3) write stream directories */
|
||||
dc.rva += nStreams * sizeof(mdDir);
|
||||
idx_stream = 0;
|
||||
|
||||
/* 3.1) write data stream directories */
|
||||
|
||||
/* must be first in minidump */
|
||||
mdDir.StreamType = SystemInfoStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_system_info(&dc);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = ThreadListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_threads(&dc, ExceptionParam);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = ModuleListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_modules(&dc, FALSE);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
mdDir.StreamType = 0xfff0; /* FIXME: this is part of MS reserved streams */
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_modules(&dc, TRUE);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
|
||||
if (!(DumpType & MiniDumpWithFullMemory))
|
||||
/* have a dedicated thread for fetching info on self */
|
||||
if (dc.pid != GetCurrentProcessId())
|
||||
ret = write_minidump(&dc);
|
||||
else
|
||||
{
|
||||
mdDir.StreamType = MemoryListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_memory_info(&dc);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
mdDir.StreamType = MiscInfoStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_misc_info(&dc);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
|
||||
/* 3.2) write exception information (if any) */
|
||||
if (ExceptionParam)
|
||||
{
|
||||
mdDir.StreamType = ExceptionStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_exception_info(&dc, ExceptionParam);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
/* 3.3) write user defined streams (if any) */
|
||||
if (UserStreamParam)
|
||||
{
|
||||
for (i = 0; i < UserStreamParam->UserStreamCount; i++)
|
||||
DWORD exit_code;
|
||||
HANDLE h = CreateThread(NULL, 0, write_minidump, &dc, 0, NULL);
|
||||
if (h)
|
||||
{
|
||||
mdDir.StreamType = UserStreamParam->UserStreamArray[i].Type;
|
||||
mdDir.Location.DataSize = UserStreamParam->UserStreamArray[i].BufferSize;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
append(&dc, UserStreamParam->UserStreamArray[i].Buffer,
|
||||
UserStreamParam->UserStreamArray[i].BufferSize);
|
||||
if (WaitForSingleObject(h, INFINITE) == WAIT_OBJECT_0 && GetExitCodeThread(h, &exit_code))
|
||||
ret = exit_code;
|
||||
else
|
||||
TerminateThread(h, 0);
|
||||
CloseHandle(h);
|
||||
}
|
||||
}
|
||||
|
||||
/* 3.4) write full memory (if requested) */
|
||||
if (DumpType & MiniDumpWithFullMemory)
|
||||
{
|
||||
fetch_memory64_info(&dc);
|
||||
|
||||
mdDir.StreamType = Memory64ListStream;
|
||||
mdDir.Location.Rva = dc.rva;
|
||||
mdDir.Location.DataSize = dump_memory64_info(&dc);
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + idx_stream++ * sizeof(mdDir),
|
||||
&mdDir, sizeof(mdDir));
|
||||
}
|
||||
|
||||
/* fill the remaining directory entries with 0's (unused stream types) */
|
||||
/* NOTE: this should always come last in the dump! */
|
||||
for (i = idx_stream; i < nStreams; i++)
|
||||
writeat(&dc, mdHead.StreamDirectoryRva + i * sizeof(emptyDir), &emptyDir, sizeof(emptyDir));
|
||||
|
||||
if (sym_initialized)
|
||||
SymCleanup(hProcess);
|
||||
|
||||
|
@ -1076,7 +1081,7 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
|
|||
HeapFree(GetProcessHeap(), 0, dc.modules);
|
||||
HeapFree(GetProcessHeap(), 0, dc.threads);
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -210,6 +210,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
|
|||
module->module.BaseOfImage = mod_addr;
|
||||
module->module.ImageSize = size;
|
||||
module_set_module(module, name);
|
||||
module->alt_modulename = NULL;
|
||||
module->module.ImageName[0] = '\0';
|
||||
lstrcpynW(module->module.LoadedImageName, name, ARRAY_SIZE(module->module.LoadedImageName));
|
||||
module->module.SymType = SymDeferred;
|
||||
|
@ -288,6 +289,7 @@ struct module* module_find_by_nameW(const struct process* pcs, const WCHAR* name
|
|||
for (module = pcs->lmodules; module; module = module->next)
|
||||
{
|
||||
if (!wcsicmp(name, module->modulename)) return module;
|
||||
if (module->alt_modulename && !wcsicmp(name, module->alt_modulename)) return module;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
return NULL;
|
||||
|
@ -374,8 +376,12 @@ BOOL module_load_debug(struct module* module)
|
|||
if (module->module.SymType == SymDeferred)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (module->is_virtual) ret = FALSE;
|
||||
|
||||
if (module->is_virtual)
|
||||
{
|
||||
module->module.SymType = SymVirtual;
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (module->type == DMT_PE)
|
||||
{
|
||||
idslW64.SizeOfStruct = sizeof(idslW64);
|
||||
|
@ -398,8 +404,9 @@ BOOL module_load_debug(struct module* module)
|
|||
if (!ret) module->module.SymType = SymNone;
|
||||
assert(module->module.SymType != SymDeferred);
|
||||
module->module.NumSyms = module->ht_symbols.num_elts;
|
||||
return ret;
|
||||
}
|
||||
return module->module.SymType != SymNone;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -410,7 +417,6 @@ BOOL module_load_debug(struct module* module)
|
|||
* the module itself)
|
||||
* - if the module has no debug info and has an ELF container, then return the ELF
|
||||
* container (and also force the ELF container's debug info loading if deferred)
|
||||
* - otherwise return the module itself if it has some debug info
|
||||
*/
|
||||
BOOL module_get_debug(struct module_pair* pair)
|
||||
{
|
||||
|
@ -940,7 +946,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
|
|||
|
||||
if (!(pcs = process_find_by_handle(hProcess))) return 0;
|
||||
|
||||
if (Flags & ~(SLMFLAG_VIRTUAL))
|
||||
if (Flags & ~(SLMFLAG_VIRTUAL | SLMFLAG_NO_SYMBOLS))
|
||||
FIXME("Unsupported Flags %08lx for %s\n", Flags, debugstr_w(wImageName));
|
||||
|
||||
/* Trying to load a new module at the same address of an existing one,
|
||||
|
@ -956,45 +962,48 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
|
|||
}
|
||||
}
|
||||
|
||||
pcs->loader->synchronize_module_list(pcs);
|
||||
|
||||
/* this is a Wine extension to the API just to redo the synchronisation */
|
||||
if (!wImageName && !hFile) return 0;
|
||||
if (!wImageName && !hFile && !Flags)
|
||||
{
|
||||
pcs->loader->synchronize_module_list(pcs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Flags & SLMFLAG_VIRTUAL)
|
||||
{
|
||||
if (!wImageName) return 0;
|
||||
if (!wImageName) wImageName = L"";
|
||||
module = module_new(pcs, wImageName, DMT_PE, FALSE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
if (!module) return 0;
|
||||
module->module.SymType = SymVirtual;
|
||||
}
|
||||
/* check if it's a builtin PE module with a containing ELF module */
|
||||
else if (wImageName && module_is_container_loaded(pcs, wImageName, BaseOfDll))
|
||||
else
|
||||
{
|
||||
/* force the loading of DLL as builtin */
|
||||
module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
|
||||
}
|
||||
if (!module)
|
||||
{
|
||||
/* otherwise, try a regular PE module */
|
||||
if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) &&
|
||||
wImageName)
|
||||
/* try PE image */
|
||||
module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll);
|
||||
if (!module && wImageName)
|
||||
{
|
||||
/* and finally an ELF or Mach-O module */
|
||||
module = pcs->loader->load_module(pcs, wImageName, BaseOfDll);
|
||||
/* It could be either a dll.so file (for which we need the corresponding
|
||||
* system module) or a system module.
|
||||
* In both cases, ensure system module list is up-to-date.
|
||||
*/
|
||||
pcs->loader->synchronize_module_list(pcs);
|
||||
if (module_is_container_loaded(pcs, wImageName, BaseOfDll))
|
||||
module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
|
||||
/* at last, try ELF or Mach-O module */
|
||||
if (!module)
|
||||
module = pcs->loader->load_module(pcs, wImageName, BaseOfDll);
|
||||
}
|
||||
if (!module)
|
||||
{
|
||||
WARN("Couldn't locate %s\n", debugstr_w(wImageName));
|
||||
SetLastError(ERROR_NO_MORE_FILES);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!module)
|
||||
{
|
||||
WARN("Couldn't locate %s\n", debugstr_w(wImageName));
|
||||
SetLastError(ERROR_NO_MORE_FILES);
|
||||
return 0;
|
||||
}
|
||||
/* by default module_new fills module.ModuleName from a derivation
|
||||
* of LoadedImageName. Overwrite it, if we have better information
|
||||
*/
|
||||
if (Flags & SLMFLAG_NO_SYMBOLS) module->dont_load_symbols = 1;
|
||||
|
||||
/* Store alternate name for module when provided. */
|
||||
if (wModuleName)
|
||||
module_set_module(module, wModuleName);
|
||||
module->alt_modulename = pool_wcsdup(&module->pool, wModuleName);
|
||||
if (wImageName)
|
||||
lstrcpynW(module->module.ImageName, wImageName, ARRAY_SIZE(module->module.ImageName));
|
||||
|
||||
|
@ -1526,6 +1535,11 @@ BOOL WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr,
|
|||
|
||||
if (dbghelp_opt_real_path && module->real_path)
|
||||
lstrcpynW(miw64.LoadedImageName, module->real_path, ARRAY_SIZE(miw64.LoadedImageName));
|
||||
else if (miw64.SymType == SymDeferred)
|
||||
{
|
||||
miw64.LoadedImageName[0] = '\0';
|
||||
miw64.TimeDateStamp = 0;
|
||||
}
|
||||
|
||||
/* update debug information from container if any */
|
||||
if (module->module.SymType == SymNone)
|
||||
|
|
|
@ -49,16 +49,19 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
|
||||
|
||||
static const GUID null_guid;
|
||||
|
||||
struct pdb_stream_name
|
||||
{
|
||||
const char* name;
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
enum pdb_kind {PDB_JG, PDB_DS};
|
||||
|
||||
struct pdb_file_info
|
||||
{
|
||||
enum pdb_kind kind;
|
||||
DWORD age;
|
||||
HANDLE hMap;
|
||||
const char* image;
|
||||
struct pdb_stream_name* stream_dict;
|
||||
|
@ -67,12 +70,10 @@ struct pdb_file_info
|
|||
{
|
||||
struct
|
||||
{
|
||||
DWORD timestamp;
|
||||
struct PDB_JG_TOC* toc;
|
||||
} jg;
|
||||
struct
|
||||
{
|
||||
GUID guid;
|
||||
struct PDB_DS_TOC* toc;
|
||||
} ds;
|
||||
} u;
|
||||
|
@ -3141,21 +3142,22 @@ static void pdb_free_file(struct pdb_file_info* pdb_file)
|
|||
HeapFree(GetProcessHeap(), 0, pdb_file->stream_dict);
|
||||
}
|
||||
|
||||
static BOOL pdb_load_stream_name_table(struct pdb_file_info* pdb_file, const char* str, unsigned cb)
|
||||
static struct pdb_stream_name* pdb_load_stream_name_table(const char* str, unsigned cb)
|
||||
{
|
||||
DWORD* pdw;
|
||||
DWORD* ok_bits;
|
||||
DWORD count, numok;
|
||||
unsigned i, j;
|
||||
char* cpstr;
|
||||
struct pdb_stream_name* stream_dict;
|
||||
DWORD* pdw;
|
||||
DWORD* ok_bits;
|
||||
DWORD count, numok;
|
||||
unsigned i, j;
|
||||
char* cpstr;
|
||||
|
||||
pdw = (DWORD*)(str + cb);
|
||||
numok = *pdw++;
|
||||
count = *pdw++;
|
||||
|
||||
pdb_file->stream_dict = HeapAlloc(GetProcessHeap(), 0, (numok + 1) * sizeof(struct pdb_stream_name) + cb);
|
||||
if (!pdb_file->stream_dict) return FALSE;
|
||||
cpstr = (char*)(pdb_file->stream_dict + numok + 1);
|
||||
stream_dict = HeapAlloc(GetProcessHeap(), 0, (numok + 1) * sizeof(struct pdb_stream_name) + cb);
|
||||
if (!stream_dict) return NULL;
|
||||
cpstr = (char*)(stream_dict + numok + 1);
|
||||
memcpy(cpstr, str, cb);
|
||||
|
||||
/* bitfield: first dword is len (in dword), then data */
|
||||
|
@ -3168,15 +3170,14 @@ static BOOL pdb_load_stream_name_table(struct pdb_file_info* pdb_file, const cha
|
|||
if (ok_bits[i / 32] & (1 << (i % 32)))
|
||||
{
|
||||
if (j >= numok) break;
|
||||
pdb_file->stream_dict[j].name = &cpstr[*pdw++];
|
||||
pdb_file->stream_dict[j].index = *pdw++;
|
||||
stream_dict[j].name = &cpstr[*pdw++];
|
||||
stream_dict[j].index = *pdw++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/* add sentinel */
|
||||
pdb_file->stream_dict[numok].name = NULL;
|
||||
pdb_file->fpoext_stream = -1;
|
||||
return TRUE;
|
||||
stream_dict[numok].name = NULL;
|
||||
return stream_dict;
|
||||
}
|
||||
|
||||
static unsigned pdb_get_stream_by_name(const struct pdb_file_info* pdb_file, const char* name)
|
||||
|
@ -3304,39 +3305,6 @@ static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
|
|||
}
|
||||
}
|
||||
|
||||
static HANDLE map_pdb_file(const struct process* pcs,
|
||||
const struct pdb_lookup* lookup,
|
||||
struct module* module)
|
||||
{
|
||||
HANDLE hFile, hMap = NULL;
|
||||
WCHAR dbg_file_path[MAX_PATH];
|
||||
BOOL ret = FALSE;
|
||||
|
||||
switch (lookup->kind)
|
||||
{
|
||||
case PDB_JG:
|
||||
ret = path_find_symbol_file(pcs, module, lookup->filename, TRUE, NULL, lookup->timestamp,
|
||||
lookup->age, dbg_file_path, &module->module.PdbUnmatched);
|
||||
break;
|
||||
case PDB_DS:
|
||||
ret = path_find_symbol_file(pcs, module, lookup->filename, TRUE, &lookup->guid, 0,
|
||||
lookup->age, dbg_file_path, &module->module.PdbUnmatched);
|
||||
break;
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
WARN("\tCouldn't find %s\n", lookup->filename);
|
||||
return NULL;
|
||||
}
|
||||
if ((hFile = CreateFileW(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
return hMap;
|
||||
}
|
||||
|
||||
static void pdb_dispose_type_parse(struct codeview_type_parse* ctp)
|
||||
{
|
||||
pdb_free(ctp->hash_stream);
|
||||
|
@ -3385,12 +3353,14 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg,
|
|||
ERR("-Unsupported hash of size %u\n", ctp->header.hash_value_size);
|
||||
return FALSE;
|
||||
}
|
||||
ctp->hash_stream = pdb_read_stream(pdb_file, ctp->header.hash_stream);
|
||||
/* FIXME always present? if not reconstruct ?*/
|
||||
if (!ctp->hash_stream)
|
||||
if (!(ctp->hash_stream = pdb_read_stream(pdb_file, ctp->header.hash_stream)))
|
||||
{
|
||||
ERR("-Missing hash table in PDB file\n");
|
||||
return FALSE;
|
||||
if (ctp->header.last_index > ctp->header.first_index)
|
||||
{
|
||||
/* may be reconstruct hash table ? */
|
||||
FIXME("-No hash table, while types exist\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ctp->module = msc_dbg->module;
|
||||
|
@ -3422,7 +3392,7 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg,
|
|||
/* parse the remap table
|
||||
* => move listed type_id at first position of their hash buckets so that we force remap to them
|
||||
*/
|
||||
if (ctp->header.type_remap_size)
|
||||
if (ctp->hash_stream && ctp->header.type_remap_size)
|
||||
{
|
||||
const unsigned* remap = (const unsigned*)((const BYTE*)ctp->hash_stream + ctp->header.type_remap_offset);
|
||||
unsigned i, capa, count_present;
|
||||
|
@ -3486,30 +3456,29 @@ static const char PDB_DS_IDENT[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0";
|
|||
* pdb_init
|
||||
*
|
||||
* Tries to load a pdb file
|
||||
* 'matched' is filled with the number of correct matches for this file:
|
||||
* - age counts for one
|
||||
* - timestamp or guid depending on kind counts for one
|
||||
* a wrong kind of file returns FALSE (FIXME ?)
|
||||
*/
|
||||
static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info* pdb_file,
|
||||
const char* image, unsigned* matched)
|
||||
static BOOL pdb_init(struct pdb_file_info* pdb_file, const char* image)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
/* check the file header, and if ok, load the TOC */
|
||||
TRACE("PDB(%s): %.40s\n", pdb_lookup->filename, debugstr_an(image, 40));
|
||||
TRACE("PDB: %.40s\n", debugstr_an(image, 40));
|
||||
|
||||
*matched = 0;
|
||||
if (!memcmp(image, PDB_JG_IDENT, sizeof(PDB_JG_IDENT)))
|
||||
{
|
||||
const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
|
||||
struct PDB_JG_ROOT* root;
|
||||
struct PDB_JG_TOC* jg_toc;
|
||||
|
||||
pdb_file->u.jg.toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
||||
root = pdb_read_jg_stream(pdb, pdb_file->u.jg.toc, 1);
|
||||
jg_toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
||||
if (!jg_toc)
|
||||
{
|
||||
ERR("-Unable to get TOC from .PDB\n");
|
||||
return FALSE;
|
||||
}
|
||||
root = pdb_read_jg_stream(pdb, jg_toc, 1);
|
||||
if (!root)
|
||||
{
|
||||
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
||||
ERR("-Unable to get root from .PDB\n");
|
||||
pdb_free(jg_toc);
|
||||
return FALSE;
|
||||
}
|
||||
switch (root->Version)
|
||||
|
@ -3522,38 +3491,32 @@ static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info*
|
|||
default:
|
||||
ERR("-Unknown root block version %d\n", root->Version);
|
||||
}
|
||||
if (pdb_lookup->kind != PDB_JG)
|
||||
{
|
||||
WARN("Found %s, but wrong PDB kind\n", pdb_lookup->filename);
|
||||
pdb_free(root);
|
||||
return FALSE;
|
||||
}
|
||||
pdb_file->kind = PDB_JG;
|
||||
pdb_file->u.jg.timestamp = root->TimeDateStamp;
|
||||
pdb_file->age = root->Age;
|
||||
if (root->TimeDateStamp == pdb_lookup->timestamp) (*matched)++;
|
||||
else WARN("Found %s, but wrong signature: %08x %08x\n",
|
||||
pdb_lookup->filename, root->TimeDateStamp, pdb_lookup->timestamp);
|
||||
if (root->Age == pdb_lookup->age) (*matched)++;
|
||||
else WARN("Found %s, but wrong age: %08x %08x\n",
|
||||
pdb_lookup->filename, root->Age, pdb_lookup->age);
|
||||
TRACE("found JG for %s: age=%x timestamp=%x\n",
|
||||
pdb_lookup->filename, root->Age, root->TimeDateStamp);
|
||||
ret = pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
|
||||
pdb_file->u.jg.toc = jg_toc;
|
||||
TRACE("found JG: age=%x timestamp=%x\n", root->Age, root->TimeDateStamp);
|
||||
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
||||
pdb_file->fpoext_stream = -1;
|
||||
|
||||
pdb_free(root);
|
||||
}
|
||||
else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
|
||||
{
|
||||
const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
|
||||
struct PDB_DS_ROOT* root;
|
||||
struct PDB_DS_TOC* ds_toc;
|
||||
|
||||
pdb_file->u.ds.toc =
|
||||
pdb_ds_read(pdb, (const UINT*)((const char*)pdb + pdb->toc_block * pdb->block_size),
|
||||
pdb->toc_size);
|
||||
root = pdb_read_ds_stream(pdb, pdb_file->u.ds.toc, 1);
|
||||
ds_toc = pdb_ds_read(pdb, (const UINT*)((const char*)pdb + pdb->toc_block * pdb->block_size),
|
||||
pdb->toc_size);
|
||||
if (!ds_toc)
|
||||
{
|
||||
ERR("-Unable to get TOC from .PDB\n");
|
||||
return FALSE;
|
||||
}
|
||||
root = pdb_read_ds_stream(pdb, ds_toc, 1);
|
||||
if (!root)
|
||||
{
|
||||
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
||||
ERR("-Unable to get root from .PDB\n");
|
||||
pdb_free(ds_toc);
|
||||
return FALSE;
|
||||
}
|
||||
switch (root->Version)
|
||||
|
@ -3564,18 +3527,10 @@ static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info*
|
|||
ERR("-Unknown root block version %u\n", root->Version);
|
||||
}
|
||||
pdb_file->kind = PDB_DS;
|
||||
pdb_file->u.ds.guid = root->guid;
|
||||
pdb_file->age = root->Age;
|
||||
if (!memcmp(&root->guid, &pdb_lookup->guid, sizeof(GUID))) (*matched)++;
|
||||
else WARN("Found %s, but wrong GUID: %s %s\n",
|
||||
pdb_lookup->filename, debugstr_guid(&root->guid),
|
||||
debugstr_guid(&pdb_lookup->guid));
|
||||
if (root->Age == pdb_lookup->age) (*matched)++;
|
||||
else WARN("Found %s, but wrong age: %08x %08x\n",
|
||||
pdb_lookup->filename, root->Age, pdb_lookup->age);
|
||||
TRACE("found DS for %s: age=%x guid=%s\n",
|
||||
pdb_lookup->filename, root->Age, debugstr_guid(&root->guid));
|
||||
ret = pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
|
||||
pdb_file->u.ds.toc = ds_toc;
|
||||
TRACE("found DS for: age=%x guid=%s\n", root->Age, debugstr_guid(&root->guid));
|
||||
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
||||
pdb_file->fpoext_stream = -1;
|
||||
|
||||
pdb_free(root);
|
||||
}
|
||||
|
@ -3599,13 +3554,13 @@ static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info*
|
|||
pdb_free(x);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return pdb_file->stream_dict != NULL;
|
||||
}
|
||||
|
||||
static BOOL pdb_process_internal(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg,
|
||||
const struct pdb_lookup* pdb_lookup,
|
||||
struct pdb_module_info* pdb_module_info,
|
||||
static BOOL pdb_process_internal(const struct process *pcs,
|
||||
const struct msc_debug_info *msc_dbg,
|
||||
const WCHAR *filename,
|
||||
struct pdb_module_info *pdb_module_info,
|
||||
unsigned module_index);
|
||||
|
||||
DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||
|
@ -3717,13 +3672,12 @@ DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
|||
return ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
static void pdb_process_symbol_imports(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg,
|
||||
const PDB_SYMBOLS* symbols,
|
||||
const void* symbols_image,
|
||||
const char* image,
|
||||
const struct pdb_lookup* pdb_lookup,
|
||||
struct pdb_module_info* pdb_module_info,
|
||||
static void pdb_process_symbol_imports(const struct process *pcs,
|
||||
const struct msc_debug_info *msc_dbg,
|
||||
const PDB_SYMBOLS *symbols,
|
||||
const void *symbols_image,
|
||||
const char *image,
|
||||
struct pdb_module_info *pdb_module_info,
|
||||
unsigned module_index)
|
||||
{
|
||||
if (module_index == -1 && symbols && symbols->pdbimport_size)
|
||||
|
@ -3733,7 +3687,6 @@ static void pdb_process_symbol_imports(const struct process* pcs,
|
|||
const void* last;
|
||||
const char* ptr;
|
||||
int i = 0;
|
||||
struct pdb_file_info sf0 = pdb_module_info->pdb_files[0];
|
||||
|
||||
imp = (const PDB_SYMBOL_IMPORT*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
|
||||
symbols->module_size + symbols->sectcontrib_size +
|
||||
|
@ -3742,29 +3695,15 @@ static void pdb_process_symbol_imports(const struct process* pcs,
|
|||
last = (const char*)imp + symbols->pdbimport_size;
|
||||
while (imp < (const PDB_SYMBOL_IMPORT*)last)
|
||||
{
|
||||
SYMSRV_INDEX_INFOW info;
|
||||
|
||||
ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename);
|
||||
if (i >= CV_MAX_MODULES) FIXME("Out of bounds!!!\n");
|
||||
if (!stricmp(pdb_lookup->filename, imp->filename))
|
||||
{
|
||||
if (module_index != -1) FIXME("Twice the entry\n");
|
||||
else module_index = i;
|
||||
pdb_module_info->pdb_files[i] = sf0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct pdb_lookup imp_pdb_lookup;
|
||||
|
||||
/* FIXME: this is an import of a JG PDB file
|
||||
* how's a DS PDB handled ?
|
||||
*/
|
||||
imp_pdb_lookup.filename = imp->filename;
|
||||
imp_pdb_lookup.kind = PDB_JG;
|
||||
imp_pdb_lookup.timestamp = imp->TimeDateStamp;
|
||||
imp_pdb_lookup.age = imp->Age;
|
||||
TRACE("got for %s: age=%u ts=%x\n",
|
||||
imp->filename, imp->Age, imp->TimeDateStamp);
|
||||
pdb_process_internal(pcs, msc_dbg, &imp_pdb_lookup, pdb_module_info, i);
|
||||
}
|
||||
TRACE("got for %s: age=%u ts=%x\n",
|
||||
imp->filename, imp->Age, imp->TimeDateStamp);
|
||||
if (path_find_symbol_file(pcs, msc_dbg->module, imp->filename, TRUE, NULL, imp->TimeDateStamp, imp->Age, &info,
|
||||
&msc_dbg->module->module.PdbUnmatched))
|
||||
pdb_process_internal(pcs, msc_dbg, info.pdbfile, pdb_module_info, i);
|
||||
i++;
|
||||
imp = (const PDB_SYMBOL_IMPORT*)((const char*)first + ((ptr - (const char*)first + strlen(ptr) + 1 + 3) & ~3));
|
||||
}
|
||||
|
@ -3780,31 +3719,34 @@ static void pdb_process_symbol_imports(const struct process* pcs,
|
|||
cv_current_module->allowed = TRUE;
|
||||
}
|
||||
|
||||
static BOOL pdb_process_internal(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg,
|
||||
const struct pdb_lookup* pdb_lookup,
|
||||
struct pdb_module_info* pdb_module_info,
|
||||
static BOOL pdb_process_internal(const struct process *pcs,
|
||||
const struct msc_debug_info *msc_dbg,
|
||||
const WCHAR *filename,
|
||||
struct pdb_module_info *pdb_module_info,
|
||||
unsigned module_index)
|
||||
{
|
||||
HANDLE hMap = NULL;
|
||||
HANDLE hFile = NULL, hMap = NULL;
|
||||
char* image = NULL;
|
||||
BYTE* symbols_image = NULL;
|
||||
PDB_STRING_TABLE* files_image = NULL;
|
||||
unsigned matched;
|
||||
struct pdb_file_info* pdb_file;
|
||||
|
||||
TRACE("Processing PDB file %s\n", pdb_lookup->filename);
|
||||
TRACE("Processing PDB file %ls\n", filename);
|
||||
|
||||
pdb_file = &pdb_module_info->pdb_files[module_index == -1 ? 0 : module_index];
|
||||
/* Open and map() .PDB file */
|
||||
if ((hMap = map_pdb_file(pcs, pdb_lookup, msc_dbg->module)) == NULL ||
|
||||
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
||||
if ((hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ||
|
||||
(hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL ||
|
||||
(image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL)
|
||||
{
|
||||
WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
|
||||
WARN("Unable to open .PDB file: %ls\n", filename);
|
||||
CloseHandle(hMap);
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pdb_init(pdb_lookup, pdb_file, image, &matched) || matched != 2)
|
||||
CloseHandle(hFile);
|
||||
if (!pdb_init(pdb_file, image))
|
||||
{
|
||||
CloseHandle(hMap);
|
||||
UnmapViewOfFile(image);
|
||||
|
@ -3823,7 +3765,8 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
struct codeview_type_parse ipi_ctp;
|
||||
BYTE* file;
|
||||
int header_size = 0;
|
||||
PDB_STREAM_INDEXES* psi;
|
||||
unsigned num_sub_streams;
|
||||
const unsigned short* sub_streams;
|
||||
BOOL ipi_ok;
|
||||
|
||||
pdb_convert_symbols_header(&symbols, &header_size, symbols_image);
|
||||
|
@ -3839,29 +3782,18 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
symbols.version, symbols.version);
|
||||
}
|
||||
|
||||
switch (symbols.stream_index_size)
|
||||
{
|
||||
case 0:
|
||||
case sizeof(PDB_STREAM_INDEXES_OLD):
|
||||
/* no fpo ext stream in this case */
|
||||
break;
|
||||
case sizeof(PDB_STREAM_INDEXES):
|
||||
case sizeof(PDB_STREAM_INDEXES) + 2:
|
||||
psi = (PDB_STREAM_INDEXES*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
|
||||
symbols.module_size + symbols.sectcontrib_size +
|
||||
symbols.segmap_size + symbols.srcmodule_size +
|
||||
symbols.pdbimport_size + symbols.unknown2_size);
|
||||
pdb_file->fpoext_stream = psi->FPO_EXT;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown PDB_STREAM_INDEXES size (%u)\n", symbols.stream_index_size);
|
||||
pdb_free(symbols_image);
|
||||
return FALSE;
|
||||
}
|
||||
num_sub_streams = symbols.stream_index_size / sizeof(sub_streams[0]);
|
||||
sub_streams = (const unsigned short*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
|
||||
symbols.module_size + symbols.sectcontrib_size +
|
||||
symbols.segmap_size + symbols.srcmodule_size +
|
||||
symbols.pdbimport_size + symbols.unknown2_size);
|
||||
if (PDB_SIDX_FPOEXT < num_sub_streams)
|
||||
pdb_file->fpoext_stream = sub_streams[PDB_SIDX_FPOEXT];
|
||||
|
||||
files_image = pdb_read_strings(pdb_file);
|
||||
|
||||
pdb_process_symbol_imports(pcs, msc_dbg, &symbols, symbols_image, image,
|
||||
pdb_lookup, pdb_module_info, module_index);
|
||||
pdb_module_info, module_index);
|
||||
pdb_process_types(msc_dbg, pdb_file);
|
||||
|
||||
ipi_image = pdb_read_stream(pdb_file, 4);
|
||||
|
@ -3947,7 +3879,7 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
}
|
||||
else
|
||||
pdb_process_symbol_imports(pcs, msc_dbg, NULL, NULL, image,
|
||||
pdb_lookup, pdb_module_info, module_index);
|
||||
pdb_module_info, module_index);
|
||||
|
||||
pdb_free(symbols_image);
|
||||
pdb_free(files_image);
|
||||
|
@ -3955,83 +3887,63 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL pdb_process_file(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg,
|
||||
struct pdb_lookup* pdb_lookup)
|
||||
static BOOL pdb_process_file(const struct process *pcs,
|
||||
const struct msc_debug_info *msc_dbg,
|
||||
const char *filename, const GUID *guid, DWORD timestamp, DWORD age)
|
||||
{
|
||||
BOOL ret;
|
||||
struct module_format* modfmt;
|
||||
struct pdb_module_info* pdb_module_info;
|
||||
SYMSRV_INDEX_INFOW info;
|
||||
BOOL unmatched;
|
||||
|
||||
modfmt = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(struct module_format) + sizeof(struct pdb_module_info));
|
||||
if (!modfmt) return FALSE;
|
||||
|
||||
pdb_module_info = (void*)(modfmt + 1);
|
||||
msc_dbg->module->format_info[DFI_PDB] = modfmt;
|
||||
modfmt->module = msc_dbg->module;
|
||||
modfmt->remove = pdb_module_remove;
|
||||
modfmt->loc_compute = pdb_location_compute;
|
||||
modfmt->u.pdb_info = pdb_module_info;
|
||||
|
||||
memset(cv_zmodules, 0, sizeof(cv_zmodules));
|
||||
codeview_init_basic_types(msc_dbg->module);
|
||||
ret = pdb_process_internal(pcs, msc_dbg, pdb_lookup,
|
||||
msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1);
|
||||
codeview_clear_type_table();
|
||||
if (ret)
|
||||
{
|
||||
struct pdb_module_info* pdb_info = msc_dbg->module->format_info[DFI_PDB]->u.pdb_info;
|
||||
msc_dbg->module->module.SymType = SymPdb;
|
||||
if (pdb_info->pdb_files[0].kind == PDB_JG)
|
||||
msc_dbg->module->module.PdbSig = pdb_info->pdb_files[0].u.jg.timestamp;
|
||||
else
|
||||
msc_dbg->module->module.PdbSig70 = pdb_info->pdb_files[0].u.ds.guid;
|
||||
msc_dbg->module->module.PdbAge = pdb_info->pdb_files[0].age;
|
||||
MultiByteToWideChar(CP_ACP, 0, pdb_lookup->filename, -1,
|
||||
msc_dbg->module->module.LoadedPdbName,
|
||||
ARRAY_SIZE(msc_dbg->module->module.LoadedPdbName));
|
||||
/* FIXME: we could have a finer grain here */
|
||||
msc_dbg->module->module.LineNumbers = TRUE;
|
||||
msc_dbg->module->module.GlobalSymbols = TRUE;
|
||||
msc_dbg->module->module.TypeInfo = TRUE;
|
||||
msc_dbg->module->module.SourceIndexed = TRUE;
|
||||
msc_dbg->module->module.Publics = TRUE;
|
||||
}
|
||||
else
|
||||
if (!msc_dbg->module->dont_load_symbols &&
|
||||
path_find_symbol_file(pcs, msc_dbg->module, filename, TRUE, guid, timestamp, age, &info, &unmatched) &&
|
||||
(modfmt = HeapAlloc(GetProcessHeap(), 0,
|
||||
sizeof(struct module_format) + sizeof(struct pdb_module_info))))
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
pdb_module_info = (void*)(modfmt + 1);
|
||||
msc_dbg->module->format_info[DFI_PDB] = modfmt;
|
||||
modfmt->module = msc_dbg->module;
|
||||
modfmt->remove = pdb_module_remove;
|
||||
modfmt->loc_compute = pdb_location_compute;
|
||||
modfmt->u.pdb_info = pdb_module_info;
|
||||
|
||||
memset(cv_zmodules, 0, sizeof(cv_zmodules));
|
||||
codeview_init_basic_types(msc_dbg->module);
|
||||
ret = pdb_process_internal(pcs, msc_dbg, info.pdbfile,
|
||||
msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1);
|
||||
codeview_clear_type_table();
|
||||
if (ret)
|
||||
{
|
||||
msc_dbg->module->module.SymType = SymPdb;
|
||||
msc_dbg->module->module.PdbSig = info.sig;
|
||||
msc_dbg->module->module.PdbAge = info.age;
|
||||
msc_dbg->module->module.PdbSig70 = info.guid;
|
||||
msc_dbg->module->module.PdbUnmatched = unmatched;
|
||||
wcscpy(msc_dbg->module->module.LoadedPdbName, info.pdbfile);
|
||||
|
||||
/* FIXME: we could have a finer grain here */
|
||||
msc_dbg->module->module.LineNumbers = TRUE;
|
||||
msc_dbg->module->module.GlobalSymbols = TRUE;
|
||||
msc_dbg->module->module.TypeInfo = TRUE;
|
||||
msc_dbg->module->module.SourceIndexed = TRUE;
|
||||
msc_dbg->module->module.Publics = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
msc_dbg->module->format_info[DFI_PDB] = NULL;
|
||||
HeapFree(GetProcessHeap(), 0, modfmt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL pdb_fetch_file_info(const struct pdb_lookup* pdb_lookup, unsigned* matched)
|
||||
{
|
||||
HANDLE hFile, hMap = NULL;
|
||||
char* image = NULL;
|
||||
BOOL ret;
|
||||
struct pdb_file_info pdb_file;
|
||||
|
||||
if ((hFile = CreateFileA(pdb_lookup->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ||
|
||||
((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
|
||||
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
||||
{
|
||||
WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
|
||||
ret = FALSE;
|
||||
}
|
||||
msc_dbg->module->module.SymType = SymNone;
|
||||
if (guid)
|
||||
msc_dbg->module->module.PdbSig70 = *guid;
|
||||
else
|
||||
{
|
||||
ret = pdb_init(pdb_lookup, &pdb_file, image, matched);
|
||||
pdb_free_file(&pdb_file);
|
||||
}
|
||||
|
||||
if (image) UnmapViewOfFile(image);
|
||||
if (hMap) CloseHandle(hMap);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
|
||||
return ret;
|
||||
memset(&msc_dbg->module->module.PdbSig70, 0, sizeof(GUID));
|
||||
msc_dbg->module->module.PdbSig = 0;
|
||||
msc_dbg->module->module.PdbAge = age;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
|
@ -4350,12 +4262,11 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
|
|||
#define CODEVIEW_NB11_SIG MAKESIG('N','B','1','1')
|
||||
#define CODEVIEW_RSDS_SIG MAKESIG('R','S','D','S')
|
||||
|
||||
static BOOL codeview_process_info(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg)
|
||||
static BOOL codeview_process_info(const struct process *pcs,
|
||||
const struct msc_debug_info *msc_dbg)
|
||||
{
|
||||
const DWORD* signature = (const DWORD*)msc_dbg->root;
|
||||
BOOL ret = FALSE;
|
||||
struct pdb_lookup pdb_lookup;
|
||||
|
||||
TRACE("Processing signature %.4s\n", (const char*)signature);
|
||||
|
||||
|
@ -4443,11 +4354,7 @@ static BOOL codeview_process_info(const struct process* pcs,
|
|||
case CODEVIEW_NB10_SIG:
|
||||
{
|
||||
const CODEVIEW_PDB_DATA* pdb = (const CODEVIEW_PDB_DATA*)msc_dbg->root;
|
||||
pdb_lookup.filename = pdb->name;
|
||||
pdb_lookup.kind = PDB_JG;
|
||||
pdb_lookup.timestamp = pdb->timestamp;
|
||||
pdb_lookup.age = pdb->age;
|
||||
ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
|
||||
ret = pdb_process_file(pcs, msc_dbg, pdb->name, NULL, pdb->timestamp, pdb->age);
|
||||
break;
|
||||
}
|
||||
case CODEVIEW_RSDS_SIG:
|
||||
|
@ -4456,11 +4363,7 @@ static BOOL codeview_process_info(const struct process* pcs,
|
|||
|
||||
TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
|
||||
wine_dbgstr_guid(&rsds->guid), rsds->age, rsds->name);
|
||||
pdb_lookup.filename = rsds->name;
|
||||
pdb_lookup.kind = PDB_DS;
|
||||
pdb_lookup.guid = rsds->guid;
|
||||
pdb_lookup.age = rsds->age;
|
||||
ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
|
||||
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -4566,6 +4469,26 @@ typedef struct _FPO_DATA
|
|||
ret = FALSE;
|
||||
}
|
||||
__ENDTRY
|
||||
|
||||
/* we haven't found yet any debug information, fallback to unmatched pdb */
|
||||
if (module->module.SymType == SymDeferred)
|
||||
{
|
||||
SYMSRV_INDEX_INFOW info = {.sizeofstruct = sizeof(info)};
|
||||
char buffer[MAX_PATH];
|
||||
char *ext;
|
||||
DWORD options;
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, module->module.LoadedImageName, -1, buffer, ARRAY_SIZE(buffer), 0, NULL);
|
||||
ext = strrchr(buffer, '.');
|
||||
if (ext) strcpy(ext + 1, "pdb"); else strcat(buffer, ".pdb");
|
||||
options = SymGetOptions();
|
||||
SymSetOptions(options | SYMOPT_LOAD_ANYTHING);
|
||||
ret = pdb_process_file(pcs, &msc_dbg, buffer, &null_guid, 0, 0);
|
||||
SymSetOptions(options);
|
||||
if (!ret && module->dont_load_symbols)
|
||||
module->module.TimeDateStamp = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -398,13 +398,6 @@ BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_p
|
|||
|
||||
filename = file_name(full_path);
|
||||
|
||||
/* first check full path to file */
|
||||
if (sffip_cb(full_path, &s))
|
||||
{
|
||||
lstrcpyW(buffer, full_path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
while (searchPath)
|
||||
{
|
||||
ptr = wcschr(searchPath, ';');
|
||||
|
@ -425,6 +418,7 @@ BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_p
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -461,7 +455,7 @@ BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path
|
|||
|
||||
struct module_find
|
||||
{
|
||||
BOOL is_pdb;
|
||||
BOOL is_pdb;
|
||||
/* pdb: guid PDB guid (if DS PDB file)
|
||||
* or dw1 PDB timestamp (if JG PDB file)
|
||||
* dw2 PDB age
|
||||
|
@ -471,7 +465,8 @@ struct module_find
|
|||
const GUID* guid;
|
||||
DWORD dw1;
|
||||
DWORD dw2;
|
||||
WCHAR filename[MAX_PATH];
|
||||
SYMSRV_INDEX_INFOW *info;
|
||||
WCHAR *buffer; /* MAX_PATH + 1 */
|
||||
unsigned matched;
|
||||
};
|
||||
|
||||
|
@ -483,151 +478,119 @@ struct module_find
|
|||
static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
|
||||
{
|
||||
struct module_find* mf = user;
|
||||
DWORD timestamp;
|
||||
unsigned matched = 0;
|
||||
SYMSRV_INDEX_INFOW info;
|
||||
|
||||
/* the matching weights:
|
||||
* +1 if a file with same name is found and is a decent file of expected type
|
||||
* +1 if first parameter and second parameter match
|
||||
*/
|
||||
|
||||
if (mf->is_pdb)
|
||||
{
|
||||
struct pdb_lookup pdb_lookup;
|
||||
char fn[MAX_PATH];
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
|
||||
pdb_lookup.filename = fn;
|
||||
|
||||
if (mf->guid)
|
||||
{
|
||||
pdb_lookup.kind = PDB_DS;
|
||||
pdb_lookup.timestamp = 0;
|
||||
pdb_lookup.guid = *mf->guid;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdb_lookup.kind = PDB_JG;
|
||||
pdb_lookup.timestamp = mf->dw1;
|
||||
/* pdb_loopkup.guid = */
|
||||
}
|
||||
pdb_lookup.age = mf->dw2;
|
||||
|
||||
if (!pdb_fetch_file_info(&pdb_lookup, &matched)) return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
HANDLE hFile, hMap;
|
||||
void* mapping;
|
||||
|
||||
timestamp = ~mf->dw1;
|
||||
hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||
if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
|
||||
{
|
||||
if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
|
||||
{
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER* hdr;
|
||||
hdr = mapping;
|
||||
|
||||
if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
|
||||
{
|
||||
matched++;
|
||||
timestamp = hdr->TimeDateStamp;
|
||||
}
|
||||
UnmapViewOfFile(mapping);
|
||||
}
|
||||
CloseHandle(hMap);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
if (timestamp == mf->dw1) matched++;
|
||||
else WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
|
||||
}
|
||||
info.sizeofstruct = sizeof(info);
|
||||
if (!SymSrvGetFileIndexInfoW(buffer, &info, 0))
|
||||
return FALSE;
|
||||
matched++;
|
||||
if (!memcmp(&info.guid, mf->guid, sizeof(GUID))) matched++;
|
||||
if (info.timestamp == mf->dw1) matched++;
|
||||
if (info.age == mf->dw2) matched++;
|
||||
|
||||
if (matched > mf->matched)
|
||||
{
|
||||
lstrcpyW(mf->filename, buffer);
|
||||
size_t len = min(wcslen(buffer), MAX_PATH);
|
||||
memcpy(mf->buffer, buffer, len * sizeof(WCHAR));
|
||||
mf->buffer[len] = L'\0';
|
||||
mf->matched = matched;
|
||||
mf->info->guid = info.guid;
|
||||
mf->info->timestamp = info.timestamp;
|
||||
mf->info->age = info.age;
|
||||
mf->info->sig = info.sig;
|
||||
}
|
||||
/* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
|
||||
* convention to stop/continue enumeration. sigh.
|
||||
*/
|
||||
return mf->matched == 2;
|
||||
return mf->matched == 4;
|
||||
}
|
||||
|
||||
BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
|
||||
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
||||
WCHAR *buffer, BOOL* is_unmatched)
|
||||
SYMSRV_INDEX_INFOW *info, BOOL* is_unmatched)
|
||||
{
|
||||
struct module_find mf;
|
||||
WCHAR full_pathW[MAX_PATH];
|
||||
WCHAR* ptr;
|
||||
WCHAR *ptr, *ext;
|
||||
const WCHAR* filename;
|
||||
WCHAR* searchPath = pcs->search_path;
|
||||
WCHAR *searchPath = pcs->search_path;
|
||||
WCHAR buffer[MAX_PATH];
|
||||
|
||||
TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08lx, dw2 = 0x%08lx, buffer = %p)\n",
|
||||
pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2, buffer);
|
||||
TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08lx, dw2 = 0x%08lx)\n",
|
||||
pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2);
|
||||
|
||||
mf.info = info;
|
||||
mf.guid = guid;
|
||||
mf.dw1 = dw1;
|
||||
mf.dw2 = dw2;
|
||||
mf.matched = 0;
|
||||
mf.buffer = is_pdb ? info->pdbfile : info->dbgfile;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
|
||||
filename = file_name(full_pathW);
|
||||
MultiByteToWideChar(CP_ACP, 0, full_path, -1, info->file, MAX_PATH);
|
||||
filename = file_name(info->file);
|
||||
mf.is_pdb = is_pdb;
|
||||
*is_unmatched = FALSE;
|
||||
|
||||
/* first check full path to file */
|
||||
if (module_find_cb(full_pathW, &mf))
|
||||
if (is_pdb && module_find_cb(info->file, &mf))
|
||||
{
|
||||
lstrcpyW( buffer, full_pathW );
|
||||
wcscpy( info->pdbfile, info->file );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* FIXME: Use Environment-Variables (see MS docs)
|
||||
_NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH
|
||||
FIXME: Implement "Standard Path Elements" (Path) ... (see MS docs)
|
||||
do a search for (every?) path-element like this ...
|
||||
<path>
|
||||
<path>\dll
|
||||
<path>\symbols\dll
|
||||
(dll may be exe, or sys depending on the file extension) */
|
||||
*/
|
||||
|
||||
/* 2. check module-path */
|
||||
file_pathW(module->module.LoadedImageName, buffer);
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
ext = wcsrchr(module->module.LoadedImageName, L'.');
|
||||
while (searchPath)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
ptr = wcschr(searchPath, ';');
|
||||
len = (ptr) ? ptr - searchPath : wcslen(searchPath);
|
||||
|
||||
if (len + 1 < ARRAY_SIZE(buffer))
|
||||
{
|
||||
memcpy(buffer, searchPath, len * sizeof(WCHAR));
|
||||
buffer[len] = L'\0';
|
||||
/* return first fully matched file */
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
len = wcslen(buffer); /* do_searchW removes the trailing \ in buffer when present */
|
||||
/* check once max size for \symbols\<ext>\ */
|
||||
if (ext && len + 9 /* \symbols\ */ + wcslen(ext + 1) + 1 + 1 <= ARRAY_SIZE(buffer))
|
||||
{
|
||||
buffer[len++] = L'\\';
|
||||
wcscpy(buffer + len, ext + 1);
|
||||
wcscat(buffer + len, L"\\");
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
wcscpy(buffer + len, L"symbols\\");
|
||||
wcscat(buffer + len, ext + 1);
|
||||
wcscat(buffer + len, L"\\");
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR("Too long search element %ls\n", searchPath);
|
||||
searchPath = ptr ? ptr + 1 : NULL;
|
||||
}
|
||||
|
||||
/* check module-path */
|
||||
if (module->real_path)
|
||||
{
|
||||
file_pathW(module->real_path, buffer);
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
}
|
||||
file_pathW(module->module.LoadedImageName, buffer);
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
|
||||
while (searchPath)
|
||||
{
|
||||
ptr = wcschr(searchPath, ';');
|
||||
if (ptr)
|
||||
{
|
||||
memcpy(buffer, searchPath, (ptr - searchPath) * sizeof(WCHAR));
|
||||
buffer[ptr - searchPath] = '\0';
|
||||
searchPath = ptr + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lstrcpyW(buffer, searchPath);
|
||||
searchPath = NULL;
|
||||
}
|
||||
/* return first fully matched file */
|
||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||
}
|
||||
/* if no fully matching file is found, return the best matching file if any */
|
||||
if ((dbghelp_options & SYMOPT_LOAD_ANYTHING) && mf.matched)
|
||||
{
|
||||
lstrcpyW( buffer, mf.filename );
|
||||
*is_unmatched = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
mf.buffer[0] = L'\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,12 +268,11 @@ BOOL pe_map_file(HANDLE file, struct image_file_map* fmap)
|
|||
memcpy(&fmap->u.pe.opt.header32, &nthdr->OptionalHeader, sizeof(fmap->u.pe.opt.header32));
|
||||
break;
|
||||
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
||||
if (sizeof(void*) == 4) return FALSE;
|
||||
fmap->addr_size = 64;
|
||||
memcpy(&fmap->u.pe.opt.header64, &nthdr->OptionalHeader, sizeof(fmap->u.pe.opt.header64));
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
fmap->u.pe.builtin = !memcmp((const IMAGE_DOS_HEADER*)mapping + 1, builtin_signature, sizeof(builtin_signature));
|
||||
|
@ -342,6 +341,52 @@ const char* pe_map_directory(struct module* module, int dirno, DWORD* size)
|
|||
nth->OptionalHeader.DataDirectory[dirno].VirtualAddress, NULL);
|
||||
}
|
||||
|
||||
BOOL pe_unmap_directory(struct module* module, int dirno, const char *dir)
|
||||
{
|
||||
if (module->type != DMT_PE || !module->format_info[DFI_PE]) return FALSE;
|
||||
if (dirno >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) return FALSE;
|
||||
pe_unmap_full(&module->format_info[DFI_PE]->u.pe_info->fmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Locks a region from a mapped PE file, from its RVA, and for at least 'size' bytes.
|
||||
* Region must fit entirely inside a PE section.
|
||||
* 'length', upon success, gets the size from RVA until end of PE section.
|
||||
*/
|
||||
const BYTE* pe_lock_region_from_rva(struct module *module, DWORD rva, DWORD size, DWORD *length)
|
||||
{
|
||||
IMAGE_NT_HEADERS* nth;
|
||||
void* mapping;
|
||||
IMAGE_SECTION_HEADER *section;
|
||||
const BYTE *ret;
|
||||
|
||||
if (module->type != DMT_PE || !module->format_info[DFI_PE]) return NULL;
|
||||
if (!(mapping = pe_map_full(&module->format_info[DFI_PE]->u.pe_info->fmap, &nth)))
|
||||
return NULL;
|
||||
section = NULL;
|
||||
ret = RtlImageRvaToVa(nth, mapping, rva, §ion);
|
||||
if (ret)
|
||||
{
|
||||
if (rva + size <= section->VirtualAddress + section->SizeOfRawData)
|
||||
{
|
||||
if (length)
|
||||
*length = section->VirtualAddress + section->SizeOfRawData - rva;
|
||||
return ret;
|
||||
}
|
||||
if (rva + size <= section->VirtualAddress + section->Misc.VirtualSize)
|
||||
FIXME("Not able to lock regions not present on file\n");
|
||||
}
|
||||
pe_unmap_full(&module->format_info[DFI_PE]->u.pe_info->fmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL pe_unlock_region(struct module *module, const BYTE* region)
|
||||
{
|
||||
if (module->type != DMT_PE || !module->format_info[DFI_PE] || !region) return FALSE;
|
||||
pe_unmap_full(&module->format_info[DFI_PE]->u.pe_info->fmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void pe_module_remove(struct process* pcs, struct module_format* modfmt)
|
||||
{
|
||||
image_unmap_file(&modfmt->u.pe_info->fmap);
|
||||
|
@ -543,15 +588,15 @@ static BOOL pe_load_dwarf(struct module* module)
|
|||
static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
|
||||
const char* dbg_name, DWORD timestamp)
|
||||
{
|
||||
WCHAR tmp[MAX_PATH];
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
|
||||
const BYTE* dbg_mapping = NULL;
|
||||
BOOL ret = FALSE;
|
||||
SYMSRV_INDEX_INFOW info;
|
||||
|
||||
TRACE("Processing DBG file %s\n", debugstr_a(dbg_name));
|
||||
|
||||
if (path_find_symbol_file(pcs, module, dbg_name, FALSE, NULL, timestamp, 0, tmp, &module->module.DbgUnmatched) &&
|
||||
(hFile = CreateFileW(tmp, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
if (path_find_symbol_file(pcs, module, dbg_name, FALSE, NULL, timestamp, 0, &info, &module->module.DbgUnmatched) &&
|
||||
(hFile = CreateFileW(info.dbgfile, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
|
||||
((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
|
||||
((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
|
||||
|
@ -574,7 +619,7 @@ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
|
|||
hdr->DebugDirectorySize / sizeof(*dbg));
|
||||
}
|
||||
else
|
||||
ERR("Couldn't find .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_w(tmp));
|
||||
ERR("Couldn't find .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_w(info.dbgfile));
|
||||
|
||||
if (dbg_mapping) UnmapViewOfFile(dbg_mapping);
|
||||
if (hMap) CloseHandle(hMap);
|
||||
|
@ -599,7 +644,7 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
|
|||
if (!(mapping = pe_map_full(fmap, &nth))) return FALSE;
|
||||
/* Read in debug directory */
|
||||
dbg = RtlImageDirectoryEntryToData( mapping, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &nDbg );
|
||||
if (!dbg || !(nDbg /= sizeof(IMAGE_DEBUG_DIRECTORY))) goto done;
|
||||
nDbg = dbg ? nDbg / sizeof(IMAGE_DEBUG_DIRECTORY) : 0;
|
||||
|
||||
/* Parse debug directory */
|
||||
if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
|
||||
|
@ -625,7 +670,6 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
|
|||
ret = pe_load_debug_directory(pcs, module, mapping, IMAGE_FIRST_SECTION( nth ),
|
||||
nth->FileHeader.NumberOfSections, dbg, nDbg);
|
||||
}
|
||||
done:
|
||||
pe_unmap_full(fmap);
|
||||
return ret;
|
||||
}
|
||||
|
@ -722,9 +766,12 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
|
|||
|
||||
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
||||
{
|
||||
ret = image_check_alternate(&module->format_info[DFI_PE]->u.pe_info->fmap, module);
|
||||
ret = pe_load_stabs(pcs, module) || ret;
|
||||
ret = pe_load_dwarf(module) || ret;
|
||||
if (!module->dont_load_symbols)
|
||||
{
|
||||
ret = image_check_alternate(&module->format_info[DFI_PE]->u.pe_info->fmap, module);
|
||||
ret = pe_load_stabs(pcs, module) || ret;
|
||||
ret = pe_load_dwarf(module) || ret;
|
||||
}
|
||||
ret = pe_load_msc_debug_info(pcs, module) || ret;
|
||||
ret = ret || pe_load_coff_symbol_table(module); /* FIXME */
|
||||
/* if we still have no debug info (we could only get SymExport at this
|
||||
|
|
|
@ -2614,10 +2614,16 @@ BOOL WINAPI SymGetLineFromNameW64(HANDLE hProcess, PCWSTR ModuleName, PCWSTR Fil
|
|||
*/
|
||||
BOOL WINAPI SymFromIndex(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFO symbol)
|
||||
{
|
||||
FIXME("hProcess = %p, BaseOfDll = %I64x, index = %ld, symbol = %p\n",
|
||||
struct module_pair pair;
|
||||
struct symt* sym;
|
||||
|
||||
TRACE("hProcess = %p, BaseOfDll = %I64x, index = %ld, symbol = %p\n",
|
||||
hProcess, BaseOfDll, index, symbol);
|
||||
|
||||
return FALSE;
|
||||
if (!module_init_pair(&pair, hProcess, BaseOfDll)) return FALSE;
|
||||
if ((sym = symt_index2ptr(pair.effective, index)) == NULL) return FALSE;
|
||||
symt_fill_sym_info(&pair, NULL, sym, symbol);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
@ -2626,10 +2632,21 @@ BOOL WINAPI SymFromIndex(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBO
|
|||
*/
|
||||
BOOL WINAPI SymFromIndexW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD index, PSYMBOL_INFOW symbol)
|
||||
{
|
||||
FIXME("hProcess = %p, BaseOfDll = %I64x, index = %ld, symbol = %p\n",
|
||||
PSYMBOL_INFO si;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("hProcess = %p, BaseOfDll = %I64x, index = %ld, symbol = %p\n",
|
||||
hProcess, BaseOfDll, index, symbol);
|
||||
|
||||
return FALSE;
|
||||
si = HeapAlloc(GetProcessHeap(), 0, sizeof(*si) + symbol->MaxNameLen * sizeof(WCHAR));
|
||||
if (!si) return FALSE;
|
||||
|
||||
si->SizeOfStruct = sizeof(*si);
|
||||
si->MaxNameLen = symbol->MaxNameLen;
|
||||
if ((ret = SymFromIndex(hProcess, BaseOfDll, index, si)))
|
||||
copy_symbolW(symbol, si);
|
||||
HeapFree(GetProcessHeap(), 0, si);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -3,4 +3,5 @@ IMPORTS = dbghelp user32
|
|||
|
||||
SOURCES = \
|
||||
dbghelp.c \
|
||||
minidump.c \
|
||||
path.c
|
||||
|
|
|
@ -1492,6 +1492,43 @@ static void test_live_modules(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define test_function_table_main_module(b) _test_function_table_entry(__LINE__, NULL, #b, (DWORD64)(DWORD_PTR)&(b))
|
||||
#define test_function_table_module(a, b) _test_function_table_entry(__LINE__, a, #b, (DWORD64)(DWORD_PTR)GetProcAddress(GetModuleHandleA(a), (b)))
|
||||
static void *_test_function_table_entry(unsigned lineno, const char *modulename, const char *name, DWORD64 addr)
|
||||
{
|
||||
DWORD64 base_module = (DWORD64)(DWORD_PTR)GetModuleHandleA(modulename);
|
||||
|
||||
if (RtlImageNtHeader(GetModuleHandleW(NULL))->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY *func;
|
||||
|
||||
func = SymFunctionTableAccess64(GetCurrentProcess(), addr);
|
||||
ok_(__FILE__, lineno)(func != NULL, "Couldn't find function table for %s\n", name);
|
||||
if (func)
|
||||
{
|
||||
ok_(__FILE__, lineno)(func->BeginAddress == addr - base_module, "Unexpected start of function\n");
|
||||
ok_(__FILE__, lineno)(func->BeginAddress < func->EndAddress, "Unexpected end of function\n");
|
||||
ok_(__FILE__, lineno)((func->UnwindData & 1) == 0, "Unexpected chained runtime function\n");
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_function_tables(void)
|
||||
{
|
||||
void *ptr1, *ptr2;
|
||||
|
||||
SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||
ptr1 = test_function_table_main_module(test_live_modules);
|
||||
ptr2 = test_function_table_main_module(test_function_tables);
|
||||
ok(ptr1 == ptr2, "Expecting unique storage area\n");
|
||||
ptr2 = test_function_table_module("kernel32.dll", "CreateFileMappingA");
|
||||
ok(ptr1 == ptr2, "Expecting unique storage area\n");
|
||||
SymCleanup(GetCurrentProcess());
|
||||
}
|
||||
|
||||
START_TEST(dbghelp)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -1523,4 +1560,5 @@ START_TEST(dbghelp)
|
|||
test_loaded_modules();
|
||||
test_live_modules();
|
||||
}
|
||||
test_function_tables();
|
||||
}
|
||||
|
|
864
dlls/dbghelp/tests/minidump.c
Normal file
864
dlls/dbghelp/tests/minidump.c
Normal file
|
@ -0,0 +1,864 @@
|
|||
/*
|
||||
* Copyright 2024 Eric Pouech for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windows.h"
|
||||
#include "dbghelp.h"
|
||||
#include "wine/test.h"
|
||||
#include "winternl.h"
|
||||
#include "winnt.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
static unsigned popcount32(ULONG val)
|
||||
{
|
||||
val -= val >> 1 & 0x55555555;
|
||||
val = (val & 0x33333333) + (val >> 2 & 0x33333333);
|
||||
return ((val + (val >> 4)) & 0x0f0f0f0f) * 0x01010101 >> 24;
|
||||
}
|
||||
|
||||
static inline unsigned popcount64(ULONG64 val)
|
||||
{
|
||||
return popcount32(val >> 32) + popcount32(val);
|
||||
}
|
||||
|
||||
#define minidump_open_for_read(a) _minidump_open_for_read(__LINE__, (a))
|
||||
static MINIDUMP_HEADER *_minidump_open_for_read(unsigned line, const char *filename)
|
||||
{
|
||||
MINIDUMP_HEADER *hdr;
|
||||
HANDLE file, map;
|
||||
BOOL ret;
|
||||
|
||||
file = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
ok_(__FILE__, line)(file != INVALID_HANDLE_VALUE, "Couldn't reopen file\n");
|
||||
map = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
ok_(__FILE__, line)(map != 0, "Couldn't map file\n");
|
||||
hdr = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
|
||||
ok(hdr != NULL, "Couldn't map file\n");
|
||||
|
||||
ok(hdr && hdr->Signature == MINIDUMP_SIGNATURE, "Unexpected signature\n");
|
||||
|
||||
ret = CloseHandle(map);
|
||||
ok_(__FILE__, line)(ret, "Couldn't unmap file\n");
|
||||
ret = CloseHandle(file);
|
||||
ok_(__FILE__, line)(ret, "Couldn't close file\n");
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
#define minidump_close_for_read(a) _minidump_close_for_read(__LINE__, (a))
|
||||
static void _minidump_close_for_read(unsigned line, MINIDUMP_HEADER *data)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
ret = UnmapViewOfFile(data);
|
||||
ok_(__FILE__, line)(ret, "Couldn't unmap file\n");
|
||||
}
|
||||
|
||||
static BOOL minidump_write(HANDLE proc, const WCHAR *filename, MINIDUMP_TYPE type, BOOL windows_can_fail,
|
||||
MINIDUMP_EXCEPTION_INFORMATION *mei, MINIDUMP_CALLBACK_INFORMATION *cbi)
|
||||
{
|
||||
HANDLE file;
|
||||
BOOL ret, ret2;
|
||||
|
||||
file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
ok(file != INVALID_HANDLE_VALUE, "Failed to create minidump %ls\n", filename);
|
||||
|
||||
ret = MiniDumpWriteDump(proc, GetProcessId(proc), file, type, mei, NULL, cbi);
|
||||
/* using new features that are not supported on old dbghelp versions */
|
||||
ok(ret || broken(windows_can_fail), "Couldn't write minidump content\n");
|
||||
|
||||
ret2 = CloseHandle(file);
|
||||
ok(ret2, "Couldn't close file\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef DWORD64 stream_mask_t;
|
||||
#define STREAM2MASK(st) (((stream_mask_t)1) << (st))
|
||||
|
||||
#define BASIC_STREAM_MASK \
|
||||
(STREAM2MASK(ThreadListStream) | STREAM2MASK(ModuleListStream) | STREAM2MASK(MemoryListStream) | \
|
||||
STREAM2MASK(SystemInfoStream) | STREAM2MASK(MiscInfoStream) | STREAM2MASK(SystemMemoryInfoStream) | \
|
||||
STREAM2MASK(ProcessVmCountersStream))
|
||||
/* streams added in Win8 & Win10... */
|
||||
#define BASIC_STREAM_BROKEN_MASK (STREAM2MASK(SystemMemoryInfoStream) | STREAM2MASK(ProcessVmCountersStream))
|
||||
#define BASIC_STREAM_TODO_MASK (STREAM2MASK(SystemMemoryInfoStream) | STREAM2MASK(ProcessVmCountersStream))
|
||||
static void test_minidump_contents(void)
|
||||
{
|
||||
static const struct minidump_streams
|
||||
{
|
||||
MINIDUMP_TYPE type;
|
||||
stream_mask_t streams_mask;
|
||||
stream_mask_t todo_wine_mask;
|
||||
}
|
||||
streams_table[] =
|
||||
{
|
||||
/* 0 */ {MiniDumpNormal, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK},
|
||||
{MiniDumpWithDataSegs, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK},
|
||||
{MiniDumpWithProcessThreadData, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK},
|
||||
{MiniDumpWithThreadInfo, BASIC_STREAM_MASK | STREAM2MASK(ThreadInfoListStream), BASIC_STREAM_TODO_MASK | STREAM2MASK(ThreadInfoListStream)},
|
||||
{MiniDumpWithCodeSegs, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK},
|
||||
/* 5 */ {MiniDumpWithTokenInformation, BASIC_STREAM_MASK | STREAM2MASK(TokenStream), BASIC_STREAM_TODO_MASK | STREAM2MASK(TokenStream)},
|
||||
{MiniDumpWithModuleHeaders, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK}, /* requires win8 at least */
|
||||
{MiniDumpWithAvxXStateContext, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK}, /* requires win10 at least */
|
||||
{MiniDumpWithIptTrace, BASIC_STREAM_MASK, BASIC_STREAM_TODO_MASK},
|
||||
};
|
||||
MINIDUMP_HEADER *hdr;
|
||||
void *where;
|
||||
ULONG size;
|
||||
BOOL ret;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(streams_table); i++)
|
||||
{
|
||||
winetest_push_context("streams_table[%d]", i);
|
||||
|
||||
/* too old for dbghelp in Win7 & 8 */
|
||||
if (minidump_write(GetCurrentProcess(), L"foo.mdmp", streams_table[i].type, i >= 6, NULL, NULL))
|
||||
{
|
||||
hdr = minidump_open_for_read("foo.mdmp");
|
||||
/* native keeps (likely padding) some unused streams at the end of directory, but lists them here */
|
||||
ok(hdr->NumberOfStreams >= popcount64(streams_table[i].streams_mask), "Unexpected number of streams %u <> %u\n",
|
||||
hdr->NumberOfStreams, popcount64(streams_table[i].streams_mask));
|
||||
ok(hdr->Flags == streams_table[i].type, "Unexpected flags\n");
|
||||
/* start at 3, 0=unused (cf above), 1,2=reserved shall be skipped */
|
||||
for (j = 3; j < 25 /* last documented stream */; j++)
|
||||
{
|
||||
ret = MiniDumpReadDumpStream(hdr, j, NULL, &where, &size);
|
||||
todo_wine_if(streams_table[i].todo_wine_mask & STREAM2MASK(j))
|
||||
if (streams_table[i].streams_mask & STREAM2MASK(j))
|
||||
ok((ret && where) || broken(BASIC_STREAM_BROKEN_MASK & STREAM2MASK(j)), "Expecting stream %d to be present\n", j);
|
||||
else
|
||||
ok(!ret, "Not expecting stream %d to be present\n", j);
|
||||
}
|
||||
|
||||
minidump_close_for_read(hdr);
|
||||
|
||||
ret = DeleteFileA("foo.mdmp");
|
||||
ok(ret, "Couldn't delete file\n");
|
||||
}
|
||||
else win_skip("Skipping not supported feature (too old dbghelp version)\n");
|
||||
winetest_pop_context();
|
||||
}
|
||||
}
|
||||
|
||||
static void minidump_check_nostream(void *data, MINIDUMP_STREAM_TYPE stream_type)
|
||||
{
|
||||
void *stream;
|
||||
BOOL ret;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, stream_type, NULL, (void**)&stream, NULL);
|
||||
ok(!ret, "Unexpected stream %u\n", stream_type);
|
||||
}
|
||||
|
||||
static void minidump_check_pid(void *data, DWORD pid)
|
||||
{
|
||||
MINIDUMP_MISC_INFO *misc_info;
|
||||
BOOL ret;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, MiscInfoStream, NULL, (void**)&misc_info, NULL);
|
||||
ok(ret && misc_info, "Couldn't find misc-info stream\n");
|
||||
ok(misc_info->Flags1 & misc_info->Flags1 & MINIDUMP_MISC1_PROCESS_ID, "No process-id in misc_info\n");
|
||||
ok(pid == misc_info->ProcessId, "Unexpected process id\n");
|
||||
}
|
||||
|
||||
static unsigned minidump_get_number_of_threads(void *data)
|
||||
{
|
||||
MINIDUMP_THREAD_LIST *thread_list;
|
||||
BOOL ret;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, ThreadListStream, NULL, (void**)&thread_list, NULL);
|
||||
ok(ret && thread_list, "Couldn't find thread-list stream\n");
|
||||
return thread_list->NumberOfThreads;
|
||||
}
|
||||
|
||||
static void minidump_check_threads(void *data)
|
||||
{
|
||||
MINIDUMP_THREAD_LIST *thread_list;
|
||||
ULONG stream_size;
|
||||
int i;
|
||||
BOOL ret;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, ThreadListStream, NULL, (void**)&thread_list, &stream_size);
|
||||
ok(ret && thread_list, "Couldn't find thread-list stream\n");
|
||||
ok(stream_size == sizeof(thread_list->NumberOfThreads) + thread_list->NumberOfThreads * sizeof(thread_list->Threads[0]),
|
||||
"Unexpected size\n");
|
||||
for (i = 0; i < thread_list->NumberOfThreads; i++)
|
||||
{
|
||||
const MINIDUMP_THREAD *thread = &thread_list->Threads[i];
|
||||
const CONTEXT *ctx;
|
||||
|
||||
ok(thread->SuspendCount == 0, "Unexpected value\n");
|
||||
ok(thread->Stack.StartOfMemoryRange, "Unexpected value %I64x\n", thread->Stack.StartOfMemoryRange);
|
||||
ok(thread->Stack.Memory.DataSize, "Unexpected value %x\n", thread->Stack.Memory.DataSize);
|
||||
ok(thread->Teb, "Unexpected value\n");
|
||||
ok(thread->ThreadContext.DataSize >= sizeof(CONTEXT), "Unexpected value\n");
|
||||
ctx = RVA_TO_ADDR(data, thread->ThreadContext.Rva);
|
||||
ok((ctx->ContextFlags & CONTEXT_ALL) == CONTEXT_ALL, "Unexpected value\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void minidump_check_module(void *data, const WCHAR *name, DWORD64 base)
|
||||
{
|
||||
MINIDUMP_MODULE_LIST *module_list;
|
||||
size_t namelen = wcslen(name);
|
||||
int i;
|
||||
BOOL ret;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, ModuleListStream, NULL, (void**)&module_list, NULL);
|
||||
ok(ret && module_list, "Couldn't find module-list stream\n");
|
||||
ok(module_list->NumberOfModules > 3, "Unexpected number of modules\n");
|
||||
for (i = 0; i < module_list->NumberOfModules; i++)
|
||||
{
|
||||
MINIDUMP_MODULE *module = &module_list->Modules[i];
|
||||
WCHAR *ptr;
|
||||
|
||||
MINIDUMP_STRING *string = RVA_TO_ADDR(data, module->ModuleNameRva);
|
||||
for (ptr = string->Buffer + string->Length / sizeof(WCHAR) - 1; ptr >= string->Buffer && *ptr != L'\\'; ptr--) {}
|
||||
ptr++;
|
||||
if (ptr + namelen == string->Buffer + string->Length / sizeof(WCHAR) &&
|
||||
!wcsnicmp(name, ptr, namelen) &&
|
||||
module->BaseOfImage == base) break;
|
||||
}
|
||||
ok(i < module_list->NumberOfModules, "Couldn't find module %ls in minidump\n", name);
|
||||
}
|
||||
|
||||
struct memory_description
|
||||
{
|
||||
/* MD_SECTION, MD_DIRECTORY can be present at the same time */
|
||||
/* MD_UNMAPPED: some DLLs are present when creating the minidump, but are unloaded afterwards (native) */
|
||||
enum {MD_NONE = 0, MD_UNMAPPED = 1, MD_PE_HEADER = 2, MD_STACK = 3, MD_SECTION = 4, MD_DIRECTORY = 8, MD_UNWIND = 16} kind;
|
||||
unsigned id; /* MD_STACK: thread index
|
||||
* MD_DIRECTORY: directory index
|
||||
* MD_UNWIND: function index in function table
|
||||
*/
|
||||
const char* name; /* MD_SECTION: section name */
|
||||
};
|
||||
|
||||
static struct memory_description minidump_get_memory_description(void *data, DWORD64 addr)
|
||||
{
|
||||
const BYTE *addr_ptr = (void*)(ULONG_PTR)addr;
|
||||
MINIDUMP_MODULE_LIST *module_list;
|
||||
MINIDUMP_THREAD_LIST *thread_list;
|
||||
struct memory_description md = {.kind = MD_NONE};
|
||||
BOOL ret;
|
||||
int i, j, dir;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, ModuleListStream, NULL, (void**)&module_list, NULL);
|
||||
ok(ret && module_list, "Couldn't find module-list stream\n");
|
||||
for (i = 0; i < module_list->NumberOfModules; i++)
|
||||
{
|
||||
MINIDUMP_MODULE *module = &module_list->Modules[i];
|
||||
MINIDUMP_STRING *string = RVA_TO_ADDR(data, module->ModuleNameRva);
|
||||
if (module->BaseOfImage <= addr && addr < module->BaseOfImage + module->SizeOfImage)
|
||||
{
|
||||
HMODULE module_handle;
|
||||
WCHAR *module_name;
|
||||
size_t module_name_len = string->Length / sizeof(WCHAR);
|
||||
IMAGE_NT_HEADERS *nthdr;
|
||||
|
||||
module_name = malloc((module_name_len + 1) * sizeof(WCHAR));
|
||||
if (!module_name) continue;
|
||||
memcpy(module_name, string->Buffer, module_name_len * sizeof(WCHAR));
|
||||
module_name[module_name_len] = L'\0';
|
||||
module_handle = GetModuleHandleW(module_name);
|
||||
if ((nthdr = RtlImageNtHeader(module_handle)))
|
||||
{
|
||||
for (dir = 0; dir < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; dir++)
|
||||
{
|
||||
ULONG dir_size;
|
||||
const BYTE *dir_start = RtlImageDirectoryEntryToData(module_handle, TRUE, dir, &dir_size);
|
||||
if (dir_start && dir_start <= addr_ptr && addr_ptr < dir_start + dir_size)
|
||||
{
|
||||
md.kind |= MD_DIRECTORY;
|
||||
md.id = dir;
|
||||
}
|
||||
switch (dir)
|
||||
{
|
||||
case IMAGE_DIRECTORY_ENTRY_EXCEPTION:
|
||||
if (nthdr->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
const IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY *func;
|
||||
for (func = (const void*)dir_start; func < (const IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY *)(dir_start + dir_size); func++)
|
||||
{
|
||||
if (RtlImageRvaToVa(nthdr, module_handle, func->UnwindData, NULL) == addr_ptr)
|
||||
{
|
||||
md.kind = MD_UNWIND;
|
||||
md.id = func - (const IMAGE_AMD64_RUNTIME_FUNCTION_ENTRY *)dir_start;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* FIXME handle more areas: import/export tables... */
|
||||
}
|
||||
}
|
||||
if (addr < (DWORD_PTR)(IMAGE_FIRST_SECTION(nthdr) + nthdr->FileHeader.NumberOfSections))
|
||||
{
|
||||
md.kind = MD_PE_HEADER;
|
||||
}
|
||||
for (j = 0; j < nthdr->FileHeader.NumberOfSections; j++)
|
||||
{
|
||||
IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(nthdr) + j;
|
||||
const BYTE *section_start = (BYTE*)module_handle + section->VirtualAddress;
|
||||
if (section_start <= addr_ptr && addr_ptr < section_start + section->Misc.VirtualSize)
|
||||
{
|
||||
md.kind |= MD_SECTION;
|
||||
md.name = (const char*)section->Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
else md.kind = MD_UNMAPPED;
|
||||
free(module_name);
|
||||
return md;
|
||||
}
|
||||
}
|
||||
ret = MiniDumpReadDumpStream(data, ThreadListStream, NULL, (void**)&thread_list, NULL);
|
||||
ok(ret && thread_list, "Couldn't find thread-list stream\n");
|
||||
for (i = 0; i < thread_list->NumberOfThreads; i++)
|
||||
{
|
||||
MINIDUMP_THREAD *thread = &thread_list->Threads[i];
|
||||
if (thread->Stack.StartOfMemoryRange <= addr &&
|
||||
addr < thread->Stack.StartOfMemoryRange + thread->Stack.Memory.DataSize)
|
||||
{
|
||||
md.kind = MD_STACK;
|
||||
md.id = i;
|
||||
return md;
|
||||
}
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
||||
/* modules could be load/unloaded when generating the minidump, so count the number of available modules */
|
||||
static unsigned minidump_get_number_of_available_modules(void *data)
|
||||
{
|
||||
MINIDUMP_MODULE_LIST *module_list;
|
||||
unsigned num_modules = 0;
|
||||
BOOL ret;
|
||||
int i;
|
||||
ret = MiniDumpReadDumpStream(data, ModuleListStream, NULL, (void**)&module_list, NULL);
|
||||
ok(ret && module_list, "Couldn't find module-list stream\n");
|
||||
for (i = 0; i < module_list->NumberOfModules; i++)
|
||||
{
|
||||
struct memory_description md;
|
||||
md = minidump_get_memory_description(data, module_list->Modules[i].BaseOfImage);
|
||||
if (md.kind != MD_UNMAPPED)
|
||||
num_modules++;
|
||||
}
|
||||
return num_modules;
|
||||
}
|
||||
|
||||
struct memory_walker
|
||||
{
|
||||
unsigned num_unknown; /* number of unknown memory locations */
|
||||
unsigned num_thread_stack; /* number of locations inside a thread stack */
|
||||
unsigned num_directories[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /* number of locations in side the directories' content */
|
||||
unsigned num_text; /* number of locations inside .text section */
|
||||
unsigned num_unwind_info;
|
||||
};
|
||||
|
||||
static void minidump_walk_memory(void *data, struct memory_walker *walker)
|
||||
{
|
||||
MINIDUMP_MEMORY_LIST *memory_list;
|
||||
BOOL ret;
|
||||
int i;
|
||||
|
||||
ret = MiniDumpReadDumpStream(data, MemoryListStream, NULL, (void**)&memory_list, NULL);
|
||||
ok(ret && memory_list, "Couldn't find memory-list stream\n");
|
||||
for (i = 0; i < memory_list->NumberOfMemoryRanges; i++)
|
||||
{
|
||||
MINIDUMP_MEMORY_DESCRIPTOR *desc = &memory_list->MemoryRanges[i];
|
||||
struct memory_description md;
|
||||
md = minidump_get_memory_description(data, desc->StartOfMemoryRange);
|
||||
switch ((int)md.kind)
|
||||
{
|
||||
case MD_NONE:
|
||||
walker->num_unknown++;
|
||||
break;
|
||||
case MD_UNMAPPED:
|
||||
/* nothing we can do here */
|
||||
break;
|
||||
case MD_STACK:
|
||||
walker->num_thread_stack++;
|
||||
break;
|
||||
case MD_SECTION | MD_UNWIND:
|
||||
walker->num_unwind_info++;
|
||||
break;
|
||||
case MD_PE_HEADER:
|
||||
/* FIXME may change with MiniDumpWithModuleHeaders */
|
||||
ok(0, "Unexpected memory block in PE header\n");
|
||||
break;
|
||||
case MD_SECTION:
|
||||
case MD_SECTION | MD_DIRECTORY:
|
||||
if (!strcmp(md.name, ".text"))
|
||||
walker->num_text++;
|
||||
if (md.kind & MD_DIRECTORY)
|
||||
{
|
||||
ok(md.id < ARRAY_SIZE(walker->num_directories), "Out of bounds index\n");
|
||||
walker->num_directories[md.id]++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ok(0, "Unexpected memory description kind: %x\n", md.kind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_current_process(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
MINIDUMP_TYPE dump_type;
|
||||
}
|
||||
process_tests[] =
|
||||
{
|
||||
{ MiniDumpNormal /* = 0 */ },
|
||||
{ MiniDumpWithCodeSegs },
|
||||
{ MiniDumpWithDataSegs },
|
||||
{ MiniDumpWithThreadInfo },
|
||||
/* requires more work
|
||||
{ MiniDumpWithModuleHeaders },
|
||||
{ MiniDumpWithProcessThreadData },
|
||||
*/
|
||||
};
|
||||
struct memory_walker walker;
|
||||
struct memory_description md, md2;
|
||||
unsigned num_available_modules, num_threads;
|
||||
void *data;
|
||||
BOOL ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(process_tests); i++)
|
||||
{
|
||||
winetest_push_context("process_tests[%d]", i);
|
||||
minidump_write(GetCurrentProcess(), L"foo.mdmp", process_tests[i].dump_type, FALSE, NULL, NULL);
|
||||
|
||||
data = minidump_open_for_read("foo.mdmp");
|
||||
|
||||
num_threads = minidump_get_number_of_threads(data);
|
||||
ok(num_threads > 0, "Unexpected number of threads\n");
|
||||
|
||||
minidump_check_threads(data);
|
||||
md = minidump_get_memory_description(data, (DWORD_PTR)&i);
|
||||
ok(md.kind == MD_STACK, "Couldn't find automatic variable\n");
|
||||
|
||||
md2 = minidump_get_memory_description(data, (DWORD_PTR)NtCurrentTeb()->Tib.StackBase - sizeof(void*));
|
||||
ok(md2.kind == MD_STACK, "Couldn't find stack bottom\n");
|
||||
ok(md.id == md2.id, "Should be on same stack\n");
|
||||
|
||||
minidump_check_pid(data, GetCurrentProcessId());
|
||||
num_available_modules = minidump_get_number_of_available_modules(data);
|
||||
#define CHECK_MODULE(s) minidump_check_module(data, s, (DWORD64)(DWORD_PTR)GetModuleHandleW(s))
|
||||
CHECK_MODULE(L"ntdll.dll");
|
||||
CHECK_MODULE(L"kernelbase.dll");
|
||||
CHECK_MODULE(L"kernel32.dll");
|
||||
CHECK_MODULE(L"dbghelp.dll");
|
||||
#undef CHECK_MODULE
|
||||
|
||||
memset(&walker, 0, sizeof(walker));
|
||||
minidump_walk_memory(data, &walker);
|
||||
|
||||
ok(walker.num_unknown == 0, "unexpected unknown memory locations\n");
|
||||
ok(walker.num_thread_stack == num_threads, "Unexpected number of stacks\n");
|
||||
|
||||
if (sizeof(void*) > 4 && (process_tests[i].dump_type & MiniDumpWithModuleHeaders))
|
||||
ok(walker.num_directories[IMAGE_DIRECTORY_ENTRY_EXCEPTION] > 0, "expected unwind information\n");
|
||||
else
|
||||
ok(walker.num_directories[IMAGE_DIRECTORY_ENTRY_EXCEPTION] == 0, "unexpected unwind information\n");
|
||||
if (process_tests[i].dump_type & MiniDumpWithCodeSegs)
|
||||
{
|
||||
todo_wine
|
||||
ok(walker.num_text >= num_available_modules ||
|
||||
/* win7 & 8 report one less */
|
||||
broken(walker.num_text + 1 >= num_available_modules), "expected code segments %u %u\n", walker.num_text, num_available_modules);
|
||||
}
|
||||
else
|
||||
/* native embeds some elements in code segment from ntdll */
|
||||
ok(walker.num_text < 5, "unexpected code segments %u %u\n", walker.num_text, num_available_modules);
|
||||
|
||||
ok(walker.num_unwind_info == 0, "unexpected unwind info %u\n", walker.num_unwind_info);
|
||||
minidump_check_nostream(data, ExceptionStream);
|
||||
|
||||
minidump_close_for_read(data);
|
||||
|
||||
ret = DeleteFileA("foo.mdmp");
|
||||
ok(ret, "Couldn't delete file\n");
|
||||
winetest_pop_context();
|
||||
}
|
||||
}
|
||||
|
||||
struct cb_info
|
||||
{
|
||||
/* input */
|
||||
unsigned module_flags;
|
||||
unsigned thread_flags;
|
||||
/* output */
|
||||
DWORD64 mask_types;
|
||||
unsigned num_modules;
|
||||
unsigned num_threads;
|
||||
unsigned num_include_modules;
|
||||
unsigned num_include_threads;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK test_callback_cb(void *pmt, MINIDUMP_CALLBACK_INPUT *input, MINIDUMP_CALLBACK_OUTPUT *output)
|
||||
{
|
||||
struct cb_info *cb = pmt;
|
||||
|
||||
ok(input->CallbackType < sizeof(cb->mask_types) * 8, "Too small mask\n");
|
||||
cb->mask_types |= (DWORD64)1u << input->CallbackType;
|
||||
|
||||
if (input->CallbackType == WriteKernelMinidumpCallback || input->CallbackType == IoStartCallback)
|
||||
{
|
||||
ok(input->ProcessId == 0, "Unexpected pid %lu %lu\n", input->ProcessId, input->CallbackType);
|
||||
ok(input->ProcessHandle == NULL, "Unexpected process handle %p %lu\n", input->ProcessHandle, input->CallbackType);
|
||||
}
|
||||
else if (input->CallbackType == IsProcessSnapshotCallback || input->CallbackType == VmStartCallback)
|
||||
{
|
||||
ok(input->ProcessId == 0, "Unexpected pid %lu %lu\n", input->ProcessId, input->CallbackType);
|
||||
ok(input->ProcessHandle == GetCurrentProcess(), "Unexpected process handle %p %lu\n", input->ProcessHandle, input->CallbackType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(input->ProcessId == GetCurrentProcessId(), "Unexpected pid %lu %lu\n", input->ProcessId, input->CallbackType);
|
||||
ok(input->ProcessHandle == GetCurrentProcess(), "Unexpected process handle %p %lu\n", input->ProcessHandle, input->CallbackType);
|
||||
}
|
||||
|
||||
switch (input->CallbackType)
|
||||
{
|
||||
case ModuleCallback:
|
||||
ok(output->ModuleWriteFlags == cb->module_flags, "Unexpected module flags %lx\n", output->ModuleWriteFlags);
|
||||
cb->num_modules++;
|
||||
break;
|
||||
case IncludeModuleCallback:
|
||||
ok(output->ModuleWriteFlags == cb->module_flags, "Unexpected module flags %lx\n", output->ModuleWriteFlags);
|
||||
cb->num_include_modules++;
|
||||
break;
|
||||
case ThreadCallback:
|
||||
case ThreadExCallback:
|
||||
ok(output->ThreadWriteFlags == cb->thread_flags, "Unexpected thread flags %lx\n", output->ThreadWriteFlags);
|
||||
cb->num_threads++;
|
||||
break;
|
||||
case IncludeThreadCallback:
|
||||
ok(output->ThreadWriteFlags == cb->thread_flags, "Unexpected thread flags %lx\n", output->ThreadWriteFlags);
|
||||
cb->num_include_threads++;
|
||||
break;
|
||||
case MemoryCallback:
|
||||
case RemoveMemoryCallback:
|
||||
ok(output->MemoryBase == 0, "Unexpected memory info\n");
|
||||
ok(output->MemorySize == 0, "Unexpected memory info\n");
|
||||
break;
|
||||
case CancelCallback:
|
||||
ok(!output->Cancel, "Unexpected value\n");
|
||||
ok(!output->CheckCancel, "Unexpected value\n");
|
||||
break;
|
||||
case WriteKernelMinidumpCallback:
|
||||
ok(output->Handle == NULL, "Unexpected value\n");
|
||||
break;
|
||||
/* case KernelMinidumpStatusCallback: */
|
||||
/* case IncludeVmRegionCallback: */
|
||||
case IoStartCallback:
|
||||
ok(output->Status == E_NOTIMPL, "Unexpected value %lx\n", output->Status);
|
||||
/* TODO check the output->Vm* fields */
|
||||
break;
|
||||
/* case IoWriteAllCallback:
|
||||
* case IoFinishCallback:
|
||||
*/
|
||||
case ReadMemoryFailureCallback:
|
||||
/* TODO check the rest */
|
||||
break;
|
||||
case SecondaryFlagsCallback:
|
||||
ok(input->SecondaryFlags == 0x00, "Unexpected value %lx\n", input->SecondaryFlags);
|
||||
ok(input->SecondaryFlags == output->SecondaryFlags, "Unexpected value %lx\n", output->SecondaryFlags);
|
||||
break;
|
||||
case IsProcessSnapshotCallback:
|
||||
break;
|
||||
case VmStartCallback:
|
||||
break;
|
||||
/*
|
||||
case VmQueryCallback:
|
||||
case VmPreReadCallback:
|
||||
case VmPostReadCallback:
|
||||
*/
|
||||
default:
|
||||
ok(0, "Unexpected callback type %lu\n", input->CallbackType);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_callback(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
MINIDUMP_TYPE dump_type;
|
||||
unsigned module_flags;
|
||||
unsigned thread_flags;
|
||||
}
|
||||
callback_tests[] =
|
||||
{
|
||||
{
|
||||
MiniDumpNormal /* = 0 */,
|
||||
ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord,
|
||||
ThreadWriteThread | ThreadWriteStack | ThreadWriteContext | ThreadWriteInstructionWindow,
|
||||
},
|
||||
{
|
||||
MiniDumpWithCodeSegs,
|
||||
ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord | ModuleWriteCodeSegs,
|
||||
ThreadWriteThread | ThreadWriteStack | ThreadWriteContext | ThreadWriteInstructionWindow,
|
||||
},
|
||||
{
|
||||
MiniDumpWithDataSegs,
|
||||
ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord | ModuleWriteDataSeg,
|
||||
ThreadWriteThread | ThreadWriteStack | ThreadWriteContext | ThreadWriteInstructionWindow,
|
||||
},
|
||||
{
|
||||
MiniDumpWithThreadInfo,
|
||||
ModuleWriteModule | ModuleWriteMiscRecord | ModuleWriteCvRecord,
|
||||
ThreadWriteThread | ThreadWriteStack | ThreadWriteContext | ThreadWriteInstructionWindow | ThreadWriteThreadInfo,
|
||||
},
|
||||
};
|
||||
#define X(a) ((stream_mask_t)1u << (a))
|
||||
static const stream_mask_t mask_types =
|
||||
X(ModuleCallback) | X(ThreadCallback) | /* ThreadExCallback */ X(IncludeThreadCallback) |
|
||||
X(IncludeModuleCallback) | X(MemoryCallback) | X(CancelCallback) | X(WriteKernelMinidumpCallback) |
|
||||
/* KernelMinidumpStatusCallback) */ X(RemoveMemoryCallback) | /* IncludeVmRegionCallback */ X(IoStartCallback) |
|
||||
/* IoWriteAllCallback IoFinishCallback ReadMemoryFailureCallback */ X(SecondaryFlagsCallback) |
|
||||
X(IsProcessSnapshotCallback) | X(VmStartCallback) /* VmQueryCallback VmPreReadCallback */
|
||||
/* VmPostReadCallback */;
|
||||
static const stream_mask_t mask_types_too_old_dbghelp = X(IsProcessSnapshotCallback) | X(VmStartCallback);
|
||||
#undef X
|
||||
struct cb_info cb_info;
|
||||
MINIDUMP_CALLBACK_INFORMATION cbi = {.CallbackRoutine = test_callback_cb, .CallbackParam = &cb_info};
|
||||
BOOL ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(callback_tests); i++)
|
||||
{
|
||||
winetest_push_context("callback_tests[%d]", i);
|
||||
|
||||
memset(&cb_info, 0, sizeof(cb_info));
|
||||
cb_info.module_flags = callback_tests[i].module_flags;
|
||||
cb_info.thread_flags = callback_tests[i].thread_flags;
|
||||
minidump_write(GetCurrentProcess(), L"foo.mdmp", callback_tests[i].dump_type, FALSE, NULL, &cbi);
|
||||
|
||||
todo_wine
|
||||
ok(cb_info.mask_types == mask_types ||
|
||||
broken(cb_info.mask_types == (mask_types & ~mask_types_too_old_dbghelp)),
|
||||
"Unexpected mask for callback types %I64x (%I64x)\n", cb_info.mask_types, mask_types);
|
||||
ok(cb_info.num_modules > 5, "Unexpected number of modules\n");
|
||||
/* native reports several threads... */
|
||||
ok(cb_info.num_threads >= 1, "Unexpected number of threads\n");
|
||||
todo_wine
|
||||
ok(cb_info.num_modules == cb_info.num_include_modules, "Unexpected number of include modules\n");
|
||||
todo_wine
|
||||
ok(cb_info.num_threads == cb_info.num_include_threads, "Unexpected number of include threads\n");
|
||||
|
||||
ret = DeleteFileA("foo.mdmp");
|
||||
ok(ret, "Couldn't delete file\n");
|
||||
winetest_pop_context();
|
||||
}
|
||||
}
|
||||
|
||||
static void test_exception(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
unsigned exception_code;
|
||||
unsigned exception_flags;
|
||||
unsigned num_args;
|
||||
BOOL with_child;
|
||||
}
|
||||
exception_tests[] =
|
||||
{
|
||||
{ 0x1234, 0, 0, FALSE },
|
||||
{ 0x1234, 0, 0, TRUE },
|
||||
{ 0x1234, 0, 5, FALSE },
|
||||
{ 0x1234, 0, 5, TRUE },
|
||||
{ EXCEPTION_BREAKPOINT, 0, 1, TRUE },
|
||||
{ EXCEPTION_ACCESS_VIOLATION, 0, 2, TRUE },
|
||||
};
|
||||
ULONG_PTR args[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
MINIDUMP_EXCEPTION_STREAM *except_info;
|
||||
ULONG size;
|
||||
void *data;
|
||||
BOOL ret;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(args); i++) args[i] = 0x666000 + i;
|
||||
for (i = 0; i < ARRAY_SIZE(exception_tests); i++)
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
MINIDUMP_EXCEPTION_INFORMATION mei;
|
||||
EXCEPTION_POINTERS ep;
|
||||
DEBUG_EVENT ev;
|
||||
/* for local access */
|
||||
EXCEPTION_RECORD er;
|
||||
CONTEXT ctx;
|
||||
CONTEXT *mctx;
|
||||
|
||||
winetest_push_context("test_exceptions[%d]", i);
|
||||
|
||||
if (exception_tests[i].with_child)
|
||||
{
|
||||
BOOL first_exception = TRUE;
|
||||
STARTUPINFOA si;
|
||||
char buffer[MAX_PATH];
|
||||
char **argv;
|
||||
|
||||
winetest_get_mainargs(&argv);
|
||||
snprintf(buffer, ARRAY_SIZE(buffer), "%s minidump exception %x;%x;%u",
|
||||
argv[0], exception_tests[i].exception_code, exception_tests[i].exception_flags,
|
||||
exception_tests[i].num_args);
|
||||
memset(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
|
||||
ok(ret, "CreateProcess failed, last error %#lx.\n", GetLastError());
|
||||
|
||||
while ((ret = WaitForDebugEvent(&ev, 2000)))
|
||||
{
|
||||
if (!first_exception && ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) break;
|
||||
if (first_exception && ev.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
|
||||
ev.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
first_exception = FALSE;
|
||||
ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
|
||||
};
|
||||
ok(ret, "Couldn't get debug event\n");
|
||||
ok(ev.dwThreadId == pi.dwThreadId, "Unexpected value\n");
|
||||
mei.ThreadId = ev.dwThreadId;
|
||||
mei.ExceptionPointers = &ep;
|
||||
mei.ClientPointers = FALSE;
|
||||
ep.ExceptionRecord = &ev.u.Exception.ExceptionRecord;
|
||||
ep.ContextRecord = &ctx;
|
||||
ctx.ContextFlags = CONTEXT_FULL;
|
||||
ret = GetThreadContext(pi.hThread, &ctx);
|
||||
ok(ret, "Couldn't get thread context\n");
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
mei.ThreadId = GetCurrentThreadId();
|
||||
mei.ExceptionPointers = &ep;
|
||||
mei.ClientPointers = FALSE;
|
||||
ep.ExceptionRecord = &er;
|
||||
ep.ContextRecord = &ctx;
|
||||
memset(&ctx, 0xA5, sizeof(ctx));
|
||||
ctx.ContextFlags = CONTEXT_FULL;
|
||||
er.ExceptionCode = exception_tests[i].exception_code;
|
||||
er.ExceptionFlags = exception_tests[i].exception_flags;
|
||||
er.ExceptionAddress = (void *)(DWORD_PTR)0xdeadbeef;
|
||||
er.NumberParameters = exception_tests[i].num_args;
|
||||
for (j = 0; j < exception_tests[i].num_args; j++)
|
||||
er.ExceptionInformation[j] = args[j];
|
||||
pi.hProcess = GetCurrentProcess();
|
||||
}
|
||||
minidump_write(pi.hProcess, L"foo.mdmp", MiniDumpNormal, FALSE, &mei, NULL);
|
||||
|
||||
data = minidump_open_for_read("foo.mdmp");
|
||||
ret = MiniDumpReadDumpStream(data, ExceptionStream, NULL, (void *)&except_info, &size);
|
||||
ok(ret, "Couldn't find exception stream\n");
|
||||
ok(except_info->ThreadId == mei.ThreadId, "Unexpected value\n");
|
||||
ok(except_info->ExceptionRecord.ExceptionCode == exception_tests[i].exception_code, "Unexpected value %x %x\n", except_info->ExceptionRecord.ExceptionCode, exception_tests[i].exception_code);
|
||||
/* windows 11 starts adding EXCEPTION_SOFTWARE_ORIGINATE flag */
|
||||
ok((except_info->ExceptionRecord.ExceptionFlags & ~EXCEPTION_SOFTWARE_ORIGINATE) == exception_tests[i].exception_flags, "Unexpected value\n");
|
||||
/* yes native does a signed conversion to DWORD64 when running on 32bit... */
|
||||
ok(except_info->ExceptionRecord.ExceptionAddress == (DWORD_PTR)ep.ExceptionRecord->ExceptionAddress
|
||||
|| broken(except_info->ExceptionRecord.ExceptionAddress == (LONG_PTR)ep.ExceptionRecord->ExceptionAddress), "Unexpected value\n");
|
||||
if (except_info->ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
|
||||
{
|
||||
/* number of parameters depend on machine, wow64... */
|
||||
ok(except_info->ExceptionRecord.NumberParameters, "Unexpected value %x\n", except_info->ExceptionRecord.NumberParameters);
|
||||
}
|
||||
else if (except_info->ExceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
ok(except_info->ExceptionRecord.NumberParameters == exception_tests[i].num_args, "Unexpected value\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(except_info->ExceptionRecord.NumberParameters == exception_tests[i].num_args, "Unexpected value\n");
|
||||
for (j = 0; j < exception_tests[i].num_args; j++)
|
||||
ok(except_info->ExceptionRecord.ExceptionInformation[j] == args[j], "Unexpected value\n");
|
||||
}
|
||||
ok(except_info->ThreadContext.Rva, "Unexpected value\n");
|
||||
mctx = RVA_TO_ADDR(data, except_info->ThreadContext.Rva);
|
||||
ok(!memcmp(mctx, &ctx, sizeof(ctx)), "Unexpected value\n");
|
||||
minidump_check_threads(data);
|
||||
minidump_close_for_read(data);
|
||||
DeleteFileA("foo.mdmp");
|
||||
winetest_pop_context();
|
||||
if (exception_tests[i].with_child)
|
||||
{
|
||||
TerminateProcess(pi.hProcess, 0);
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_child_exception(const char *arg)
|
||||
{
|
||||
DWORD code, flags;
|
||||
unsigned num_args;
|
||||
|
||||
if (sscanf(arg, "%lx;%lx;%u", &code, &flags, &num_args) == 3)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
DbgBreakPoint();
|
||||
break;
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
{
|
||||
/* volatile to silence gcc warning */
|
||||
char * volatile crashme = (char *)(DWORD_PTR)0x12;
|
||||
*crashme = 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
DWORD_PTR my_args[EXCEPTION_MAXIMUM_PARAMETERS];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(my_args); i++)
|
||||
my_args[i] = 0x666000 + i;
|
||||
RaiseException(code, flags, num_args, my_args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(minidump)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
argc = winetest_get_mainargs(&argv);
|
||||
if (argc == 4 && !strcmp(argv[2], "exception"))
|
||||
{
|
||||
generate_child_exception(argv[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
test_minidump_contents();
|
||||
test_current_process();
|
||||
test_callback();
|
||||
test_exception();
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -420,6 +420,7 @@ static void ddraw_destroy_swapchain(struct ddraw *ddraw)
|
|||
*****************************************************************************/
|
||||
static void ddraw_destroy(struct ddraw *This)
|
||||
{
|
||||
struct d3d_device *device;
|
||||
IDirectDraw7_SetCooperativeLevel(&This->IDirectDraw7_iface, NULL, DDSCL_NORMAL);
|
||||
IDirectDraw7_RestoreDisplayMode(&This->IDirectDraw7_iface);
|
||||
|
||||
|
@ -437,12 +438,13 @@ static void ddraw_destroy(struct ddraw *This)
|
|||
|
||||
if (This->wined3d_swapchain)
|
||||
ddraw_destroy_swapchain(This);
|
||||
wined3d_stateblock_decref(This->state);
|
||||
wined3d_device_decref(This->wined3d_device);
|
||||
wined3d_decref(This->wined3d);
|
||||
|
||||
if (This->d3ddevice)
|
||||
This->d3ddevice->ddraw = NULL;
|
||||
LIST_FOR_EACH_ENTRY(device, &This->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
device->ddraw = NULL;
|
||||
}
|
||||
|
||||
/* Now free the object */
|
||||
free(This);
|
||||
|
@ -794,9 +796,8 @@ static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface)
|
|||
static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
|
||||
DWORD cooplevel, BOOL restore_mode_on_normal)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv = NULL, *dsv = NULL;
|
||||
struct wined3d_stateblock *stateblock;
|
||||
BOOL restore_state = FALSE;
|
||||
struct d3d_device *device;
|
||||
RECT clip_rect;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -930,22 +931,24 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
|
|||
{
|
||||
restore_state = TRUE;
|
||||
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
|
||||
ddraw->state, WINED3D_SBT_ALL, &stateblock)))
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
ERR("Failed to create stateblock, hr %#lx.\n", hr);
|
||||
goto done;
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device,
|
||||
device->state, WINED3D_SBT_ALL, &device->saved_state)))
|
||||
{
|
||||
struct list *entry;
|
||||
|
||||
ERR("Failed to create stateblock, hr %#lx.\n", hr);
|
||||
entry = &device->ddraw_entry;
|
||||
while ((entry = list_prev(&ddraw->d3ddevice_list, entry)))
|
||||
{
|
||||
device = LIST_ENTRY(entry, struct d3d_device, ddraw_entry);
|
||||
wined3d_stateblock_decref(device->saved_state);
|
||||
device->saved_state = NULL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
rtv = wined3d_device_context_get_rendertarget_view(ddraw->immediate_context, 0);
|
||||
/* Rendering to the wined3d frontbuffer. */
|
||||
if (rtv && !wined3d_rendertarget_view_get_sub_resource_parent(rtv))
|
||||
rtv = NULL;
|
||||
else if (rtv)
|
||||
wined3d_rendertarget_view_incref(rtv);
|
||||
|
||||
if ((dsv = wined3d_device_context_get_depth_stencil_view(ddraw->immediate_context)))
|
||||
wined3d_rendertarget_view_incref(dsv);
|
||||
}
|
||||
|
||||
ddraw_destroy_swapchain(ddraw);
|
||||
|
@ -956,20 +959,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
|
|||
|
||||
if (restore_state)
|
||||
{
|
||||
if (dsv)
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
wined3d_device_context_set_depth_stencil_view(ddraw->immediate_context, dsv);
|
||||
wined3d_rendertarget_view_decref(dsv);
|
||||
wined3d_stateblock_apply(device->saved_state, device->state);
|
||||
wined3d_stateblock_decref(device->saved_state);
|
||||
device->saved_state = NULL;
|
||||
}
|
||||
|
||||
if (rtv)
|
||||
{
|
||||
wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &rtv, FALSE);
|
||||
wined3d_rendertarget_view_decref(rtv);
|
||||
}
|
||||
|
||||
wined3d_stateblock_apply(stateblock, ddraw->state);
|
||||
wined3d_stateblock_decref(stateblock);
|
||||
}
|
||||
|
||||
if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE))
|
||||
|
@ -3868,7 +3863,10 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA
|
|||
* never have POW2 unset in d3d7 on windows. */
|
||||
if (ddraw->d3dversion != 1)
|
||||
{
|
||||
static CHAR reference_description[] = "RGB Direct3D emulation";
|
||||
/* Tomb Raider 3 overwrites the reference device description buffer
|
||||
* with its own custom string. Reserve some extra space in the array
|
||||
* to avoid a buffer overrun. */
|
||||
static CHAR reference_description[64] = "RGB Direct3D emulation";
|
||||
|
||||
TRACE("Enumerating WineD3D D3DDevice interface.\n");
|
||||
hal_desc = device_desc1;
|
||||
|
@ -5124,15 +5122,6 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
|
|||
ddraw->immediate_context = wined3d_device_get_immediate_context(ddraw->wined3d_device);
|
||||
|
||||
list_init(&ddraw->surface_list);
|
||||
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, NULL, WINED3D_SBT_PRIMARY, &ddraw->state)))
|
||||
{
|
||||
ERR("Failed to create the primary stateblock, hr %#lx.\n", hr);
|
||||
wined3d_device_decref(ddraw->wined3d_device);
|
||||
wined3d_decref(ddraw->wined3d);
|
||||
return hr;
|
||||
}
|
||||
ddraw->stateblock_state = wined3d_stateblock_get_state(ddraw->state);
|
||||
|
||||
list_init(&ddraw->d3ddevice_list);
|
||||
return DD_OK;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ struct ddraw
|
|||
|
||||
/* D3D things */
|
||||
HWND d3d_window;
|
||||
struct d3d_device *d3ddevice;
|
||||
struct list d3ddevice_list;
|
||||
int d3dversion;
|
||||
|
||||
/* Various HWNDs */
|
||||
|
@ -132,9 +132,6 @@ struct ddraw
|
|||
struct FvfToDecl *decls;
|
||||
UINT numConvertedDecls, declArraySize;
|
||||
|
||||
struct wined3d_stateblock *state;
|
||||
const struct wined3d_stateblock_state *stateblock_state;
|
||||
|
||||
unsigned int frames;
|
||||
DWORD prev_frame_time;
|
||||
};
|
||||
|
@ -329,7 +326,9 @@ struct d3d_device
|
|||
struct wined3d_device *wined3d_device;
|
||||
struct wined3d_device_context *immediate_context;
|
||||
struct ddraw *ddraw;
|
||||
struct list ddraw_entry;
|
||||
IUnknown *rt_iface;
|
||||
struct ddraw_surface *target, *target_ds;
|
||||
|
||||
struct wined3d_streaming_buffer vertex_buffer, index_buffer;
|
||||
|
||||
|
@ -364,6 +363,9 @@ struct d3d_device
|
|||
|
||||
struct wined3d_stateblock *recording, *state, *update_state;
|
||||
const struct wined3d_stateblock_state *stateblock_state;
|
||||
|
||||
/* For temporary saving state during reset. */
|
||||
struct wined3d_stateblock *saved_state;
|
||||
};
|
||||
|
||||
HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface,
|
||||
|
|
|
@ -284,10 +284,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
|
|||
|
||||
wined3d_device_context_set_rendertarget_views(This->immediate_context, 0, 1, &null_rtv, FALSE);
|
||||
|
||||
wined3d_stateblock_decref(This->state);
|
||||
if (This->recording)
|
||||
wined3d_stateblock_decref(This->recording);
|
||||
|
||||
/* Release the wined3d device. This won't destroy it. */
|
||||
if (!wined3d_device_decref(This->wined3d_device))
|
||||
ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
|
||||
|
@ -303,22 +299,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
|
|||
case DDRAW_HANDLE_FREE:
|
||||
break;
|
||||
|
||||
case DDRAW_HANDLE_MATERIAL:
|
||||
{
|
||||
struct d3d_material *m = entry->object;
|
||||
FIXME("Material handle %#lx (%p) not unset properly.\n", i + 1, m);
|
||||
m->Handle = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case DDRAW_HANDLE_MATRIX:
|
||||
{
|
||||
/* No FIXME here because this might happen because of sloppy applications. */
|
||||
WARN("Leftover matrix handle %#lx (%p), deleting.\n", i + 1, entry->object);
|
||||
IDirect3DDevice_DeleteMatrix(&This->IDirect3DDevice_iface, i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case DDRAW_HANDLE_STATEBLOCK:
|
||||
{
|
||||
/* No FIXME here because this might happen because of sloppy applications. */
|
||||
|
@ -327,14 +307,6 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
|
|||
break;
|
||||
}
|
||||
|
||||
case DDRAW_HANDLE_SURFACE:
|
||||
{
|
||||
struct ddraw_surface *surf = entry->object;
|
||||
FIXME("Texture handle %#lx (%p) not unset properly.\n", i + 1, surf);
|
||||
surf->Handle = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Handle %#lx (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
|
||||
break;
|
||||
|
@ -349,18 +321,27 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface)
|
|||
IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
|
||||
}
|
||||
|
||||
wined3d_stateblock_decref(This->state);
|
||||
if (This->recording)
|
||||
wined3d_stateblock_decref(This->recording);
|
||||
|
||||
/* Releasing the render target below may release the last reference to the ddraw object. Detach
|
||||
* the device from it before so it doesn't try to save / restore state on the teared down device. */
|
||||
if (This->ddraw)
|
||||
{
|
||||
list_remove(&This->ddraw_entry);
|
||||
This->ddraw = NULL;
|
||||
}
|
||||
|
||||
TRACE("Releasing render target %p.\n", This->rt_iface);
|
||||
rt_iface = This->rt_iface;
|
||||
This->rt_iface = NULL;
|
||||
This->target = NULL;
|
||||
This->target_ds = NULL;
|
||||
if (This->version != 1)
|
||||
IUnknown_Release(rt_iface);
|
||||
TRACE("Render target release done.\n");
|
||||
|
||||
/* Releasing the render target above may have released the last
|
||||
* reference to the ddraw object. */
|
||||
if (This->ddraw)
|
||||
This->ddraw->d3ddevice = NULL;
|
||||
|
||||
/* Now free the structure */
|
||||
free(This);
|
||||
wined3d_mutex_unlock();
|
||||
|
@ -1320,7 +1301,6 @@ static HRESULT WINAPI d3d_device1_EnumTextureFormats(IDirect3DDevice *iface,
|
|||
*****************************************************************************/
|
||||
static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
|
||||
{
|
||||
struct d3d_device *device = impl_from_IDirect3DDevice(iface);
|
||||
D3DMATRIX *matrix;
|
||||
DWORD h;
|
||||
|
||||
|
@ -1337,7 +1317,7 @@ static HRESULT WINAPI d3d_device1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIX
|
|||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
h = ddraw_allocate_handle(&device->handle_table, matrix, DDRAW_HANDLE_MATRIX);
|
||||
h = ddraw_allocate_handle(NULL, matrix, DDRAW_HANDLE_MATRIX);
|
||||
if (h == DDRAW_INVALID_HANDLE)
|
||||
{
|
||||
ERR("Failed to allocate a matrix handle.\n");
|
||||
|
@ -1386,7 +1366,7 @@ static HRESULT WINAPI d3d_device1_SetMatrix(IDirect3DDevice *iface,
|
|||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
m = ddraw_get_object(&device->handle_table, matrix_handle - 1, DDRAW_HANDLE_MATRIX);
|
||||
m = ddraw_get_object(NULL, matrix_handle - 1, DDRAW_HANDLE_MATRIX);
|
||||
if (!m)
|
||||
{
|
||||
WARN("Invalid matrix handle.\n");
|
||||
|
@ -1435,7 +1415,6 @@ static HRESULT WINAPI d3d_device1_SetMatrix(IDirect3DDevice *iface,
|
|||
static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface,
|
||||
D3DMATRIXHANDLE D3DMatHandle, D3DMATRIX *D3DMatrix)
|
||||
{
|
||||
struct d3d_device *device = impl_from_IDirect3DDevice(iface);
|
||||
D3DMATRIX *m;
|
||||
|
||||
TRACE("iface %p, matrix_handle %#lx, matrix %p.\n", iface, D3DMatHandle, D3DMatrix);
|
||||
|
@ -1444,7 +1423,7 @@ static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface,
|
|||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
m = ddraw_get_object(&device->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
|
||||
m = ddraw_get_object(NULL, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
|
||||
if (!m)
|
||||
{
|
||||
WARN("Invalid matrix handle.\n");
|
||||
|
@ -1476,14 +1455,13 @@ static HRESULT WINAPI d3d_device1_GetMatrix(IDirect3DDevice *iface,
|
|||
*****************************************************************************/
|
||||
static HRESULT WINAPI d3d_device1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE D3DMatHandle)
|
||||
{
|
||||
struct d3d_device *device = impl_from_IDirect3DDevice(iface);
|
||||
D3DMATRIX *m;
|
||||
|
||||
TRACE("iface %p, matrix_handle %#lx.\n", iface, D3DMatHandle);
|
||||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
m = ddraw_free_handle(&device->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
|
||||
m = ddraw_free_handle(NULL, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
|
||||
if (!m)
|
||||
{
|
||||
WARN("Invalid matrix handle.\n");
|
||||
|
@ -1868,6 +1846,7 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device,
|
|||
IUnknown_AddRef(rt_iface);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = rt_iface;
|
||||
device->target = target;
|
||||
d3d_device_update_depth_stencil(device);
|
||||
|
||||
return D3D_OK;
|
||||
|
@ -1911,6 +1890,8 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface,
|
|||
IDirectDrawSurface7_AddRef(target);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = (IUnknown *)target;
|
||||
device->target = NULL;
|
||||
device->target_ds = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
return DDERR_INVALIDPIXELFORMAT;
|
||||
}
|
||||
|
@ -1970,6 +1951,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface,
|
|||
IDirectDrawSurface4_AddRef(target);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = (IUnknown *)target;
|
||||
device->target = NULL;
|
||||
device->target_ds = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
return DDERR_INVALIDPIXELFORMAT;
|
||||
}
|
||||
|
@ -1980,6 +1963,8 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface,
|
|||
IDirectDrawSurface4_AddRef(target);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = (IUnknown *)target;
|
||||
device->target = NULL;
|
||||
device->target_ds = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
return D3D_OK;
|
||||
}
|
||||
|
@ -2019,6 +2004,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface,
|
|||
WARN("Surface %p is a depth buffer.\n", target_impl);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = (IUnknown *)target;
|
||||
device->target = NULL;
|
||||
device->target_ds = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
return DDERR_INVALIDPIXELFORMAT;
|
||||
}
|
||||
|
@ -2029,6 +2016,8 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface,
|
|||
IDirectDrawSurface_AddRef(target);
|
||||
IUnknown_Release(device->rt_iface);
|
||||
device->rt_iface = (IUnknown *)target;
|
||||
device->target = NULL;
|
||||
device->target_ds = NULL;
|
||||
wined3d_mutex_unlock();
|
||||
return D3D_OK;
|
||||
}
|
||||
|
@ -2768,7 +2757,7 @@ static HRESULT WINAPI d3d_device3_SetRenderState(IDirect3DDevice3 *iface,
|
|||
break;
|
||||
}
|
||||
|
||||
surf = ddraw_get_object(&device->handle_table, value - 1, DDRAW_HANDLE_SURFACE);
|
||||
surf = ddraw_get_object(NULL, value - 1, DDRAW_HANDLE_SURFACE);
|
||||
if (!surf)
|
||||
{
|
||||
WARN("Invalid texture handle.\n");
|
||||
|
@ -2936,7 +2925,7 @@ static HRESULT WINAPI d3d_device3_SetLightState(IDirect3DDevice3 *iface,
|
|||
{
|
||||
struct d3d_material *m;
|
||||
|
||||
if (!(m = ddraw_get_object(&device->handle_table, value - 1, DDRAW_HANDLE_MATERIAL)))
|
||||
if (!(m = ddraw_get_object(NULL, value - 1, DDRAW_HANDLE_MATERIAL)))
|
||||
{
|
||||
WARN("Invalid material handle.\n");
|
||||
wined3d_mutex_unlock();
|
||||
|
@ -3391,16 +3380,36 @@ static HRESULT WINAPI d3d_device2_MultiplyTransform(IDirect3DDevice2 *iface,
|
|||
*****************************************************************************/
|
||||
static void d3d_device_sync_rendertarget(struct d3d_device *device)
|
||||
{
|
||||
struct wined3d_rendertarget_view *rtv;
|
||||
struct wined3d_rendertarget_view *rtv, *dsv;
|
||||
|
||||
rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL;
|
||||
if (rtv)
|
||||
{
|
||||
if (FAILED(wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, FALSE)))
|
||||
ERR("wined3d_device_context_set_rendertarget_views failed.\n");
|
||||
}
|
||||
else if (!device->target)
|
||||
{
|
||||
/* NULL device->target may appear when the game was setting invalid render target which in some cases
|
||||
* still keeps the invalid render target in the device even while returning an error.
|
||||
*
|
||||
* TODO: make render go nowhere instead of lefover render target (like it seems to work on Windows on HW devices
|
||||
* while may just crash on software devices. */
|
||||
FIXME("Keeping leftover render target.\n");
|
||||
}
|
||||
|
||||
dsv = device->target_ds ? ddraw_surface_get_rendertarget_view(device->target_ds) : NULL;
|
||||
if (FAILED(wined3d_device_context_set_depth_stencil_view(device->immediate_context, dsv)))
|
||||
ERR("wined3d_device_context_set_depth_stencil_view failed.\n");
|
||||
|
||||
if (device->hardware_device)
|
||||
return;
|
||||
|
||||
if ((rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0)))
|
||||
if (rtv)
|
||||
ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
|
||||
|
||||
if ((rtv = wined3d_device_context_get_depth_stencil_view(device->immediate_context)))
|
||||
ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(rtv), DDRAW_SURFACE_RW);
|
||||
if (dsv)
|
||||
ddraw_surface_get_draw_texture(wined3d_rendertarget_view_get_parent(dsv), DDRAW_SURFACE_RW);
|
||||
}
|
||||
|
||||
void d3d_device_sync_surfaces(struct d3d_device *device)
|
||||
|
@ -5195,7 +5204,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
|
|||
return DDERR_INVALIDPARAMS;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
if (!(rtv = wined3d_device_context_get_rendertarget_view(device->immediate_context, 0)))
|
||||
rtv = device->target ? ddraw_surface_get_rendertarget_view(device->target) : NULL;
|
||||
if (!rtv)
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
return DDERR_INVALIDCAPS;
|
||||
|
@ -6780,7 +6790,6 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
|
|||
IDirectDrawSurface7 *depthStencil = NULL;
|
||||
IDirectDrawSurface7 *render_target;
|
||||
static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, {0} };
|
||||
struct ddraw_surface *dsi;
|
||||
|
||||
if (device->rt_iface && SUCCEEDED(IUnknown_QueryInterface(device->rt_iface,
|
||||
&IID_IDirectDrawSurface7, (void **)&render_target)))
|
||||
|
@ -6792,26 +6801,27 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device
|
|||
{
|
||||
TRACE("Setting wined3d depth stencil to NULL\n");
|
||||
wined3d_device_context_set_depth_stencil_view(device->immediate_context, NULL);
|
||||
device->target_ds = NULL;
|
||||
return WINED3D_ZB_FALSE;
|
||||
}
|
||||
|
||||
dsi = impl_from_IDirectDrawSurface7(depthStencil);
|
||||
device->target_ds = impl_from_IDirectDrawSurface7(depthStencil);
|
||||
wined3d_device_context_set_depth_stencil_view(device->immediate_context,
|
||||
ddraw_surface_get_rendertarget_view(dsi));
|
||||
ddraw_surface_get_rendertarget_view(device->target_ds));
|
||||
|
||||
IDirectDrawSurface7_Release(depthStencil);
|
||||
return WINED3D_ZB_TRUE;
|
||||
}
|
||||
|
||||
static void ddraw_reset_viewport_state(struct ddraw *ddraw)
|
||||
static void device_reset_viewport_state(struct d3d_device *device)
|
||||
{
|
||||
struct wined3d_viewport vp;
|
||||
RECT rect;
|
||||
|
||||
wined3d_device_context_get_viewports(ddraw->immediate_context, NULL, &vp);
|
||||
wined3d_stateblock_set_viewport(ddraw->state, &vp);
|
||||
wined3d_device_context_get_scissor_rects(ddraw->immediate_context, NULL, &rect);
|
||||
wined3d_stateblock_set_scissor_rect(ddraw->state, &rect);
|
||||
wined3d_device_context_get_viewports(device->immediate_context, NULL, &vp);
|
||||
wined3d_stateblock_set_viewport(device->state, &vp);
|
||||
wined3d_device_context_get_scissor_rects(device->immediate_context, NULL, &rect);
|
||||
wined3d_stateblock_set_scissor_rect(device->state, &rect);
|
||||
}
|
||||
|
||||
static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, const GUID *guid,
|
||||
|
@ -6865,13 +6875,19 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
|
|||
device->legacy_projection = ident;
|
||||
device->legacy_clipspace = ident;
|
||||
|
||||
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, NULL, WINED3D_SBT_PRIMARY, &device->state)))
|
||||
{
|
||||
ERR("Failed to create the primary stateblock, hr %#lx.\n", hr);
|
||||
ddraw_handle_table_destroy(&device->handle_table);
|
||||
return hr;
|
||||
}
|
||||
device->stateblock_state = wined3d_stateblock_get_state(device->state);
|
||||
device->update_state = device->state;
|
||||
|
||||
/* This is for convenience. */
|
||||
device->wined3d_device = ddraw->wined3d_device;
|
||||
device->immediate_context = ddraw->immediate_context;
|
||||
wined3d_device_incref(ddraw->wined3d_device);
|
||||
device->update_state = device->state = ddraw->state;
|
||||
device->stateblock_state = ddraw->stateblock_state;
|
||||
wined3d_stateblock_incref(ddraw->state);
|
||||
|
||||
wined3d_streaming_buffer_init(&device->vertex_buffer, WINED3D_BIND_VERTEX_BUFFER);
|
||||
wined3d_streaming_buffer_init(&device->index_buffer, WINED3D_BIND_INDEX_BUFFER);
|
||||
|
@ -6887,24 +6903,25 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c
|
|||
}
|
||||
|
||||
device->rt_iface = rt_iface;
|
||||
device->target = target;
|
||||
if (version != 1)
|
||||
IUnknown_AddRef(device->rt_iface);
|
||||
|
||||
ddraw->d3ddevice = device;
|
||||
list_add_head(&ddraw->d3ddevice_list, &device->ddraw_entry);
|
||||
|
||||
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_ZENABLE,
|
||||
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
|
||||
d3d_device_update_depth_stencil(device));
|
||||
if (version == 1) /* Color keying is initially enabled for version 1 devices. */
|
||||
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_COLORKEYENABLE, TRUE);
|
||||
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_COLORKEYENABLE, TRUE);
|
||||
else if (version == 2)
|
||||
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_SPECULARENABLE, TRUE);
|
||||
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_SPECULARENABLE, TRUE);
|
||||
if (version < 7)
|
||||
{
|
||||
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_NORMALIZENORMALS, TRUE);
|
||||
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_NORMALIZENORMALS, TRUE);
|
||||
IDirect3DDevice3_SetRenderState(&device->IDirect3DDevice3_iface,
|
||||
D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE);
|
||||
}
|
||||
ddraw_reset_viewport_state(ddraw);
|
||||
device_reset_viewport_state(device);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
|
@ -6938,12 +6955,6 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su
|
|||
return DDERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (ddraw->d3ddevice)
|
||||
{
|
||||
FIXME("Only one Direct3D device per DirectDraw object supported.\n");
|
||||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
if (!(object = calloc(1, sizeof(*object))))
|
||||
{
|
||||
ERR("Failed to allocate device memory.\n");
|
||||
|
|
|
@ -209,9 +209,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
|
|||
D3DMATRIXMULTIPLY *ci = (D3DMATRIXMULTIPLY *)instr;
|
||||
struct wined3d_matrix *a, *b, *c;
|
||||
|
||||
a = ddraw_get_object(&device->handle_table, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX);
|
||||
b = ddraw_get_object(&device->handle_table, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX);
|
||||
c = ddraw_get_object(&device->handle_table, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX);
|
||||
a = ddraw_get_object(NULL, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX);
|
||||
b = ddraw_get_object(NULL, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX);
|
||||
c = ddraw_get_object(NULL, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX);
|
||||
|
||||
if (!a || !b || !c)
|
||||
{
|
||||
|
@ -235,7 +235,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
|
|||
D3DSTATE *ci = (D3DSTATE *)instr;
|
||||
D3DMATRIX *m;
|
||||
|
||||
m = ddraw_get_object(&device->handle_table, ci->dwArg[0] - 1, DDRAW_HANDLE_MATRIX);
|
||||
m = ddraw_get_object(NULL, ci->dwArg[0] - 1, DDRAW_HANDLE_MATRIX);
|
||||
if (!m)
|
||||
{
|
||||
ERR("Invalid matrix handle %#lx.\n", ci->dwArg[0]);
|
||||
|
@ -347,14 +347,12 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d
|
|||
|
||||
instr += size;
|
||||
|
||||
if (!(dst = ddraw_get_object(&device->handle_table,
|
||||
ci->hDestTexture - 1, DDRAW_HANDLE_SURFACE)))
|
||||
if (!(dst = ddraw_get_object(NULL, ci->hDestTexture - 1, DDRAW_HANDLE_SURFACE)))
|
||||
{
|
||||
WARN("Invalid destination texture handle %#lx.\n", ci->hDestTexture);
|
||||
continue;
|
||||
}
|
||||
if (!(src = ddraw_get_object(&device->handle_table,
|
||||
ci->hSrcTexture - 1, DDRAW_HANDLE_SURFACE)))
|
||||
if (!(src = ddraw_get_object(NULL, ci->hSrcTexture - 1, DDRAW_HANDLE_SURFACE)))
|
||||
{
|
||||
WARN("Invalid source texture handle %#lx.\n", ci->hSrcTexture);
|
||||
continue;
|
||||
|
|
|
@ -37,6 +37,8 @@ static HINSTANCE instance;
|
|||
/* value of ForceRefreshRate */
|
||||
DWORD force_refresh_rate = 0;
|
||||
|
||||
static struct ddraw_handle_table global_handle_table;
|
||||
|
||||
/* Structure for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
|
||||
struct callback_info
|
||||
{
|
||||
|
@ -137,6 +139,9 @@ DWORD ddraw_allocate_handle(struct ddraw_handle_table *t, void *object, enum ddr
|
|||
{
|
||||
struct ddraw_handle_entry *entry;
|
||||
|
||||
if (!t)
|
||||
t = &global_handle_table;
|
||||
|
||||
if (t->free_entries)
|
||||
{
|
||||
DWORD idx = t->free_entries - t->entries;
|
||||
|
@ -181,6 +186,9 @@ void *ddraw_free_handle(struct ddraw_handle_table *t, DWORD handle, enum ddraw_h
|
|||
struct ddraw_handle_entry *entry;
|
||||
void *object;
|
||||
|
||||
if (!t)
|
||||
t = &global_handle_table;
|
||||
|
||||
if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count)
|
||||
{
|
||||
WARN("Invalid handle %#lx passed.\n", handle);
|
||||
|
@ -206,6 +214,9 @@ void *ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_ha
|
|||
{
|
||||
struct ddraw_handle_entry *entry;
|
||||
|
||||
if (!t)
|
||||
t = &global_handle_table;
|
||||
|
||||
if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count)
|
||||
{
|
||||
WARN("Invalid handle %#lx passed.\n", handle);
|
||||
|
@ -815,6 +826,12 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ddraw_handle_table_init(&global_handle_table, 64))
|
||||
{
|
||||
UnregisterClassA(DDRAW_WINDOW_CLASS_NAME, inst);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* On Windows one can force the refresh rate that DirectDraw uses by
|
||||
* setting an override value in dxdiag. This is documented in KB315614
|
||||
* (main article), KB230002, and KB217348. By comparing registry dumps
|
||||
|
@ -866,6 +883,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
|||
if (WARN_ON(ddraw))
|
||||
{
|
||||
struct ddraw *ddraw;
|
||||
unsigned int i;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ddraw, &global_ddraw_list, struct ddraw, ddraw_list_entry)
|
||||
{
|
||||
|
@ -874,8 +892,8 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
|||
WARN("DirectDraw object %p has reference counts {%lu, %lu, %lu, %lu, %lu}.\n",
|
||||
ddraw, ddraw->ref7, ddraw->ref4, ddraw->ref3, ddraw->ref2, ddraw->ref1);
|
||||
|
||||
if (ddraw->d3ddevice)
|
||||
WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice);
|
||||
if (!list_empty(&ddraw->d3ddevice_list))
|
||||
WARN("DirectDraw object %p has Direct3D device(s) attached.\n", ddraw);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(surface, &ddraw->surface_list, struct ddraw_surface, surface_list_entry)
|
||||
{
|
||||
|
@ -884,6 +902,34 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
|
|||
surface->ref2, surface->ref1, surface->gamma_count);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < global_handle_table.entry_count; ++i)
|
||||
{
|
||||
struct ddraw_handle_entry *entry = &global_handle_table.entries[i];
|
||||
|
||||
switch (entry->type)
|
||||
{
|
||||
case DDRAW_HANDLE_FREE:
|
||||
break;
|
||||
|
||||
case DDRAW_HANDLE_MATERIAL:
|
||||
WARN("Material handle %#x (%p) not unset properly.\n", i + 1, entry->object);
|
||||
break;
|
||||
|
||||
case DDRAW_HANDLE_SURFACE:
|
||||
WARN("Texture handle %#x (%p) not unset properly.\n", i + 1, entry->object);
|
||||
break;
|
||||
|
||||
case DDRAW_HANDLE_MATRIX:
|
||||
WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ddraw_handle_table_destroy(&global_handle_table);
|
||||
}
|
||||
|
||||
if (reserved) break;
|
||||
|
|
|
@ -143,7 +143,7 @@ static ULONG WINAPI d3d_material3_Release(IDirect3DMaterial3 *iface)
|
|||
if (material->Handle)
|
||||
{
|
||||
wined3d_mutex_lock();
|
||||
ddraw_free_handle(&material->ddraw->d3ddevice->handle_table, material->Handle - 1, DDRAW_HANDLE_MATERIAL);
|
||||
ddraw_free_handle(NULL, material->Handle - 1, DDRAW_HANDLE_MATERIAL);
|
||||
wined3d_mutex_unlock();
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ static HRESULT WINAPI d3d_material3_GetHandle(IDirect3DMaterial3 *iface,
|
|||
material->active_device = device_impl;
|
||||
if (!material->Handle)
|
||||
{
|
||||
DWORD h = ddraw_allocate_handle(&device_impl->handle_table, material, DDRAW_HANDLE_MATERIAL);
|
||||
DWORD h = ddraw_allocate_handle(NULL, material, DDRAW_HANDLE_MATERIAL);
|
||||
if (h == DDRAW_INVALID_HANDLE)
|
||||
{
|
||||
ERR("Failed to allocate a material handle.\n");
|
||||
|
|
|
@ -1563,7 +1563,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *
|
|||
const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
|
||||
{
|
||||
struct ddraw *ddraw = dst_surface->ddraw;
|
||||
struct wined3d_device *wined3d_device = ddraw->wined3d_device;
|
||||
struct wined3d_color colour;
|
||||
DWORD wined3d_flags;
|
||||
HRESULT hr;
|
||||
|
@ -1578,7 +1577,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *
|
|||
dst_surface->palette, fill_colour, &colour))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
|
||||
wined3d_device_apply_stateblock(wined3d_device, ddraw->state);
|
||||
ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE);
|
||||
hr = wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context,
|
||||
ddraw_surface_get_rendertarget_view(dst_surface),
|
||||
|
@ -1597,7 +1595,6 @@ static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *
|
|||
dst_surface->palette, fill_colour, &colour))
|
||||
return DDERR_INVALIDPARAMS;
|
||||
|
||||
wined3d_device_apply_stateblock(wined3d_device, ddraw->state);
|
||||
ddraw_surface_get_draw_texture(dst_surface, dst_rect ? DDRAW_SURFACE_RW : DDRAW_SURFACE_WRITE);
|
||||
return wined3d_device_context_clear_rendertarget_view(ddraw->immediate_context,
|
||||
ddraw_surface_get_rendertarget_view(dst_surface),
|
||||
|
@ -2016,6 +2013,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 *
|
|||
*****************************************************************************/
|
||||
static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct ddraw_surface *Surf)
|
||||
{
|
||||
struct d3d_device *device;
|
||||
|
||||
TRACE("surface %p, attachment %p.\n", This, Surf);
|
||||
|
||||
if(Surf == This)
|
||||
|
@ -2042,8 +2041,10 @@ static HRESULT ddraw_surface_attach_surface(struct ddraw_surface *This, struct d
|
|||
This->next_attached = Surf;
|
||||
|
||||
/* Check if the WineD3D depth stencil needs updating */
|
||||
if (This->ddraw->d3ddevice)
|
||||
d3d_device_update_depth_stencil(This->ddraw->d3ddevice);
|
||||
LIST_FOR_EACH_ENTRY(device, &This->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
d3d_device_update_depth_stencil(device);
|
||||
}
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
|
@ -4349,7 +4350,7 @@ static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *ifa
|
|||
static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD MaxLOD)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
|
||||
HRESULT hr;
|
||||
struct d3d_device *device;
|
||||
|
||||
TRACE("iface %p, lod %lu.\n", iface, MaxLOD);
|
||||
|
||||
|
@ -4360,12 +4361,18 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma
|
|||
return DDERR_INVALIDOBJECT;
|
||||
}
|
||||
|
||||
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->wined3d_texture, MaxLOD);
|
||||
if (SUCCEEDED(hr) && surface->draw_texture)
|
||||
hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->draw_texture, MaxLOD);
|
||||
wined3d_mutex_unlock();
|
||||
wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD);
|
||||
if (surface->draw_texture)
|
||||
wined3d_texture_set_lod(surface->draw_texture, MaxLOD);
|
||||
|
||||
return hr;
|
||||
LIST_FOR_EACH_ENTRY(device, &surface->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
wined3d_stateblock_texture_changed(device->state, surface->wined3d_texture);
|
||||
if (surface->draw_texture)
|
||||
wined3d_stateblock_texture_changed(device->state, surface->draw_texture);
|
||||
}
|
||||
wined3d_mutex_unlock();
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -5441,7 +5448,6 @@ static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface,
|
|||
IDirect3DDevice2 *device, D3DTEXTUREHANDLE *handle)
|
||||
{
|
||||
struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
|
||||
struct d3d_device *device_impl = unsafe_impl_from_IDirect3DDevice2(device);
|
||||
|
||||
TRACE("iface %p, device %p, handle %p.\n", iface, device, handle);
|
||||
|
||||
|
@ -5449,7 +5455,7 @@ static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface,
|
|||
|
||||
if (!surface->Handle)
|
||||
{
|
||||
DWORD h = ddraw_allocate_handle(&device_impl->handle_table, surface, DDRAW_HANDLE_SURFACE);
|
||||
DWORD h = ddraw_allocate_handle(NULL, surface, DDRAW_HANDLE_SURFACE);
|
||||
if (h == DDRAW_INVALID_HANDLE)
|
||||
{
|
||||
ERR("Failed to allocate a texture handle.\n");
|
||||
|
@ -6060,7 +6066,7 @@ static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *paren
|
|||
|
||||
/* Having a texture handle set implies that the device still exists. */
|
||||
if (surface->Handle)
|
||||
ddraw_free_handle(&surface->ddraw->d3ddevice->handle_table, surface->Handle - 1, DDRAW_HANDLE_SURFACE);
|
||||
ddraw_free_handle(NULL, surface->Handle - 1, DDRAW_HANDLE_SURFACE);
|
||||
|
||||
/* Reduce the ddraw surface count. */
|
||||
list_remove(&surface->surface_list_entry);
|
||||
|
@ -6519,15 +6525,17 @@ static HRESULT ddraw_texture_init(struct ddraw_texture *texture, struct ddraw *d
|
|||
|
||||
fail:
|
||||
if (draw_texture)
|
||||
{
|
||||
wined3d_texture_decref(draw_texture);
|
||||
|
||||
parent = wined3d_texture_get_sub_resource_parent(draw_texture, 0);
|
||||
if (texture->version == 7)
|
||||
IDirectDrawSurface7_Release(&parent->IDirectDrawSurface7_iface);
|
||||
else if (texture->version == 4)
|
||||
IDirectDrawSurface4_Release(&parent->IDirectDrawSurface4_iface);
|
||||
else
|
||||
IDirectDrawSurface_Release(&parent->IDirectDrawSurface_iface);
|
||||
parent = wined3d_texture_get_sub_resource_parent(draw_texture, 0);
|
||||
if (texture->version == 7)
|
||||
IDirectDrawSurface7_Release(&parent->IDirectDrawSurface7_iface);
|
||||
else if (texture->version == 4)
|
||||
IDirectDrawSurface4_Release(&parent->IDirectDrawSurface4_iface);
|
||||
else
|
||||
IDirectDrawSurface_Release(&parent->IDirectDrawSurface_iface);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -6763,20 +6771,21 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
if (ddraw->cooperative_level & DDSCL_EXCLUSIVE)
|
||||
{
|
||||
struct wined3d_swapchain_desc swapchain_desc;
|
||||
struct d3d_device *device;
|
||||
|
||||
wined3d_swapchain_get_desc(ddraw->wined3d_swapchain, &swapchain_desc);
|
||||
swapchain_desc.backbuffer_width = mode.width;
|
||||
swapchain_desc.backbuffer_height = mode.height;
|
||||
swapchain_desc.backbuffer_format = mode.format_id;
|
||||
|
||||
if (ddraw->d3ddevice)
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
if (ddraw->d3ddevice->recording)
|
||||
wined3d_stateblock_decref(ddraw->d3ddevice->recording);
|
||||
ddraw->d3ddevice->recording = NULL;
|
||||
ddraw->d3ddevice->update_state = ddraw->d3ddevice->state;
|
||||
if (device->recording)
|
||||
wined3d_stateblock_decref(device->recording);
|
||||
device->recording = NULL;
|
||||
device->update_state = device->state;
|
||||
wined3d_stateblock_reset(device->state);
|
||||
}
|
||||
wined3d_stateblock_reset(ddraw->state);
|
||||
|
||||
if (FAILED(hr = wined3d_device_reset(ddraw->wined3d_device,
|
||||
&swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE)))
|
||||
|
@ -6786,8 +6795,11 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
return hr_ddraw_from_wined3d(hr);
|
||||
}
|
||||
|
||||
wined3d_stateblock_set_render_state(ddraw->state, WINED3D_RS_ZENABLE,
|
||||
!!swapchain_desc.enable_auto_depth_stencil);
|
||||
LIST_FOR_EACH_ENTRY(device, &ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
wined3d_stateblock_set_render_state(device->state, WINED3D_RS_ZENABLE,
|
||||
!!swapchain_desc.enable_auto_depth_stencil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6838,11 +6850,19 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
|
|||
{
|
||||
if (!(desc->ddsCaps.dwCaps2 & (DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_D3DTEXTUREMANAGE)))
|
||||
{
|
||||
unsigned int bind_flags = WINED3D_BIND_SHADER_RESOURCE;
|
||||
unsigned int bind_flags = 0;
|
||||
DWORD usage = 0;
|
||||
|
||||
if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
|
||||
{
|
||||
usage |= WINED3DUSAGE_LEGACY_CUBEMAP;
|
||||
bind_flags |= WINED3D_BIND_SHADER_RESOURCE;
|
||||
}
|
||||
else if (desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
|
||||
{
|
||||
bind_flags |= WINED3D_BIND_SHADER_RESOURCE;
|
||||
}
|
||||
|
||||
if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
|
||||
bind_flags |= WINED3D_BIND_DEPTH_STENCIL;
|
||||
else if (desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE)
|
||||
|
|
|
@ -1523,13 +1523,8 @@ static void BackBuffer3DCreateSurfaceTest(void)
|
|||
"GetSurfaceDesc returned caps %#lx.\n", created_ddsd.ddsCaps.dwCaps);
|
||||
|
||||
hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DHALDevice, (void **)&d3dhal);
|
||||
/* Currently Wine only supports the creation of one Direct3D device
|
||||
for a given DirectDraw instance. It has been created already
|
||||
in D3D1_createObjects() - IID_IDirect3DRGBDevice */
|
||||
todo_wine ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
IDirect3DDevice_Release(d3dhal);
|
||||
ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
|
||||
IDirect3DDevice_Release(d3dhal);
|
||||
|
||||
IDirectDrawSurface_Release(surf);
|
||||
}
|
||||
|
|
|
@ -4563,6 +4563,7 @@ static void test_unsupported_formats(void)
|
|||
|
||||
static void test_rt_caps(const GUID *device_guid)
|
||||
{
|
||||
DWORD fourcc_codes[64], fourcc_code_count;
|
||||
PALETTEENTRY palette_entries[256];
|
||||
IDirectDrawPalette *palette;
|
||||
IDirect3DDevice *device;
|
||||
|
@ -4580,6 +4581,12 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
|
||||
{8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
|
||||
};
|
||||
static const DDPIXELFORMAT fourcc_fmt =
|
||||
{
|
||||
.dwSize = sizeof(DDPIXELFORMAT),
|
||||
.dwFlags = DDPF_FOURCC,
|
||||
.dwFourCC = MAKEFOURCC('Y','U','Y','2'),
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
|
@ -4710,6 +4717,12 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
DDERR_INVALIDCAPS,
|
||||
TRUE /* Nvidia Kepler */,
|
||||
},
|
||||
{
|
||||
&fourcc_fmt,
|
||||
DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_OFFSCREENPLAIN,
|
||||
DDERR_INVALIDCAPS,
|
||||
FALSE,
|
||||
},
|
||||
};
|
||||
|
||||
software_device = is_software_device_type(device_guid);
|
||||
|
@ -4737,6 +4750,10 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
hr = IDirectDraw_GetCaps(ddraw, &hal_caps, NULL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
fourcc_code_count = ARRAY_SIZE(fourcc_codes);
|
||||
hr = IDirectDraw4_GetFourCCCodes(ddraw, &fourcc_code_count, fourcc_codes);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_data); ++i)
|
||||
{
|
||||
DWORD caps_in, expected_caps;
|
||||
|
@ -4753,6 +4770,21 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.ddsCaps.dwCaps = caps_in;
|
||||
if (test_data[i].pf)
|
||||
{
|
||||
if (test_data[i].pf->dwFlags & DDPF_FOURCC)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < fourcc_code_count; ++j)
|
||||
{
|
||||
if (test_data[i].pf->dwFourCC == fourcc_codes[j])
|
||||
break;
|
||||
}
|
||||
if (j == fourcc_code_count)
|
||||
{
|
||||
skip("Fourcc format %#lx is not supported, skipping test.\n", test_data[i].pf->dwFourCC);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
|
@ -4761,6 +4793,11 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.dwFlags |= DDSD_ZBUFFERBITDEPTH;
|
||||
surface_desc.dwZBufferBitDepth = z_depth;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
if ((caps_in & DDSCAPS_VIDEOMEMORY) && !(hal_caps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
||||
|
@ -4784,6 +4821,9 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
else
|
||||
expected_caps = caps_in | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
expected_caps |= DDSCAPS_FRONTBUFFER;
|
||||
|
||||
ok(surface_desc.ddsCaps.dwCaps == expected_caps || (test_data[i].pf == &p8_fmt
|
||||
&& surface_desc.ddsCaps.dwCaps == (caps_in | DDSCAPS_SYSTEMMEMORY))
|
||||
|| (software_device && caps_in & DDSCAPS_ZBUFFER
|
||||
|
@ -15530,6 +15570,109 @@ static void test_pinned_sysmem(void)
|
|||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
static void test_multiple_devices(void)
|
||||
{
|
||||
static D3DMATRIX test_matrix =
|
||||
{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 3.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 4.0f,
|
||||
};
|
||||
|
||||
D3DTEXTUREHANDLE texture_handle, texture_handle2;
|
||||
D3DMATERIALHANDLE mat_handle, mat_handle2;
|
||||
IDirect3DViewport *viewport, *viewport2;
|
||||
IDirect3DDevice *device, *device2;
|
||||
IDirectDrawSurface *texture_surf;
|
||||
D3DMATRIXHANDLE matrix_handle;
|
||||
IDirectDraw *ddraw, *ddraw2;
|
||||
IDirect3DMaterial *material;
|
||||
DDSURFACEDESC surface_desc;
|
||||
IDirect3DTexture *texture;
|
||||
D3DMATRIX matrix;
|
||||
ULONG refcount;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
ddraw2 = create_ddraw();
|
||||
ok(!!ddraw2, "Failed to create a ddraw object.\n");
|
||||
|
||||
device2 = create_device_ex(ddraw2, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice);
|
||||
ok(!!device2, "got NULL.\n");
|
||||
|
||||
viewport = create_viewport(device, 0, 0, 640, 480);
|
||||
viewport2 = create_viewport(device2, 0, 0, 640, 480);
|
||||
|
||||
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(mat_handle == mat_handle2, "got different handles.\n");
|
||||
|
||||
hr = IDirect3DMaterial_GetHandle(material, device2, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
todo_wine ok(mat_handle != mat_handle2, "got same handles.\n");
|
||||
|
||||
hr = IDirect3DViewport_SetBackground(viewport, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DViewport_SetBackground(viewport2, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||
surface_desc.dwSize = sizeof(surface_desc);
|
||||
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
surface_desc.dwWidth = 256;
|
||||
surface_desc.dwHeight = 256;
|
||||
hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DTexture_GetHandle(texture, device, &texture_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DTexture_GetHandle(texture, device2, &texture_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(texture_handle != texture_handle2, "got same handles.\n");
|
||||
|
||||
hr = IDirect3DDevice_CreateMatrix(device, &matrix_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice_SetMatrix(device, matrix_handle, &test_matrix);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
memset(&matrix, 0xcc, sizeof(matrix));
|
||||
hr = IDirect3DDevice_GetMatrix(device2, matrix_handle, &matrix);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(!memcmp(&matrix, &test_matrix, sizeof(matrix)), "matrix does not match.\n");
|
||||
|
||||
IDirect3DTexture_Release(texture);
|
||||
IDirectDrawSurface_Release(texture_surf);
|
||||
IDirect3DMaterial_Release(material);
|
||||
IDirect3DViewport_Release(viewport);
|
||||
IDirect3DViewport_Release(viewport2);
|
||||
|
||||
refcount = IDirect3DDevice_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice_Release(device2);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
|
||||
IDirectDraw_Release(ddraw);
|
||||
IDirectDraw_Release(ddraw2);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(ddraw1)
|
||||
{
|
||||
DDDEVICEIDENTIFIER identifier;
|
||||
|
@ -15650,4 +15793,5 @@ START_TEST(ddraw1)
|
|||
test_filling_convention();
|
||||
test_enum_devices();
|
||||
test_pinned_sysmem();
|
||||
test_multiple_devices();
|
||||
}
|
||||
|
|
|
@ -462,7 +462,8 @@ static IDirectDraw2 *create_ddraw(void)
|
|||
return ddraw2;
|
||||
}
|
||||
|
||||
static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid)
|
||||
static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWORD coop_level, const GUID *device_guid,
|
||||
IDirectDrawSurface **ret_surface)
|
||||
{
|
||||
/* Prefer 16 bit depth buffers because Nvidia gives us an unpadded D24 buffer if we ask
|
||||
* for 24 bit and handles such buffers incorrectly in DDBLT_DEPTHFILL. AMD only supports
|
||||
|
@ -541,13 +542,17 @@ static IDirect3DDevice2 *create_device_ex(IDirectDraw2 *ddraw, HWND window, DWOR
|
|||
}
|
||||
|
||||
IDirect3D2_Release(d3d);
|
||||
IDirectDrawSurface_Release(surface);
|
||||
if (ret_surface)
|
||||
*ret_surface = surface;
|
||||
else
|
||||
IDirectDrawSurface_Release(surface);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static IDirect3DDevice2 *create_device(IDirectDraw2 *ddraw, HWND window, DWORD coop_level)
|
||||
{
|
||||
return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice);
|
||||
return create_device_ex(ddraw, window, coop_level, &IID_IDirect3DHALDevice, NULL);
|
||||
}
|
||||
|
||||
static IDirect3DViewport2 *create_viewport(IDirect3DDevice2 *device, UINT x, UINT y, UINT w, UINT h)
|
||||
|
@ -1330,7 +1335,7 @@ static void test_depth_blit(const GUID *device_guid)
|
|||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
IDirectDraw2_Release(ddraw);
|
||||
|
@ -1856,7 +1861,7 @@ static void test_zenable(const GUID *device_guid)
|
|||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
IDirectDraw2_Release(ddraw);
|
||||
|
@ -1971,7 +1976,7 @@ static void test_ck_rgba(const GUID *device_guid)
|
|||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
IDirectDraw2_Release(ddraw);
|
||||
|
@ -5007,6 +5012,7 @@ static void test_unsupported_formats(void)
|
|||
|
||||
static void test_rt_caps(const GUID *device_guid)
|
||||
{
|
||||
DWORD fourcc_codes[64], fourcc_code_count;
|
||||
PALETTEENTRY palette_entries[256];
|
||||
IDirectDrawPalette *palette;
|
||||
IDirect3DDevice2 *device;
|
||||
|
@ -5025,6 +5031,12 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
|
||||
{8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
|
||||
};
|
||||
static const DDPIXELFORMAT fourcc_fmt =
|
||||
{
|
||||
.dwSize = sizeof(DDPIXELFORMAT),
|
||||
.dwFlags = DDPF_FOURCC,
|
||||
.dwFourCC = MAKEFOURCC('Y','U','Y','2'),
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
|
@ -5197,6 +5209,13 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
DDERR_INVALIDCAPS,
|
||||
TRUE /* Nvidia Kepler */,
|
||||
},
|
||||
{
|
||||
&fourcc_fmt,
|
||||
DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_OFFSCREENPLAIN,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
},
|
||||
};
|
||||
|
||||
software_device = is_software_device_type(device_guid);
|
||||
|
@ -5204,7 +5223,7 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
IDirectDraw2_Release(ddraw);
|
||||
|
@ -5230,6 +5249,10 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
hr = IDirectDraw2_GetCaps(ddraw, &hal_caps, NULL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
fourcc_code_count = ARRAY_SIZE(fourcc_codes);
|
||||
hr = IDirectDraw4_GetFourCCCodes(ddraw, &fourcc_code_count, fourcc_codes);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_data); ++i)
|
||||
{
|
||||
IDirectDrawSurface *surface, *rt, *expected_rt, *tmp;
|
||||
|
@ -5246,6 +5269,21 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.ddsCaps.dwCaps = caps_in;
|
||||
if (test_data[i].pf)
|
||||
{
|
||||
if (test_data[i].pf->dwFlags & DDPF_FOURCC)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < fourcc_code_count; ++j)
|
||||
{
|
||||
if (test_data[i].pf->dwFourCC == fourcc_codes[j])
|
||||
break;
|
||||
}
|
||||
if (j == fourcc_code_count)
|
||||
{
|
||||
skip("Fourcc format %#lx is not supported, skipping test.\n", test_data[i].pf->dwFourCC);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
|
@ -5254,6 +5292,11 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.dwFlags |= DDSD_ZBUFFERBITDEPTH;
|
||||
surface_desc.dwZBufferBitDepth = z_depth;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
if ((caps_in & DDSCAPS_VIDEOMEMORY) && !(hal_caps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
||||
|
@ -5276,6 +5319,9 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
else
|
||||
expected_caps = caps_in | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
expected_caps |= DDSCAPS_FRONTBUFFER;
|
||||
|
||||
ok(surface_desc.ddsCaps.dwCaps == expected_caps || (test_data[i].pf == &p8_fmt
|
||||
&& surface_desc.ddsCaps.dwCaps == (caps_in | DDSCAPS_SYSTEMMEMORY))
|
||||
|| (software_device && caps_in & DDSCAPS_ZBUFFER
|
||||
|
@ -5343,6 +5389,11 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.dwFlags |= DDSD_ZBUFFERBITDEPTH;
|
||||
surface_desc.dwZBufferBitDepth = z_depth;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &rt, NULL);
|
||||
|
@ -15692,7 +15743,7 @@ static void test_texture_wrong_caps(const GUID *device_guid)
|
|||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -16442,6 +16493,144 @@ static void run_for_each_device_type(void (*test_func)(const GUID *))
|
|||
test_func(&IID_IDirect3DRGBDevice);
|
||||
}
|
||||
|
||||
static void test_multiple_devices(void)
|
||||
{
|
||||
D3DTEXTUREHANDLE texture_handle, texture_handle2;
|
||||
IDirect3DDevice2 *device, *device2, *device3;
|
||||
IDirectDrawSurface *surface, *texture_surf;
|
||||
D3DMATERIALHANDLE mat_handle, mat_handle2;
|
||||
IDirect3DViewport2 *viewport, *viewport2;
|
||||
IDirectDraw2 *ddraw, *ddraw2;
|
||||
IDirect3DMaterial2 *material;
|
||||
DDSURFACEDESC surface_desc;
|
||||
IDirect3DTexture2 *texture;
|
||||
IDirect3D2 *d3d;
|
||||
ULONG refcount;
|
||||
DWORD value;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
ddraw = create_ddraw();
|
||||
ok(!!ddraw, "Failed to create a ddraw object.\n");
|
||||
|
||||
if (!(device = create_device_ex(ddraw, window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice2_GetDirect3D(device, &d3d);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3D2_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
ddraw2 = create_ddraw();
|
||||
ok(!!ddraw2, "Failed to create a ddraw object.\n");
|
||||
device3 = create_device(ddraw2, window, DDSCL_NORMAL);
|
||||
ok(!!device3, "got NULL.\n");
|
||||
|
||||
viewport = create_viewport(device, 0, 0, 640, 480);
|
||||
viewport2 = create_viewport(device2, 0, 0, 640, 480);
|
||||
hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport);
|
||||
ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetCurrentViewport(device2, viewport2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(mat_handle == mat_handle2, "got different handles.\n");
|
||||
|
||||
hr = IDirect3DMaterial2_GetHandle(material, device2, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
todo_wine ok(mat_handle != mat_handle2, "got same handles.\n");
|
||||
|
||||
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DViewport2_SetBackground(viewport, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DViewport2_SetBackground(viewport2, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
value = 0xdeadbeef;
|
||||
hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(value == TRUE, "got %#lx.\n", value);
|
||||
hr = IDirect3DDevice2_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!value, "got %#lx.\n", value);
|
||||
hr = IDirect3DDevice2_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!value, "got %#lx.\n", value);
|
||||
|
||||
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||
surface_desc.dwSize = sizeof(surface_desc);
|
||||
surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
||||
surface_desc.dwWidth = 256;
|
||||
surface_desc.dwHeight = 256;
|
||||
hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &texture_surf, NULL);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirectDrawSurface_QueryInterface(texture_surf, &IID_IDirect3DTexture2, (void **)&texture);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DTexture2_GetHandle(texture, device, &texture_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DTexture2_GetHandle(texture, device2, &texture_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(texture_handle == texture_handle2, "got different handles.\n");
|
||||
hr = IDirect3DTexture2_GetHandle(texture, device3, &texture_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(texture_handle == texture_handle2, "got different handles.\n");
|
||||
hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetRenderState(device2, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice2_SetRenderState(device3, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
IDirect3DTexture2_Release(texture);
|
||||
IDirectDrawSurface_Release(texture_surf);
|
||||
IDirect3DMaterial2_Release(material);
|
||||
IDirect3DViewport2_Release(viewport);
|
||||
IDirect3DViewport2_Release(viewport2);
|
||||
|
||||
refcount = IDirect3DDevice2_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice2_Release(device2);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice2_Release(device3);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirectDrawSurface_Release(surface);
|
||||
ok(!refcount, "Surface has %lu references left.\n", refcount);
|
||||
|
||||
IDirectDraw2_Release(ddraw);
|
||||
IDirectDraw_Release(ddraw2);
|
||||
IDirect3D2_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(ddraw2)
|
||||
{
|
||||
DDDEVICEIDENTIFIER identifier;
|
||||
|
@ -16567,4 +16756,5 @@ START_TEST(ddraw2)
|
|||
run_for_each_device_type(test_texture_wrong_caps);
|
||||
test_filling_convention();
|
||||
test_enum_devices();
|
||||
test_multiple_devices();
|
||||
}
|
||||
|
|
|
@ -450,7 +450,8 @@ static IDirectDraw4 *create_ddraw(void)
|
|||
return ddraw4;
|
||||
}
|
||||
|
||||
static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid)
|
||||
static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid,
|
||||
IDirectDrawSurface4 **ret_surface)
|
||||
{
|
||||
IDirectDrawSurface4 *surface, *ds;
|
||||
IDirect3DDevice3 *device = NULL;
|
||||
|
@ -539,16 +540,22 @@ static IDirect3DDevice3 *create_device_ex(HWND window, DWORD coop_level, const G
|
|||
|
||||
hr = IDirect3D3_CreateDevice(d3d3, device_guid, surface, &device, NULL);
|
||||
IDirect3D3_Release(d3d3);
|
||||
IDirectDrawSurface4_Release(surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IDirectDrawSurface4_Release(surface);
|
||||
return NULL;
|
||||
}
|
||||
if (ret_surface)
|
||||
*ret_surface = surface;
|
||||
else
|
||||
IDirectDrawSurface4_Release(surface);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static IDirect3DDevice3 *create_device(HWND window, DWORD coop_level)
|
||||
{
|
||||
return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice);
|
||||
return create_device_ex(window, coop_level, &IID_IDirect3DHALDevice, NULL);
|
||||
}
|
||||
|
||||
static IDirect3DViewport3 *create_viewport(IDirect3DDevice3 *device, UINT x, UINT y, UINT w, UINT h)
|
||||
|
@ -1506,7 +1513,7 @@ static void test_depth_blit(const GUID *device_guid)
|
|||
D3DRECT d3drect;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -2101,7 +2108,7 @@ static void test_zenable(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -2213,7 +2220,7 @@ static void test_ck_rgba(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -6615,6 +6622,7 @@ static void test_unsupported_formats(void)
|
|||
|
||||
static void test_rt_caps(const GUID *device_guid)
|
||||
{
|
||||
DWORD fourcc_codes[64], fourcc_code_count;
|
||||
PALETTEENTRY palette_entries[256];
|
||||
IDirectDrawPalette *palette;
|
||||
BOOL software_device;
|
||||
|
@ -6632,6 +6640,12 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
|
||||
{8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
|
||||
};
|
||||
static const DDPIXELFORMAT fourcc_fmt =
|
||||
{
|
||||
.dwSize = sizeof(DDPIXELFORMAT),
|
||||
.dwFlags = DDPF_FOURCC,
|
||||
.dwFourCC = MAKEFOURCC('Y','U','Y','2'),
|
||||
};
|
||||
|
||||
const struct
|
||||
{
|
||||
|
@ -6819,6 +6833,14 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
},
|
||||
{
|
||||
&fourcc_fmt,
|
||||
DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_OFFSCREENPLAIN,
|
||||
0,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
},
|
||||
};
|
||||
|
||||
software_device = is_software_device_type(device_guid);
|
||||
|
@ -6853,6 +6875,10 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
hr = IDirectDraw4_GetCaps(ddraw, &hal_caps, NULL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
fourcc_code_count = ARRAY_SIZE(fourcc_codes);
|
||||
hr = IDirectDraw4_GetFourCCCodes(ddraw, &fourcc_code_count, fourcc_codes);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_data); ++i)
|
||||
{
|
||||
IDirectDrawSurface4 *surface, *rt, *expected_rt, *tmp;
|
||||
|
@ -6870,9 +6896,29 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.ddsCaps.dwCaps2 = test_data[i].caps2_in;
|
||||
if (test_data[i].pf)
|
||||
{
|
||||
if (test_data[i].pf->dwFlags & DDPF_FOURCC)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < fourcc_code_count; ++j)
|
||||
{
|
||||
if (test_data[i].pf->dwFourCC == fourcc_codes[j])
|
||||
break;
|
||||
}
|
||||
if (j == fourcc_code_count)
|
||||
{
|
||||
skip("Fourcc format %#lx is not supported, skipping test.\n", test_data[i].pf->dwFourCC);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
if ((caps_in & DDSCAPS_VIDEOMEMORY) && !(hal_caps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
||||
|
@ -6898,6 +6944,9 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
else
|
||||
expected_caps = caps_in | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
expected_caps |= DDSCAPS_FRONTBUFFER;
|
||||
|
||||
ok(surface_desc.ddsCaps.dwCaps == expected_caps || (test_data[i].pf == &p8_fmt
|
||||
&& surface_desc.ddsCaps.dwCaps == (caps_in | DDSCAPS_SYSTEMMEMORY))
|
||||
|| (software_device && test_data[i].pf == &z_fmt
|
||||
|
@ -6962,6 +7011,11 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &rt, NULL);
|
||||
|
@ -18750,7 +18804,7 @@ static void test_texture_wrong_caps(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -19506,6 +19560,109 @@ static void test_enum_devices(void)
|
|||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
}
|
||||
|
||||
static void test_multiple_devices(void)
|
||||
{
|
||||
IDirect3DDevice3 *device, *device2, *device3;
|
||||
D3DMATERIALHANDLE mat_handle, mat_handle2;
|
||||
IDirect3DViewport3 *viewport, *viewport2;
|
||||
IDirect3DMaterial3 *material;
|
||||
IDirectDrawSurface4 *surface;
|
||||
IDirectDraw4 *ddraw;
|
||||
IDirect3D3 *d3d;
|
||||
ULONG refcount;
|
||||
DWORD value;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DHALDevice, &surface)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3D3_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2, NULL);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
device3 = create_device(window, DDSCL_NORMAL);
|
||||
ok(!!device3, "got NULL.\n");
|
||||
|
||||
viewport = create_viewport(device, 0, 0, 640, 480);
|
||||
viewport2 = create_viewport(device2, 0, 0, 640, 480);
|
||||
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport);
|
||||
ok(hr == DDERR_INVALIDPARAMS, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetCurrentViewport(device2, viewport2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
ok(mat_handle == mat_handle2, "got different handles.\n");
|
||||
|
||||
hr = IDirect3DMaterial3_GetHandle(material, device2, &mat_handle2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
todo_wine ok(mat_handle != mat_handle2, "got same handles.\n");
|
||||
|
||||
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetLightState(device2, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetLightState(device3, D3DLIGHTSTATE_MATERIAL, mat_handle);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle2);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DViewport3_SetBackground(viewport, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DViewport3_SetBackground(viewport2, mat_handle);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
value = 0xdeadbeef;
|
||||
hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(value == TRUE, "got %#lx.\n", value);
|
||||
hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!value, "got %#lx.\n", value);
|
||||
hr = IDirect3DDevice3_GetRenderState(device3, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!value, "got %#lx.\n", value);
|
||||
|
||||
IDirect3DMaterial3_Release(material);
|
||||
IDirect3DViewport3_Release(viewport);
|
||||
IDirect3DViewport3_Release(viewport2);
|
||||
|
||||
refcount = IDirect3DDevice3_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice3_Release(device2);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice3_Release(device3);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirectDrawSurface4_Release(surface);
|
||||
ok(!refcount, "Surface has %lu references left.\n", refcount);
|
||||
IDirectDraw4_Release(ddraw);
|
||||
IDirect3D3_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(ddraw4)
|
||||
{
|
||||
DDDEVICEIDENTIFIER identifier;
|
||||
|
@ -19647,4 +19804,5 @@ START_TEST(ddraw4)
|
|||
run_for_each_device_type(test_texture_wrong_caps);
|
||||
test_filling_convention();
|
||||
test_enum_devices();
|
||||
test_multiple_devices();
|
||||
}
|
||||
|
|
|
@ -498,7 +498,8 @@ static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7
|
|||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid)
|
||||
static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const GUID *device_guid,
|
||||
IDirectDrawSurface7 **ret_surface)
|
||||
{
|
||||
IDirectDrawSurface7 *surface, *ds;
|
||||
IDirect3DDevice7 *device = NULL;
|
||||
|
@ -586,9 +587,16 @@ static IDirect3DDevice7 *create_device_ex(HWND window, DWORD coop_level, const G
|
|||
|
||||
hr = IDirect3D7_CreateDevice(d3d7, device_guid, surface, &device);
|
||||
IDirect3D7_Release(d3d7);
|
||||
IDirectDrawSurface7_Release(surface);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IDirectDrawSurface7_Release(surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret_surface)
|
||||
*ret_surface = surface;
|
||||
else
|
||||
IDirectDrawSurface7_Release(surface);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
@ -615,7 +623,7 @@ static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
|
|||
|
||||
IDirect3D7_Release(d3d7);
|
||||
|
||||
return create_device_ex(window, coop_level, device_guid);
|
||||
return create_device_ex(window, coop_level, device_guid, NULL);
|
||||
}
|
||||
|
||||
static bool init_3d_test_context_guid(struct ddraw_test_context *context, const GUID *device_guid)
|
||||
|
@ -625,7 +633,7 @@ static bool init_3d_test_context_guid(struct ddraw_test_context *context, const
|
|||
memset(context, 0, sizeof(*context));
|
||||
|
||||
context->window = create_window();
|
||||
if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(context->device = create_device_ex(context->window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a D3D device.\n");
|
||||
DestroyWindow(context->window);
|
||||
|
@ -1586,7 +1594,7 @@ static void test_depth_blit(const GUID *device_guid)
|
|||
HWND window;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -1844,7 +1852,7 @@ static void test_zenable(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -1948,7 +1956,7 @@ static void test_ck_rgba(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -6468,6 +6476,7 @@ static void test_unsupported_formats(void)
|
|||
|
||||
static void test_rt_caps(const GUID *device_guid)
|
||||
{
|
||||
DWORD fourcc_codes[64], fourcc_code_count;
|
||||
PALETTEENTRY palette_entries[256];
|
||||
IDirectDrawPalette *palette;
|
||||
BOOL software_device;
|
||||
|
@ -6485,6 +6494,12 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
|
||||
{8}, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000},
|
||||
};
|
||||
static const DDPIXELFORMAT fourcc_fmt =
|
||||
{
|
||||
.dwSize = sizeof(DDPIXELFORMAT),
|
||||
.dwFlags = DDPF_FOURCC,
|
||||
.dwFourCC = MAKEFOURCC('Y','U','Y','2'),
|
||||
};
|
||||
|
||||
const struct
|
||||
{
|
||||
|
@ -6672,6 +6687,14 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
},
|
||||
{
|
||||
&fourcc_fmt,
|
||||
DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_OFFSCREENPLAIN,
|
||||
0,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
DDERR_INVALIDCAPS,
|
||||
},
|
||||
};
|
||||
|
||||
software_device = is_software_device_type(device_guid);
|
||||
|
@ -6706,6 +6729,10 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
fourcc_code_count = ARRAY_SIZE(fourcc_codes);
|
||||
hr = IDirectDraw4_GetFourCCCodes(ddraw, &fourcc_code_count, fourcc_codes);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(test_data); ++i)
|
||||
{
|
||||
IDirectDrawSurface7 *surface, *rt, *expected_rt, *tmp;
|
||||
|
@ -6723,9 +6750,29 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.ddsCaps.dwCaps2 = test_data[i].caps2_in;
|
||||
if (test_data[i].pf)
|
||||
{
|
||||
if (test_data[i].pf->dwFlags & DDPF_FOURCC)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j = 0; j < fourcc_code_count; ++j)
|
||||
{
|
||||
if (test_data[i].pf->dwFourCC == fourcc_codes[j])
|
||||
break;
|
||||
}
|
||||
if (j == fourcc_code_count)
|
||||
{
|
||||
skip("Fourcc format %#lx is not supported, skipping test.\n", test_data[i].pf->dwFourCC);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
if ((caps_in & DDSCAPS_VIDEOMEMORY) && !(hal_caps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
|
||||
|
@ -6751,6 +6798,9 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
else
|
||||
expected_caps = caps_in | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
expected_caps |= DDSCAPS_FRONTBUFFER;
|
||||
|
||||
ok(surface_desc.ddsCaps.dwCaps == expected_caps || (test_data[i].pf == &p8_fmt
|
||||
&& surface_desc.ddsCaps.dwCaps == (caps_in | DDSCAPS_SYSTEMMEMORY))
|
||||
|| (software_device && test_data[i].pf == &z_fmt
|
||||
|
@ -6810,6 +6860,11 @@ static void test_rt_caps(const GUID *device_guid)
|
|||
surface_desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
surface_desc.ddpfPixelFormat = *test_data[i].pf;
|
||||
}
|
||||
if (caps_in & DDSCAPS_FLIP)
|
||||
{
|
||||
surface_desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
||||
surface_desc.dwBackBufferCount = 1;
|
||||
}
|
||||
surface_desc.dwWidth = 640;
|
||||
surface_desc.dwHeight = 480;
|
||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &rt, NULL);
|
||||
|
@ -19134,7 +19189,7 @@ static void test_texture_wrong_caps(const GUID *device_guid)
|
|||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid)))
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, device_guid, NULL)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
|
@ -20001,6 +20056,69 @@ static void run_for_each_device_type(void (*test_func)(const GUID *))
|
|||
winetest_pop_context();
|
||||
}
|
||||
|
||||
static void test_multiple_devices(void)
|
||||
{
|
||||
IDirect3DDevice7 *device, *device2;
|
||||
IDirectDrawSurface7 *surface;
|
||||
IDirectDraw7 *ddraw;
|
||||
IDirect3D7 *d3d;
|
||||
ULONG refcount;
|
||||
DWORD stateblock;
|
||||
DWORD value;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
window = create_window();
|
||||
if (!(device = create_device_ex(window, DDSCL_NORMAL, &IID_IDirect3DTnLHalDevice, &surface)))
|
||||
{
|
||||
skip("Failed to create a 3D device, skipping test.\n");
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3D7_CreateDevice(d3d, &IID_IDirect3DHALDevice, surface, &device2);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice7_CreateStateBlock(device, D3DSBT_ALL, &stateblock);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice7_CaptureStateBlock(device2, stateblock);
|
||||
ok(hr == D3DERR_INVALIDSTATEBLOCK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice7_CaptureStateBlock(device, stateblock);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
hr = IDirect3DDevice7_DeleteStateBlock(device, stateblock);
|
||||
ok(hr == D3D_OK, "got %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
hr = IDirect3DDevice3_SetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
value = 0xdeadbeef;
|
||||
hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(value == TRUE, "got %#lx.\n", value);
|
||||
hr = IDirect3DDevice3_GetRenderState(device2, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
|
||||
ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
|
||||
ok(!value, "got %#lx.\n", value);
|
||||
|
||||
refcount = IDirect3DDevice3_Release(device);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirect3DDevice3_Release(device2);
|
||||
ok(!refcount, "Device has %lu references left.\n", refcount);
|
||||
refcount = IDirectDrawSurface4_Release(surface);
|
||||
ok(!refcount, "Surface has %lu references left.\n", refcount);
|
||||
IDirectDraw4_Release(ddraw);
|
||||
IDirect3D3_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(ddraw7)
|
||||
{
|
||||
DDDEVICEIDENTIFIER2 identifier;
|
||||
|
@ -20176,4 +20294,5 @@ START_TEST(ddraw7)
|
|||
test_enum_devices();
|
||||
run_for_each_device_type(test_user_memory);
|
||||
test_flip_3d();
|
||||
test_multiple_devices();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
|
|||
{
|
||||
struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface);
|
||||
ULONG ref = InterlockedDecrement(&buffer->ref);
|
||||
struct d3d_device *device;
|
||||
|
||||
TRACE("%p decreasing refcount to %lu.\n", buffer, ref);
|
||||
|
||||
|
@ -85,8 +86,12 @@ static ULONG WINAPI d3d_vertex_buffer7_Release(IDirect3DVertexBuffer7 *iface)
|
|||
* stream source in wined3d and they should get unset there before
|
||||
* they are destroyed. */
|
||||
wined3d_mutex_lock();
|
||||
if (buffer->ddraw->stateblock_state->streams[0].buffer == buffer->wined3d_buffer)
|
||||
wined3d_stateblock_set_stream_source(buffer->ddraw->state, 0, NULL, 0, 0);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(device, &buffer->ddraw->d3ddevice_list, struct d3d_device, ddraw_entry)
|
||||
{
|
||||
if (device->stateblock_state->streams[0].buffer == buffer->wined3d_buffer)
|
||||
wined3d_stateblock_set_stream_source(device->state, 0, NULL, 0, 0);
|
||||
}
|
||||
|
||||
wined3d_vertex_declaration_decref(buffer->wined3d_declaration);
|
||||
wined3d_buffer_decref(buffer->wined3d_buffer);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue