c++练习守护注册表服务程序
来源:互联网 发布:知之深爱之切全书内容 编辑:程序博客网 时间:2024/06/14 00:40
服务程序读写 HKEY_CURRENT_USER 注册表不同于普通程序,需要在路径前面添加用户的SID + “注册表路径”才是当前登录用户的正确注册表位置, 并且主键 HKEY_CURRENT_USER 需改为 HKEY_USERS 。其他路径不用变。
资料参考 http://www.2cto.com/kf/201111/111990.html
// SCguardHomepage.cpp : 定义控制台应用程序的入口点。///*================================================================================================= 如何安装服务: 运行命令提示符cmd.exe 输入 sc create SCguardHomepage binpath= E:\vs-proj\SCguardHomepage\Release\SCguardHomepage.exe 输入 sc start SCguardHomepage 启动服务 输入 sc query 会在最底部显示你的服务当前的状态 输入 sc stop SCguardHomepage 停止服务 输入 sc delete SCguardHomepage 删除服务,该服务将在下次重启后删除,在重启之前将不能注册同一个名字的服务。=================================================================================================*/#include "stdafx.h"#include <stdio.h>#include <Windows.h>#include "CLog.h"#include"tlhelp32.h"#include<Sddl.h>#include <WtsApi32.h>#pragma comment(lib, "WtsApi32.lib")#define SLEEP_TIME 5000 //间隔时间#define FILE_PATH "C:\\cLog.log" //信息输出文件using namespace std;HKEY hKEY;bool brun=false;SERVICE_STATUS servicestatus;SERVICE_STATUS_HANDLE hstatus;int WriteToLog(char* str);void WINAPI ServiceMain(int argc, char** argv);void WINAPI CtrlHandler(DWORD request);int InitService();/*void showNowLog(){ m_LogModule->Init(); ////CLog类的成员 m_LogModule->ShowNowLogConsole(); //Console 显示}void hideNowLog(){ m_LogModule->HideNowLogConsole(); //隐藏 Console}*/int WriteToLog(char* str){ FILE* pfile; fopen_s(&pfile,FILE_PATH,"a+"); if (pfile==NULL) { return -1; } time_t t = time(0); char tmp[64]; strftime( tmp, sizeof(tmp), "%Y/%m/%d %X",localtime(&t)); fprintf_s(pfile,"%s --> %s\n",tmp,str); fclose(pfile); return 0;}//查找进程IDDWORD FindProcessByName(LPCWSTR ProcessName){ HANDLE hHandle; DWORD i; BOOL Next; wchar_t szName[MAX_PATH]; PROCESSENTRY32 p32 = {sizeof(p32)}; hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); Next = Process32First(hHandle, &p32); i = 0; while (Next) { wsprintf(szName, L"%s", p32.szExeFile); if (lstrcmpi(szName, ProcessName) == 0) { return p32.th32ProcessID ; } Next = Process32Next(hHandle, &p32); i++; } CloseHandle(hHandle); return 0;}////获取用户sid//BOOL GetAccountSid(LPTSTR AccountName, PSID *Sid){ PSID pSID = NULL; DWORD cbSid = 0; LPTSTR DomainName = NULL; DWORD cbDomainName = 0; SID_NAME_USE SIDNameUse; BOOL bDone = FALSE; try { if(!LookupAccountName(NULL, AccountName, pSID, &cbSid, DomainName, &cbDomainName, &SIDNameUse)) { pSID = (PSID)malloc(cbSid); DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR)); if(!pSID || !DomainName) { throw; } if(!LookupAccountName(NULL, AccountName, pSID, &cbSid, DomainName, &cbDomainName, &SIDNameUse)) { throw; } bDone = TRUE; } } catch(...) { //nothing } if(DomainName) { free(DomainName); } if(!bDone && pSID) { free(pSID); } if(bDone) { *Sid = pSID; } return bDone;}std::string getUserSid(){ //要调用ImpersonateLoggedOnUser 函数,就先要获得该用户的令牌 (token) DWORD pid = FindProcessByName(L"explorer.exe"); HANDLE ph = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); HANDLE token; OpenProcessToken (ph, TOKEN_QUERY | TOKEN_DUPLICATE, &token); //模拟登录用户的安全上下文 ImpersonateLoggedOnUser (token); //获取用户名 wchar_t szBuf[MAX_PATH] = L""; DWORD dwRet = MAX_PATH; GetUserName(szBuf, &dwRet); //到这里已经模拟完了,别忘记返回原来的安全上下文 RevertToSelf(); //获取sid PSID pSid = NULL; LPWSTR sid; GetAccountSid(szBuf, &pSid); //获取得到的是一个结构体 ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串 //可以读取了,注意RegQueryValueEx的参数“HKEY_USERS” char cStr[_MAX_PATH]; memset(cStr,'\0',_MAX_PATH); int iLength = WideCharToMultiByte(CP_ACP, 0, sid, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, sid, -1, cStr, iLength, NULL, NULL); std::string strSid = cStr; return strSid;}/*------------------------------------------------------------------------------------------------ 将你需要执行的任务放到该函数中循环执行即可。 这就是服务程序的工作函数。在ServiceMain执行你的任务前, 需要给SERVICE_TABLE_ENTRY 分派表结构体进行赋值, 注意由于此时服务还没有开始执行你的任务所以我们将服务的状态设置为SERVICE_START_PENDING,即正在初始化------------------------------------------------------------------------------------------------*/void WINAPI ServiceMain(int argc, char** argv){ servicestatus.dwServiceType = SERVICE_WIN32; servicestatus.dwCurrentState = SERVICE_START_PENDING; servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;//在本例中只接受系统关机和停止服务两种控制命令 servicestatus.dwWin32ExitCode = 0; servicestatus.dwServiceSpecificExitCode = 0; servicestatus.dwCheckPoint = 0; servicestatus.dwWaitHint = 0; //Hstatus为SERVICE_STATUS_HANDLE类型的全局变量。当需要改变服务状态时SetServiceStatus()函数需要它做为参数来标识一个服务。 hstatus = ::RegisterServiceCtrlHandler(L"SCguardHomepage", CtrlHandler); if (hstatus==0) { //NowLogStringEx(_T("RegisterServiceCtrlHandler failed")); WriteToLog("RegisterServiceCtrlHandler failed"); return; } //NowLogStringEx(_T("RegisterServiceCtrlHandler success")); WriteToLog("RegisterServiceCtrlHandler success"); //向SCM 报告运行状态 servicestatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hstatus, &servicestatus); //下面就开始任务循环了,你可以添加你自己希望服务做的工作 brun=true; while (brun) { //---------------------------------------- char pBuf[500]; memset(pBuf,'\0',500); DWORD dllPathLength = GetModuleFileNameA(NULL, pBuf, sizeof(pBuf)); *(strrchr( pBuf, '\\') ) = 0; strcat_s(pBuf, "\\lewangIE.exe"); CString strDefaultKeyValue=pBuf; strDefaultKeyValue=_T("\"")+strDefaultKeyValue+_T("\" \"%1\""); WriteToLog(pBuf); //--------------------------------------------------------------------服务读注册表例子 std::string keyPosition = getUserSid(); keyPosition += "\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice"; WriteToLog(const_cast<char*>(keyPosition.c_str())); int result = RegOpenKeyExA(HKEY_USERS,keyPosition.data(),0,KEY_READ,&hKEY); if(result != 0) { WriteToLog("没打开注册表");return;} DWORD dwKeyValueType; char szRegItem[256] = { 0 }; //注册表值 DWORD iRegItemLen = sizeof(szRegItem); result = RegQueryValueExA(hKEY, "Progid", 0, &dwKeyValueType, (LPBYTE)szRegItem, &iRegItemLen); if (result != 0) { RegCloseKey(hKEY); return; } RegCloseKey(hKEY); WriteToLog(szRegItem); Sleep(SLEEP_TIME); } WriteToLog("service stopped");}/*--------------------------------------------------------------------------------- 接收系统传递的控制命令,比如当你通过sc.exe关闭服务时, 该函数会收到SERVICE_CONTROL_STOP消息,你就可以对服务进行必要的管理。 在本例子程序中就只接收SERVICE_ACCEPT_SHUTDOWN和SERVICE_ACCEPT_STOP消息, 这是通过前面给servicestatus赋值设定的。----------------------------------------------------------------------------------*/void WINAPI CtrlHandler(DWORD request){ switch (request) { case SERVICE_CONTROL_STOP: brun=false; servicestatus.dwCurrentState = SERVICE_STOPPED; break; case SERVICE_CONTROL_SHUTDOWN: brun=false; servicestatus.dwCurrentState = SERVICE_STOPPED; break; default: break; } SetServiceStatus (hstatus, &servicestatus);}void main(){ //showNowLog(); //NowLogStringEx(_T("服务开始了")); SERVICE_TABLE_ENTRY entrytable[2]; entrytable[0].lpServiceName=L"SCguardHomepage"; entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain; entrytable[1].lpServiceName=NULL; entrytable[1].lpServiceProc=NULL; StartServiceCtrlDispatcher(entrytable);}
0 0
- c++练习守护注册表服务程序
- Linux (系统服务守护程序)
- C程序练习
- C程序练习
- C语言程序练习
- C程序练习
- c语言程序练习
- 服务程序C#编写系统服务,注册表读写问题
- 服务程序C#编写系统服务,注册表读写问题
- 完全卸载mysql(停止服务、卸载相关程序、删除注册表
- 完全卸载mysql(停止服务、卸载相关程序、删除注册表
- linux后台服务程序练习开发
- c初学者练习程序需求
- 第一次c程序 编码练习
- c语言小程序练习
- c语言程序练习一
- c语言程序练习二
- C语言程序练习三
- 欧拉角与万向节死锁
- 引导页实现ScrollView左右无缝滚动
- vlc在ubuntu下安装
- 模仿网易新闻做的新闻软件
- 美团Android自动化之旅—生成渠道包
- c++练习守护注册表服务程序
- NSSearchPathForDirectoriesInDomains和NSHomeDirectory
- 通过自定义theme来改变Activity之间切换动画
- python 学习
- UICollectionView执行performBatchUpdates 奔溃
- poj 2369 Permutations 【置换群】
- AFNetworking Post 请求
- CSS常用属性:
- Servlet 生命周期、工作原理