#include "bitblt.h" #include "nt/providers.h" #include #include #include static void check(bool value,const char *message) { if (!value) throw std::runtime_error(message); } int main(int argc,char **argv) { try { check(argc==2,"bootstrap required"); raven::ModuleSet modules; auto &module=modules.add("kernel32.dll",raven::environment_provider("kernel32.dll",0x180000000)); raven::LoadedImage *images[]{&module.loaded}; raven::NativeProcess process(images,argv[1],std::chrono::seconds(2)); raven::DesktopObjects objects; std::vector source(4*3*4),destination(source.size(),0x73); for (size_t i=0;iclip.emplace(); objects.dc(b)->clip.emplace(); objects.dc(b)->clip->add({1,0,4,3}); objects.dc(b)->clip->subtract({2,1,3,2}); uint64_t args[]{b,0,0,4,3,a,0,0,0x00cc0020}; check(raven::bit_blt(process,objects,args),"blit incorrectly used source clipping"); for (unsigned y=0;y<3;++y) for (unsigned x=0;x<4;++x) for (unsigned c=0;c<4;++c) { const size_t at=(y*4+x)*4+c; check(objects.bitmap(sb)->bits[at]==(x>=1 && !(x==2 && y==1) ? source[at] : 0x73),"blit escaped destination clip or missed a region"); } objects.dc(b)->clip.reset(); objects.bitmap(sb)->bits=source; args[5]=b; args[1]=1; args[3]=3; check(raven::bit_blt(process,objects,args),"overlapping blit failed"); for (unsigned y=0;y<3;++y) for (unsigned x=1;x<4;++x) for (unsigned c=0;c<4;++c) check(objects.bitmap(sb)->bits[(y*4+x)*4+c]==source[(y*4+x-1)*4+c],"overlapping source was not snapshotted"); const auto before=objects.bitmap(sb)->bits; for (unsigned failure=0;failure<5;++failure) { args[0]=failure==0 ? 0 : b; args[5]=failure==1 ? 0 : a; args[8]=failure==2 ? 0x40cc0020 : 0x00cc0020; args[3]=failure==3 ? uint32_t(-1) : 3; if (failure==4) objects.bitmap(sa)->depth=1; bool rejected=false; try { raven::bit_blt(process,objects,args); } catch (uint32_t error) { rejected=error==(failure<2 ? 6U : 120U); } check(rejected && objects.bitmap(sb)->bits==before,"unsupported blit succeeded or mutated destination"); } } catch (const std::exception &error) { std::cerr<