﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-aurain-随笔分类-Windows开发</title><link>http://www.cppblog.com/aurain/category/10149.html</link><description>专注Windows下的驱动开发、网络开发</description><language>zh-cn</language><lastBuildDate>Mon, 15 Aug 2011 16:50:48 GMT</lastBuildDate><pubDate>Mon, 15 Aug 2011 16:50:48 GMT</pubDate><ttl>60</ttl><item><title>windows 多线程编程的几点经验 (防止死锁)</title><link>http://www.cppblog.com/aurain/archive/2011/08/15/153407.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 15 Aug 2011 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2011/08/15/153407.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/153407.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2011/08/15/153407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/153407.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/153407.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: windows 多线程编程的几点经验 (防止死锁)&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2011/08/15/153407.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/153407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2011-08-15 10:46 <a href="http://www.cppblog.com/aurain/archive/2011/08/15/153407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc2008编译openssl</title><link>http://www.cppblog.com/aurain/archive/2010/09/15/126633.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Wed, 15 Sep 2010 02:19:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2010/09/15/126633.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/126633.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2010/09/15/126633.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/126633.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/126633.html</trackback:ping><description><![CDATA[<p>需要先安装ActivePerl，下载地址<a href="http://downloads.activestate.com/ActivePerl/releases/5.12.2.1202/ActivePerl-5.12.2.1202-MSWin32-x86-293621.msi">http://downloads.activestate.com/ActivePerl/releases/5.12.2.1202/ActivePerl-5.12.2.1202-MSWin32-x86-293621.msi</a><br>openssl源代码，下载地址<a href="http://www.openssl.org/source/openssl-1.0.0.tar.gz">http://www.openssl.org/source/openssl-1.0.0.tar.gz</a><br><br>从VC2008命令行进入openssl源代码目录：<br>开始菜单-&gt;所有程序-&gt;Microsoft Visual Studio 2008-&gt;Visual Studio Tools-&gt;Visual Studio 2008 Command Prompt<br>cd /d c:\openssl-1.0.0<br>运行Configure：<br>perl Configure VC-WIN32 no-asm --prefix=c:/openssl<br>创建Makefile文件:<br>ms\do_ms<br>编译动态库：<br>nmake -f ms\ntdll.mak<br>编译静态库：<br>nmake -f ms\nt.mak</p>
<p>测试动态库：<br>nmake -f ms\ntdll.mak test<br>测试静态库：<br>nmake -f ms\nt.mak test</p>
<p>安装动态库：<br>nmake -f ms\ntdll.mak install<br>安装静态库：<br>nmake -f ms\nt.mak install</p>
<p>清除上次动态库的编译，以便重新编译：<br>nmake -f ms\ntdll.mak clean<br>清除上次静态库的编译，以便重新编译：<br>nmake -f ms\nt.mak clean<br></p>
<img src ="http://www.cppblog.com/aurain/aggbug/126633.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2010-09-15 10:19 <a href="http://www.cppblog.com/aurain/archive/2010/09/15/126633.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows核心编程学习笔记之二（进程）</title><link>http://www.cppblog.com/aurain/archive/2010/05/21/116024.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Fri, 21 May 2010 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2010/05/21/116024.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/116024.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2010/05/21/116024.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/116024.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/116024.html</trackback:ping><description><![CDATA[<p><font size=2><strong><span>5</span></strong><strong><span>．进程：</span></strong></font></p>
<p><font size=2><span>（</span><span>1</span><span>）在</span><span>Win32</span><span>系统中每一个进程都拥有</span><span>4GB</span><span>的地址空间。</span><span>Win32</span><span>进程什么也不执行，它只是拥有</span><span>4GB</span><span>的地址空间来存放应用程序</span><span>EXE</span><span>文件所需要的代码和数据。除地址空间外，进程还拥有文件、动态内存、线程等资源。由线程负责执行包含在进程地址空间里的代码。每一个线程有它自己的</span><span>CPU</span><span>寄存器组和自己的栈。每一个进程至少有一个线程来执行包含在地址空间中的代码。如果地址空间中没有线程在执行代码，那么系统就会释放进程和它的地址空间。</span></font></p>
<br>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(2)</span><span>加载器：</span><span>Win32</span><span>支持两类应用程序，控制台应用程序</span><span>CUI</span><span>和图形用户界面应用程序</span><span>GUI</span><span>。</span><span>Exe</span><span>文件中的一个子系统值指出这个应用程序是控制台应用程序还是图形用户界面应用程序。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(3)VC</span><span>编写的</span><span>Win32</span><span>控制台应用程序都有一个</span><span>main</span><span>函数，而图形界面应用程序都有一个</span><span>WinMain</span><span>函数。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(4)C/C++</span><span>的启动函数：</span><span>_WinMainCRTStartup</span><span>函数。它负责执行：</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>1.</span><span>得到一个新进程的全部命令行指针。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>2.</span><span>得到一个新进程的环境变量指针。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>3.</span><span>通过包含</span><span>Stdlib.h</span><span>来初始化能被应用程序访问的</span><span>C</span><span>运行时全局变量。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>4.</span><span>初始化由</span><span>C</span><span>运行时内存分配函数使用的堆和其它的低级输入输出例程。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>5</span><span>调用</span><span>WinMain</span><span>函数。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>6.</span><span>当</span><span>WinMain</span><span>返回后，启动代码调用</span><span>C</span><span>运行时的</span><span>exit</span><span>函数，传给它</span><span>WinMain</span><span>的返回值。</span><span>Exit</span><span>函数执行一些清理工作，然后调用</span><span>Win32</span><span>的</span><span>ExitProcess</span><span>函数，传给它</span><span>WinMain</span><span>函数的返回值。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(5)</span><span>实例句柄：每一个加载到进程地址空间的</span><span>Exe</span><span>或</span><span>DLL</span><span>文件都有一个唯一的实例句柄。</span><span>WinMain</span><span>的第一个参数</span><span>hinstExe</span><span>是</span><span>Exe</span><span>文件的实例。在加载资源时所使用的函数要使用这个实例句柄。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(6)</span><span>基本内存地址：</span><span>WinMain</span><span>的参数</span><span>hinstExe</span><span>的实际值就是一个基本内存地址。它指出系统是在什么地方把</span><span>EXE</span><span>文件的映象装入进程的地址空间的。基本内存地址由链接器决定。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(7)HANDLE GetModuleHandle(LPCTSTR lpszModule)</span><span>函数：返回的句柄是</span><span>EXE</span><span>或</span><span>DLL</span><span>文件在地址空间里的基本地址。参数是</span><span>Exe</span><span>或</span><span>DLL</span><span>文件的名字。该函数的两个需要注意的地方：一、该函数只查看调用进程的地址空间。二、参数为</span><span>NULL</span><span>时返回的是</span><span>EXE</span><span>文件的基本内存地址。</span></font></p>
<p style="TEXT-INDENT: 21.75pt"><font size=2><span>(8)</span><span>在</span><span>Win32</span><span>下</span><span>hinstExe</span><span>和</span><span>hmodExe</span><span>是一个值。</span><span>WinMain</span><span>的参数</span><span>hinstExePrev</span><span>对于</span><span>Win32</span><span>无意义，它的值总为</span><span>NULL</span><span>。在</span><span>Win32</span><span>下，应用程序的每一个实例都必须注册它自己窗口类，这是因为窗口类不能被同一应用程序中的所有实例共享。只有</span><span>hinstExePrev</span><span>值为</span><span>NULL</span><span>时，在</span><span>Win32</span><span>下应用程序的每一个实例才会注册它自己的窗口类。</span></font></p>
<p><font size=2><span>(9)</span><span>进程的环境变量函数：</span><span>BOOL SetEnviromentVariable(LPCTSTR lpszName,LPCTSTR lpszValue);</span><span>该函数把由</span><span>lpszName</span><span>标识的值设置为由</span><span>lpszValue</span><span>标识的值。如果指定的变量名已经存在，就修改它的值。如果不存在，就增加该变量。如果</span><span>lpszValue</span><span>的值为</span><span>NULL</span><span>，变量就被从环境变量中删除。</span></font></p>
<p><font size=2><span>(10)</span><span>进程的命令行</span></font></p>
<p><font size=2><span>(11)</span><span>进程的错误模式：当进程出现错误时</span><span>, </span><span>它用来告诉系统应当以何种模式去处理该错误。使用的函数是：</span><span>UINT SetErrorMode(UINT fuErrorMode);</span><span>其中参数</span><span>fuErrorMode</span><span>是以下四个值的任意组合，它们是：</span><span>SEM_FAILCRITICALERRORS(</span><span>系统不显示严重错误处理消息框，把错误返回调用的进程</span><span>)</span><span>、</span><span>SEM_NOGPFAULTERRORBOX(</span><span>系统不显示普通保护错误消息框。该标识只能被调试应用程序设置来用异常句柄自己处理普通保护错误</span><span>GP)</span><span>、</span><span>SEM_NOOPENFILEERRORBOX(</span><span>系统在找不到文件时不显示消息框</span><span>)</span><span>、</span><span>SEM_NOALIGNMENTFAULTEXCEPT(</span><span>系统自动修复内在排列错误，使它们对应用不可见。该标识对</span><span>x86</span><span>或</span><span>Alpha</span><span>处理器无用</span><span>)</span><span>。</span></font></p>
<p><font size=2><span>注：缺省情况下子进程会继承父进程的错误模式。但是父进程可以通过在调用</span><span>CreateProcess</span><span>时设置</span><span>CREATE_DEFAULT_ERROR_MODE</span><span>标识来防止子进程继承。</span></font></p>
<p>&#160;</p>
<p><font size=2><span>(12)</span><span>进程的当前驱动器和目录：可以使用下列函数来得到和设置进程的当前驱动器和目录：</span><span>DWORD GetCurrentDirectory(DWORD cchCurDir,LPCTSTR lpszCurDir);</span></font></p>
<p><span><font size=2>BOOL SetCurrentDirectory(LPCTSTR lpszCurDir);</font></span></p>
<p><font size=2><span>(13)</span><span>系统版本号：一般使用</span><span> BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation);</span><span>来得到系统版本号，其中参数</span><span>lpVersionInformation</span><span>是一个</span><span>LPOSVERSIONINFO</span><span>结构，该结构的定义如下：</span></font></p>
<p><span><font size=2>typedef struct{</font></span></p>
<p><font size=2><span>DWORD dwOSVersionInfoSize;//</span><span>在调用</span><span>GetVersionEx</span><span>函数前必须被设置为：</span><span>SizeOf(OSVERSIONINFO);</span></font></p>
<p><font size=2><span>DWORD dwMajorVersion;//</span><span>系统主版本号</span></font></p>
<p><font size=2><span>DWORD dwMinorVersion;//</span><span>系统次版本号</span></font></p>
<p><span><font size=2>DWORD dwBuildNumber;</font></span></p>
<p><font size=2><span>DWORD dwPlatformID;//</span><span>标识当前系统支持的平台</span></font></p>
<p><span><font size=2>TCHAR szCSDVersion[128]; </font></span></p>
<p style="TEXT-INDENT: 21pt"><span><font size=2>}OSVERSIONINFO,*LPOSVERSIONINFO;</font></span></p>
<p><font size=2><span>(14)CreateProcess</span><span>函数：应用程序调用</span><span>CreateProcess</span><span>函数来创建一个进程。</span></font></p>
<p><span><font size=2>BOOL CreateProcess(</font></span></p>
<p><span><font size=2>LPCTSTR lpszApplicationName,</font></span></p>
<p><span><font size=2>LPCTSTR lpszCommandLine,</font></span></p>
<p><span><font size=2>LPSECURITY_ATTRIBUTES lpsaProcess,</font></span></p>
<p><span><font size=2>LPSECURITY_ATTRIBUTES lpsaThread,</font></span></p>
<p><span><font size=2>BOOL fInheritHandles,</font></span></p>
<p><span><font size=2>DWORD fdwCreate,</font></span></p>
<p><span><font size=2>LPVOID lpvEnvironment,</font></span></p>
<p><span><font size=2>LPTSTR lpszCurDir,</font></span></p>
<p><span><font size=2>LPSTARTUPINFO lpsiStartInfo,</font></span></p>
<p><span><font size=2>LPPROCESS_INFORMATION lppiProcInfo</font></span></p>
<p style="TEXT-INDENT: 10.5pt"><span><font size=2>);</font></span></p>
<p><font size=2><span>当应用程序中某个线程调用这个函数时，系统创建了一个引用计数为</span><span>1</span><span>的进程内核对象。该内核对象不是进程，而是操作系统用来管理进程的一小块数据结构。系统然后为新进程创建一个</span><span>4GB</span><span>的虚拟地址空间，把可执行文件和</span><span>DLL</span><span>及数据都装入该地址空间。系统之后为新进程的主线程创建一个使用计数为</span><span>1</span><span>的线程内核对象，之后主线程开始执行</span><span>C</span><span>运行时的启动代码，最终会调用</span><span>WinMain</span><span>函数。如果系统成功地创建了新进程和主线程，</span><span>CreateProcess</span><span>函数返回</span><span>True</span><span>。</span></font></p>
<font size=2><span>
<p><font size=2><span>各个参数说明：</span></font></p>
<p><font size=2><span><strong>lpszCommandLine</strong></span><span>：该参数可以用来指定</span><span>CreateProcess</span><span>用来创建新进程的完整命令行，这个命令行里可以包含&#8220;可执行文件名&#8221;（如果这个可执行文件没有指定扩展名的话，系统会认为其扩展名为</span><span>exe</span><span>）注：可以包含可执行文件名</span><span>+</span><span>这个可执行文件的完整路径，如果未指定完整路径，那么</span><span>CreateProcess</span><span>会以下面的顺序查找可执行文件：</span><span>1.</span><span>含有调用进程的</span><span>Exe</span><span>文件目录</span><span>2</span><span>调用进程的当前目录</span><span>3 Windows</span><span>系统目录</span><span>4Windows</span><span>目录</span><span>5</span><span>列在</span><span>PATH</span><span>环境变量中的目录。如果系统找到了可执行文件，就创建一个进程，把可执行文件的代码和</span><span>DLL</span><span>及数据装入新进程的地址空间。系统然后调用</span><span>C</span><span>运行时的启动例程。之后</span><span>C</span><span>运行时的启动例程会查看进程的命令行，把可执行文件名后的第一个参数地址传递为</span><span>WinMain</span><span>的</span><span>lpszCmdLine</span><span>参数。上面讲述的情况是在参数</span><span>lpszApplicationName</span><span>为</span><span>NULL</span><span>时。</span></font></p>
<p><font size=2><span><strong>lpszApplicationName</strong></span><span>：可执行文件的名称及其扩展名。如果不指定扩展名那么系统将不会认为其扩展名为</span><span>exe</span><span>。如果不指定可执行文件的路径，那么</span><span>CreateProcess</span><span>只在当前目录下查找可执行文件，如果找不到它将返回失败。</span></font></p>
<p><font size=2><span>下面列举一例说明上面讲的两个参数，</span><span>CreateProcess(&#8220;C:WINNTSYSTEM32NOTEPAD.EXE&#8221;,&#8221;WORDPAD README.TXT&#8221;&#8230;..);</span></font></p>
<p><font size=2><span>系统将启动</span><span>NotePad</span><span>，但是</span><span>NotePad</span><span>的命令行是</span><span>WORDPAD README.TXT</span><span>这样写主要是为了支持</span><span>Windows NT</span><span>的</span><span>POSIX</span><span>子系统。</span></font></p>
</span></font>
<img src ="http://www.cppblog.com/aurain/aggbug/116024.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2010-05-21 14:23 <a href="http://www.cppblog.com/aurain/archive/2010/05/21/116024.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows核心编程学习笔记一（内核对象）</title><link>http://www.cppblog.com/aurain/archive/2010/05/21/116022.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Fri, 21 May 2010 06:13:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2010/05/21/116022.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/116022.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2010/05/21/116022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/116022.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/116022.html</trackback:ping><description><![CDATA[<table style="TABLE-LAYOUT: fixed; WIDTH: 100%">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <p><font size=2>1.windows95上部分Win32实际上不可用，如:CreateRemoteThread函数，在Windo</font><font size=2>ws95上调用该函数时返回结果是NULL。(为什么会有部分函数不可用呢？答案：</font><font size=2>为了使Windows95适合4MB的内存的计算机。Windows95具体不支持的Win32有：Wi</font><font size=2>n32的一些异步文件I/O函数、高度函数、注册函数、安全函数和事件记录函数，</font><font size=2>这些函数虽然在Windows95上有，但是它们是有限制地实现的)</font></p>
            <br>
            <p><font size=2><strong><span>2.</span></strong><strong><span>内核对象</span></strong><span>：内核对象的数据结构只能由内核访问，应用程序不能在内存中定位这些数据结构和直接改变它们的内容。</span><span>(</span><span>内核对象通过调用相应的</span><span>Win32</span><span>函数产生</span><span>,</span><span>并返回一个标识该对象的句柄，注：该句柄进程相关。每一个内核对象实际上是由内核分配的一块内存，而只能由内核访问。这块内存就是一块数据结构，它包含的成员是关于该对象的信息。内核对象由内核控制何时释放，而不是由调用它的进程，每一个内核对象的数据中都有一个进程引用计数，当某进行创建了一个内核对象时，该内核对象中的引用计数被置为</span><span>1</span><span>，之后要是有其它进程访问该内核对象时，引用计数加</span><span>1</span><span>，当所有访问内核对象的进程都释放，引用计数为</span><span>0</span><span>时，该内核对象由内核释放</span><span>)</span></font></p>
            <p><font size=2><strong><span>3.</span></strong><strong><span>用户及图形接口对象</span></strong><span>：菜单、窗口、鼠标、光标、刷子、字体等对象。可以使用创建对象的函数来区分哪个是内核对象，哪个是用户及图形接口对象，在内核对象创建函数的参数中大多都有</span><span>LPSECURITY_ATTRIBUTES</span><span>类型的参数，相反用户对象图形接口对象无此类型参数。</span></font></p>
            <p><font size=2><strong><span>4.</span></strong><strong><span>内核对象共享：</span></strong></font></p>
            <p><font size=2><span><strong>(1)</strong></span><strong><span>内核对象的共继承：</span></strong><span>一个子进程继承父进程中</span><span>(</span><span>可继承的</span><span>)</span><span>内核对象。如果父进程想指定某个子进程继承它的内核对象该怎么办呢？可以通过函数</span><span>SetHandleInformation(HANDLE hObject,DWORD dwMask,DWORD dwFlags);</span><span>来实现。</span></font></p>
            <p><font size=2><span>具体方法：</span></font></p>
            <p style="TEXT-INDENT: 21pt"><font size=2><span>1.</span><span>使子进程可以继承父进程的内核对象：</span><span>SetHandleInformation(hObj,HANDLE_F</span></font></p>
            <p style="TEXT-INDENT: 21pt"><font size=2><span>LAG_INHERIT,HANDLE_FLAG_INHERIT);//</span><span>注：这种操作也可以称为打开内核对象</span></font></p>
            <p style="TEXT-INDENT: 21pt"><span><font size=2>句柄继承标志。</font></span></p>
            <p><font size=2><span>2.</span><span>子进程不能继承父进程的内核对象方法：</span><span>SetHandleInformation(hObj,HANDLE</span></font></p>
            <p><font size=2><span>_FLAG_INHERIT,0);//</span><span>注：这个操作也可以称为关闭内核对象继承标志</span></font></p>
            <p style="TEXT-INDENT: 21pt"><span><font size=2>另注：判断某个句柄是否可继承方法：</font></span></p>
            <p style="TEXT-INDENT: 21pt"><span><font size=2>DWORD dwFlags;</font></span></p>
            <p style="TEXT-INDENT: 21pt"><span><font size=2>GetHandleInformation(hObj,&amp;dwFlags);</font></span></p>
            <p style="TEXT-INDENT: 21pt"><span><font size=2>BOOL fHandleIsInheritable = (0!=(dwFlags &amp;HANDLE_FLAG_INHERITABLE));</font></span></p>
            <p style="TEXT-INDENT: 21pt"><font size=2><span>其中函数</span><span>GetHandleInformation(HANDLE hObj,LPDWORD lpdwFlags)</span><span>函数是用来返回当前句柄标志到</span><span>lpdwFlags</span><span>指向的</span><span>DWORD</span><span>中。</span></font></p>
            <p><font size=2><span><strong>(2)</strong></span><strong><span>命名对象</span></strong><span>：使用下列函数可以创建一个命名的内核对象，</span></font></p>
            <p><span><font size=2>HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpszName); </font></span></p>
            <p><span><font size=2>HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCTSTR lpszName);</font></span></p>
            <p><span><font size=2>HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCTSTR lpszName);</font></span></p>
            <p><span><font size=2>HANDLE CreateWaitableTimer(LPSECURITY_ATTRIBUTES lpTimerAttributes,BOOL bManualReset,LPCTSTR lpszName);</font></span></p>
            <p><span><font size=2>HANDLE CreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCTSTR lpszName);</font></span></p>
            <p><font size=2><span>当这些函数的最后一个参数</span><span>lpszName</span><span>为</span><span>NULL</span><span>时，系统将创建一个无名的内核对象。创建的无名对象，可以通过继承和复制来实现在进程间共享内核对象。</span><span>lpszName</span><span>参数：它的最大长度为</span><span>MAX_PATH(260</span><span>个字符</span><span>)</span><span>，且不能包含左斜杠</span><span>。</span></font></p>
            <p><font size=2><span>小常识：</span> <span>得到执行错误信息可以通过函数</span><span>GetLastError();</span></font></p>
            <p><font size=2><span>例如：</span><span>DWORD dwErrorCode = GetLastError();</span></font></p>
            <p><font size=2><span>那么如何使用&#8220;命名的内核对象来共享内核对象呢？&#8221;</span></font></p>
            <p><font size=2><span>方法及理论实质：通过具体例子说明，假设进程</span><span>A</span><span>创建一个内核对象：</span></font></p>
            <p><font size=2><span>HANDLE hMutexProcessA = CreateMutex(NULL,FALSE,"UUXAMutex");</span><span>之后进程</span><span>B</span><span>也同样：</span><span>HANDLE hMutexProcessB = CreateMutex(NULL,FALSE,"UUXAMutex");</span><span>创建了一个与进程</span><span>A</span><span>相同的内核对象，那么结果进程</span><span>B</span><span>是否成功创建内核对象了呢？系统是这样处理这种情况的，首先系统检查是否存在一个名称为</span><span>"UUXAMutex"</span><span>的内核对象，经检查后呢，发现已经存在内核对象</span><span>"UUXAMutex"</span><span>，之后检查内核对象类型，由于进程</span><span>A</span><span>和</span><span>B</span><span>创建的内核对象类型都是&#8220;互斥量&#8221;，所以系统就认为进程</span><span>B</span><span>对</span><span>CreateMutex</span><span>的调用成功了。系统在进程</span><span>B</span><span>的句柄表中找到一个空表项，然后初始化该表项指向已经存在的内核对象。</span></font></p>
            <p><font size=2><span>判断一个进程是否真正的创建了一个新的内核对象可以使用</span><span>GetLastError</span><span>来判断。</span></font></p>
            <p><span><font size=2>HANDLE hMutex = CreateMutex(NULL,FALSE,"SomeMutex");</font></span></p>
            <p><span><font size=2>if (GetLastError() == ERROR_ALREADY_EXISTS) {</font></span></p>
            <p><span><font size=2>}else{};</font></span></p>
            <p><font size=2><span><strong>(3)</strong></span><strong><span>复制对象句柄</span></strong><span>：通过函数</span><span>BOOL DuplicateHandle(HANDLE hSourceProcessHandle,HANDLE hSourceHandle,HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,DWORD dwDesireAccess,BOOL bInheritHandle,DWORD dwOptions);</span></font></p>
            <p><font size=2><span>参数：</span><span>dwOptions</span><span>可以是</span><span>0</span><span>或是</span><span>DUPLICATE_SAME_ACCESS</span><span>和</span><span>DUPLICATE_CLOSE_SOURCE</span></font></p>
            <p><font size=2><span>举例：如果进程</span><span>A</span><span>想让进程</span><span>B</span><span>得到自己能够访问的一个内核对象的访问权限，那么该如何做呢？如下所示：</span></font></p>
            <p><span><font size=2>HANDLE hObjProcessA = CreateMutex(NULL,FALSE,NULL);</font></span></p>
            <p><span><font size=2>HANDLE hProcessB = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessIdB);</font></span></p>
            <p><span><font size=2>HANDLE hObjProcessB;</font></span></p>
            <p><span><font size=2>DuplicateHandle(GetCurrentProcess(),hObjProcessA,hProcessB,&amp;hObjProcessB,0,FALSE,DUPLICATE_SAME_ACCESS);</font></span></p>
            <p><span><font size=2>CloseHandle(hProcessB);</font></span></p>
            <p><span><font size=2>CloseHandle(hObjProcessA);</font></span></p>
            <p>&nbsp;</p>
            <p><span><font size=2>来自：<a href="http://uuxa.itpub.net/"><u><font color=#0000ff>http://uuxa.itpub.net/</font></u></a></font></span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/aurain/aggbug/116022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2010-05-21 14:13 <a href="http://www.cppblog.com/aurain/archive/2010/05/21/116022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：如何删除windows服务(regedit进入注册表) </title><link>http://www.cppblog.com/aurain/archive/2009/08/17/93547.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 17 Aug 2009 01:15:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/08/17/93547.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/93547.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/08/17/93547.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/93547.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/93547.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如果你要卸载一个本地服务，可以通过命令行输入如下命令<br>                       sc delete ServiceName<br>或者在直接修改注册表<br>                       在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 中删除相应的键值.&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2009/08/17/93547.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/93547.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-08-17 09:15 <a href="http://www.cppblog.com/aurain/archive/2009/08/17/93547.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JIURL PE 格式学习总结（四）-- PE文件中的资源</title><link>http://www.cppblog.com/aurain/archive/2009/06/29/88771.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 29 Jun 2009 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/06/29/88771.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/88771.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/06/29/88771.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/88771.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/88771.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JIURL PE 格式学习总结（四）-- PE文件中的资源&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2009/06/29/88771.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/88771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-06-29 14:07 <a href="http://www.cppblog.com/aurain/archive/2009/06/29/88771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JIURL PE 格式学习总结（三）-- PE文件中的输入函数</title><link>http://www.cppblog.com/aurain/archive/2009/06/29/88770.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 29 Jun 2009 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/06/29/88770.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/88770.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/06/29/88770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/88770.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/88770.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JIURL PE 格式学习总结（三）-- PE文件中的输入函数&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2009/06/29/88770.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/88770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-06-29 13:56 <a href="http://www.cppblog.com/aurain/archive/2009/06/29/88770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JIURL PE 格式学习总结（二）-- PE文件中的输出函数</title><link>http://www.cppblog.com/aurain/archive/2009/06/29/88767.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 29 Jun 2009 05:48:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/06/29/88767.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/88767.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/06/29/88767.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/88767.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/88767.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JIURL PE 格式学习总结（二）-- PE文件中的输出函数&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2009/06/29/88767.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/88767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-06-29 13:48 <a href="http://www.cppblog.com/aurain/archive/2009/06/29/88767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JIURL PE 格式学习总结（一）--PE文件概述</title><link>http://www.cppblog.com/aurain/archive/2009/06/29/88766.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Mon, 29 Jun 2009 05:45:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/06/29/88766.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/88766.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/06/29/88766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/88766.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/88766.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JIURL PE 格式学习总结（一）--PE文件概述&nbsp;&nbsp;<a href='http://www.cppblog.com/aurain/archive/2009/06/29/88766.html'>阅读全文</a><img src ="http://www.cppblog.com/aurain/aggbug/88766.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-06-29 13:45 <a href="http://www.cppblog.com/aurain/archive/2009/06/29/88766.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CreateService参数介绍</title><link>http://www.cppblog.com/aurain/archive/2009/04/08/79259.html</link><dc:creator>水</dc:creator><author>水</author><pubDate>Wed, 08 Apr 2009 05:51:00 GMT</pubDate><guid>http://www.cppblog.com/aurain/archive/2009/04/08/79259.html</guid><wfw:comment>http://www.cppblog.com/aurain/comments/79259.html</wfw:comment><comments>http://www.cppblog.com/aurain/archive/2009/04/08/79259.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/aurain/comments/commentRss/79259.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aurain/services/trackbacks/79259.html</trackback:ping><description><![CDATA[SC_HANDLE CreateService(&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>SC_HANDLE hSCManager, //服务控制管理程序维护的登记数据库的句柄，由系统函数OpenSCManager 返回&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpServiceName, //以NULL 结尾的服务名，用于创建登记数据库中的关键字&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpDisplayName, //以NULL 结尾的服务名，用于用户界面标识服务&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>DWORD dwDesiredAccess, //指定服务返回类型&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>DWORD dwServiceType, //指定服务类型&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>DWORD dwStartType, //指定何时启动服务&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>DWORD dwErrorControl, //指定服务启动失败的严重程度&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpBinaryPathName, //指定服务程序二进制文件的路径&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpLoadOrderGroup, //指定顺序装入的服务组名&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPDWORD lpdwTagId, //忽略，NULL&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpDependencies, //指定启动该服务前必须先启动的服务或服务组&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpServiceStartName, //以NULL 结尾的字符串，指定服务帐号。如是NULL,则表示使用LocalSystem 帐号&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>LPCTSTR lpPassword //以NULL 结尾的字符串，指定对应的口令。为NULL表示无口令。但使用LocalSystem时填NULL&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>); <br><br>其中dwStartType取值类型如下：<br>共有五种启动类型。前三种类型是：SERVICE_AUTO_START、SERVICE_DISABLED &nbsp; 和 &nbsp; SERVICE_DEMAND_START。对应的标准启动类型：自动、禁用和手动，通常使用&#8220;计算机管理&#8221;管理工具中的&#8220;服务&#8221;进行配置。后两种类型是：SERVICE_BOOT_START &nbsp; 和 &nbsp; SERVICE_SYSTEM_START，通常用于配置加载设备驱动程序的方式。例如，在启动计算机时或启动 &nbsp; Windows &nbsp; 2000 &nbsp; 时加载。&nbsp;&nbsp; 
<img src ="http://www.cppblog.com/aurain/aggbug/79259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aurain/" target="_blank">水</a> 2009-04-08 13:51 <a href="http://www.cppblog.com/aurain/archive/2009/04/08/79259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>