// Owned scalar telemetry reference provider. No process, memory-address or driver API.
#include <windows.h>
#include <nlohmann/json.hpp>
#include <string>
#include <iostream>
#include <cmath>
using Json=nlohmann::json;
bool id_valid(const std::string& id){if(id.empty()||id.size()>64)return false;for(char c:id)if(!((c>='a'&&c<='z')||(c>='0'&&c<='9')||c=='-'||c=='_'))return false;return true;}
struct Handle{HANDLE h{};explicit Handle(HANDLE v):h(v){}~Handle(){if(h&&h!=INVALID_HANDLE_VALUE)CloseHandle(h);}};
bool wait_io(HANDLE pipe,OVERLAPPED& operation,bool started,DWORD& count,DWORD timeout){
if(started)return true;if(GetLastError()!=ERROR_IO_PENDING)return false;
if(WaitForSingleObject(operation.hEvent,timeout)!=WAIT_OBJECT_0){CancelIoEx(pipe,&operation);GetOverlappedResult(pipe,&operation,&count,TRUE);return false;}
return GetOverlappedResult(pipe,&operation,&count,FALSE)!=FALSE;
}
int main(int argc,char** argv){
try{
const std::string id=argc>1?argv[1]:"demo",mode=argc>2?argv[2]:"normal";
if(!id_valid(id))throw std::runtime_error("invalid provider id");
const auto name=L"\\\\.\\pipe\\EasyUniversalTelemetry-"+std::wstring(id.begin(),id.end());
Json values={{"speed",42},{"rpm",1200},{"label","Easy owned telemetry"},{"enabled",true}};
Handle pipe(CreateNamedPipeW(name.c_str(),PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED|FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT|PIPE_REJECT_REMOTE_CLIENTS,1,8192,8192,0,nullptr));
if(pipe.h==INVALID_HANDLE_VALUE)throw std::runtime_error("provider pipe unavailable");
std::cout<<GetCurrentProcessId()<<std::endl;
const auto until=GetTickCount64()+300000;
while(GetTickCount64()<until){
// Reuse the first instance: recreating it races the previous client's handle close.
DisconnectNamedPipe(pipe.h);
Handle event(CreateEventW(nullptr,TRUE,FALSE,nullptr));if(!event.h)throw std::runtime_error("provider event failed");
OVERLAPPED operation{};operation.hEvent=event.h;DWORD count=0;
bool connected=ConnectNamedPipe(pipe.h,&operation)!=FALSE;
if(!connected&&GetLastError()==ERROR_PIPE_CONNECTED)connected=true;
const auto now=GetTickCount64();
if(!wait_io(pipe.h,operation,connected,count,now>=until?0:DWORD(until-now)))continue;
ResetEvent(event.h);operation={};operation.hEvent=event.h;char bytes[8193];
if(!wait_io(pipe.h,operation,ReadFile(pipe.h,bytes,sizeof(bytes),&count,&operation)!=FALSE,count,300)||count>8192)continue;
unsigned depth=0;bool quoted=false,escape=false,valid=true;
for(DWORD i=0;i<count;i++){char c=bytes[i];if(quoted){if(escape)escape=false;else if(c=='\\')escape=true;else if(c=='"')quoted=false;}
else if(c=='"')quoted=true;else if(c=='{'||c=='['){if(++depth>4){valid=false;break;}}else if(c=='}'||c==']'){if(!depth){valid=false;break;}--depth;}}
if(!valid||depth||quoted)continue;
auto request=Json::parse(std::string(bytes,count),nullptr,false);
if(!request.is_object()||request.size()!=4||!request.contains("protocol")||request["protocol"]!=1||!request.contains("sequence")||!request["sequence"].is_number_unsigned()||
!request.contains("op")||request["op"]!="snapshot"||!request.contains("updates")||!request["updates"].is_object()||request["updates"].size()>8)continue;
if(mode=="stall"){Sleep(700);continue;}
auto staged=values;bool accepted=mode!="reject"&&mode!="readonly";
for(auto it=request["updates"].begin();it!=request["updates"].end();++it){
const auto& v=it.value();bool scalar=v.is_boolean()||(v.is_string()&&v.get_ref<const std::string&>().size()<=1024)||(v.is_number()&&std::isfinite(v.get<double>())&&std::abs(v.get<double>())<=1e12);
if(!id_valid(it.key())||!scalar){accepted=false;break;}staged[it.key()]=v;
}
if(staged.size()>64||staged.dump().size()>7000)accepted=false;if(accepted)values=staged;
Json caps=Json::array({"snapshot"});if(mode!="readonly")caps.push_back("update");
auto response=Json{{"protocol",1},{"sequence",request["sequence"]},{"provider",id},{"capabilities",caps},{"values",values},{"accepted",accepted}};
if(mode=="bad-sequence")response["sequence"]=request["sequence"].get<uint64_t>()+1;
auto reply=mode=="oversize"?std::string(9000,'x'):response.dump();
ResetEvent(event.h);operation={};operation.hEvent=event.h;
if(wait_io(pipe.h,operation,WriteFile(pipe.h,reply.data(),DWORD(reply.size()),&count,&operation)!=FALSE,count,300)){
ResetEvent(event.h);operation={};operation.hEvent=event.h;char ack{};
wait_io(pipe.h,operation,ReadFile(pipe.h,&ack,1,&count,&operation)!=FALSE,count,100);
}
// Disconnect/reuse without FlushFileBuffers: a lost client must not stall the server.
}
return 0;
}catch(const std::exception& e){std::cerr<<e.what()<<std::endl;return 1;}
}
Easy Universal / Примеры и шаблоны