日历
网志分类
展开全部
· ***    All     ***
· ***    Mood    ***
· ***    Life    ***
· *** Technology ***
· ***     Yc     ***
· ***  Cartoon   ***
· *** Collection ***
· ***  Unsorted  ***
媒体播放器

Get the Flash Player to see this player.
SkyDrive is currently not available.

站内搜索
友情链接
· 我的歪酷 非非共享界
· 风雨妖虹
· kingbeful@csdn
· 手心的太阳@瞬间十年
· Moment@Travis
· 江南麒麟居
· εз毛线团εз
· 乌拉的neverland
· 碾过的日子 闲也陶陶
· 狡兔三窟 *^.^*
· 橄榄林的风
· 水色の街
· Powerful and delicate, Life struggling
· 阿德咖吧
· 陷阱
· 风之华
· vkobe的Neverland@@
· 白日梦已死 · 伤越夜海
· 望天
· 空の軌跡
· 没什么好东西的空间
· 心情...咖啡屋
· 随风独自凉
· Some where i belong
· .★·°双晨·故事°☆ .
· BigWorld的记事本
· *Sara's*
· 人生若只如初见
· 宠辱不惊闲看庭前花开花落·去留无意漫随天外云卷云舒
· 我思我不在
· 飞扬飘雨
· lazy的猫猫
常用链接
· [Google]
· [Google Accounts]
· [IT Items]
· [Telnet@Yanxi]
· [Wikipedia]
· [Linux Manpages]
· [Mofile.com]
· [163888.net]
· [fm.qq.com]
· [Proxy]
· [Animepaper.net]
· [FreeproxySite]
· [gonwan@fc2]
· [skydrive.live.com]
· [gonwan@lifelogger]

订阅 RSS

0109289

歪酷博客

逆さまの蝶
In this Craziness
Uncertainy
一人一人の想いを
僕らは何処かに遺せるだろうか

In this Craziness
You gave me life
一つの想いを
僕らは何処まで守れるだろうか



« 上一篇: 一个程序, 省钱, 省麻烦 下一篇: 十月新番全面完结 »
丸子·酱 @ 2008-03-25 17:30

    最近对于Vista下的service的debug工作真是太有心得了.

    Service起来的时候可能你的桌面都没有show出来, 那么这种时候怎么debug呢? 写文件? 不错的方法. 但是我们有更好的方法: 写event log. ATL中的CAtlServiceModuleT这个类中有LogEvent()这个函数, 可以很方便的调用. 瞄了一眼, 其实这是一个很light-weight的函数, 稍微改改完全可以单独使用:
void LogEvent(LPCTSTR pszFormat, ...)
{
    TCHAR chMsg[1024];
    HANDLE hEventSource;
    va_list pArg;
    va_start(pArg, pszFormat);
    _vstprintf(chMsg, pszFormat, pArg);
    va_end(pArg);
    /* Get a handle to use with ReportEvent(). */
    hEventSource = RegisterEventSource(NULL, SERVICE_NAME);
    if (hEventSource != NULL)
    {
        /* Write to event log. */
        ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &chMsg, NULL);
        DeregisterEventSource(hEventSource);
    }
}

    然后就是FAQ了, service中怎么起一个程序? 诶, 其实直接CreateProcess()的话程序是起来的, 但只是跑在当前service的那个session下了, 所以你看不见而已. 那怎么才能看见呢? 这个技术叫做impersonate -.-. 我们要拿到当前active用户的执行environment和权限token, 然后调用CreateProcessAsUser(). 这里我用的全部都是unicode, msdn的论坛上说ansi版本有bug @.- :
BOOL RunProcess(LPWSTR lpwszPath, LPWSTR lpwszArgs)
{
    HANDLE hToken = NULL, hTokenDup = NULL;
    DWORD dwSessionId = WTSGetActiveConsoleSessionId();
    WTSQueryUserToken(dwSessionId, &hToken);
    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);

    LPVOID pEnv = NULL;
    DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
    CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
    dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;

    WCHAR wszTemp[MAX_PATH];
    ZeroMemory(wszTemp, MAX_PATH*sizeof(WCHAR));
    wsprintfW(wszTemp, L"\"%s\" %s", lpwszPath, lpwszArgs);

    STARTUPINFOW si = { sizeof(STARTUPINFO) };
    si.lpDesktop = L"winsta0\default";
    PROCESS_INFORMATION pi;
    BOOL bRet = CreateProcessAsUserW(hTokenDup, NULL, wszTemp,
        NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi);
    if (bRet)
    {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    DestroyEnvironmentBlock(&pEnv);
    CloseHandle(hToken);
    CloseHandle(hTokenDup);

    return bRet;
}
    恩, winsta0表示当前的windows station, 表看成winvista0. default表示当前的session. 其它应该没什么好解释了.

    最后还有两个函数, 用来真正的impersonate. 由于一般service都跑在local system账号下, 所以注册表之类的HKEY_CURRENT_USER之类的键值其实访问的都不是当前active的用户, 而就是local system这个账号的. 看到一篇文章所幸就说service里不能访问HKEY_CURRENT_USER, 囧... 好了废话不多说:
void BeginImpersonate()
{
    HANDLE hToken = NULL, hTokenDup = NULL;
    DWORD dwSessionId = WTSGetActiveConsoleSessionId();
    WTSQueryUserToken(dwSessionId, &hToken);
    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
    ImpersonateLoggedOnUser(hTokenDup);
    CloseHandle(hToken);
    CloseHandle(hTokenDup);
}
void EndImpersonate()
{
    RevertToSelf();
}
    这两个函数分别开始和结束impersonate一个账号. 之前忘了说了, 拿到当前active的用户的API用的是WTS(Windows Terminal Service)的那套.

    以上...
    另外可以参考我之前写的:
Windows Service Howto (1)
Windows Service Howto (2)




评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定