zoukankan      html  css  js  c++  java
  • 《Windows核心编程》学习笔记(3)– 程序入口函数

    1 进程实例句柄

    加载到进程地址空间的每一个可执行文件或者dll文件都被赋予了一个独一无二的实例句柄.

    他实际上是一个内存基地址,系统将可执行程序的映像加载到进程地址空间中的这个位置。

    Ps :

    HMODULE HINSTANCE

    其实就是一回事.

     

    获得一个可执行文件或者dll文件的句柄/基地址:

    1GetModuleHandle函数

    HMODULE GetModuleHandle( LPCTSTR lpModuleName );

    调用这个函数时,参数指定了已在主调进程的地址空间中加载的一个可执行文件或者DLL文件的名称。或者参数为NULL时,会返回主调函数的可执行文件的基地址

     

    (2)GetModuleHandleEx 函数

            BOOL WINAPI GetModuleHandleEx(

            __in          DWORD dwFlags,

            __in          LPCTSTR lpModuleName,

            __out         HMODULE* phModule

            );

    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为他的第一个参数,将当前函数的地址作为第二个参数,最后一个参数是一个指向HMODULE的指针,GetModuleHandleEx函数会用传入函数(既第二个参数)所在DLL的基地址来填写该指针.

     

    3)利用链接器提供的为变量__ImageBase,他指向当前正在运行的模块的基地址.

    例如:

    #include<windows.h>

    #include<tchar.h>

    #include<stdio.h>

    extern "C" const IMAGE_DOS_HEADER  __ImageBase;

    void DumpModule()

    {

           HMODULE hModule = GetModuleHandle( NULL );

           _tprintf( TEXT( "with GetModuleHandle(NULL) = 0x%x\r\n" ),hModule );

     

           _tprintf( TEXT( "with __ImageBase = 0x%x\r\n" ),( HINSTANCE )&__ImageBase );

     

           hModule = NULL;

           GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,

                  (PCTSTR)DumpModule,

                  &hModule);

           printf("with GetModuleHandleEx = 0x%x\r\n", hModule);

    }

    int main( int argc, char* argv[] )

    {

           DumpModule();

           system("pause");

           return 0;

    }

    ps:当调用GetModuleHandle函数,并向其传递NULL值,会返回进程的地址空间中的可执行文件的基地址。所以,即使调用GetModuleHandleNULL)的代码是一个DLL文件中,返回值仍是可执行文件的基地址,而非DLL文件的基地址。

     

    2.进程前一个实例的句柄

    该参数用于16Windows系统,仍然将其保留为WinMain的一个参数,目的只是方便我们移植到16Windows应用程序.

     

    3.进程的环境变量  

    每个进程都有一个与它关联的环境块(environment block,这是在进程地址空间内分配的一个 内存块,其中包含和下面相似的一组字符串: (可以使用GetEnvironmentStrings函数获得)

    =::=::\ ... 

    VarName1=VarValue1\0 

    VarName2=VarValue2\0 

    VarName3=VarValue3\0 ... 

    VarNameX=VarValueX\0 

    \0 

    (1)可以使用

    GetEnvironmentVariable 函数来判断一个环境变量是否存在;如果存在,它的值是什么。如下 

    所示: 

    DWORD GetEnvironmentVariable( 

       PCTSTR pszName, 

       PTSTR pszValue, 

       DWORD cchValue); 

    调用GetEnvironmentVariable时,pszName指向预期的变量名称,pszValue指向保存变量值的缓冲区,而 cchValue指出缓冲区大小(用字符数来表示)。如果在环境中找到变量名,GetEnvironmentVariable函数将返回复制到缓冲区的字符数;如果在环境中没有找到变量名, 就返回0。然而,由于我们不知道为了保存一个环境变量的值需要多少个字符,所以当0值被当 cchValue参数的值传入时,GetEnvironmentVariable会返回包括末尾的NULL字符在内的字符的数量。以下代码演示了如何安全地使用这个函数: 

    void PrintEnvironmentVariable(PCTSTR pszVariableName) { 

       PTSTR pszValue = NULL; 

       // 先获得环境变量中的字符数

      DWORD dwResult = GetEnvironmentVariable(pszVariableName, pszValue, 0); 

       if (dwResult != 0) { 

         // 为环境变量分配足够的内存,并获得环境变量的值

         DWORD size = dwResult * sizeof(TCHAR); 

         pszValue = (PTSTR)malloc(size); 

         GetEnvironmentVariable(pszVariableName, pszValue, size); 

         _tprintf(TEXT("%s=%s\n"), pszVariableName, pszValue); 

         free(pszValue); 

       } else { 

         _tprintf(TEXT("'%s'=<unknown value>\n"), pszVariableName); 

       } 

     

    (2)可以使用 ExpandEnvironmentStrings 函数来展开一个环境变量 ,: %USERPROFILE%\Documents   在我的机器上

    USERPROFILE环境变量值为C:\Users\mzf,因此替换后的字符串为:

    C:\Users\mzf

    \Documents

    DWORD ExpandEnvironmentStrings

       PTCSTR pszSrc, 

       PTSTR pszDst, 

      DWORD chSize); 

    调用这个函数时,pszSrc参数是包含可替换环境变量字符串的一个字符串的地址。pszDst 参数是用于接收扩展字符串的一个缓冲区的地址,而chSize参数是这个缓冲区的最大大小(用字符数来表示)。返回值是保存扩展字符串所需的缓冲区的大小(用字符数来表示)。如果chSize 参数小于此值,%%变量就不会扩展,而是被空字符串替换。所以,通常要调用两次 ExpandEnvironmentStrings 函数,如下所示: 

    DWORD chValue = 

      ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), NULL, 0); 

    PTSTR pszBuffer = new TCHAR[chValue]; 

    chValue = ExpandEnvironmentStrings(TEXT("PATH='%PATH%'"), pszBuffer, chValue); 

    _tprintf(TEXT("%s\r\n"), pszBuffer); 

    delete[] pszBuffer; 

     

    (3)使用SetEnvironmentVariable函数添加一个变量,删除一个变量,或者修改一个变 

    量的值: 

    BOOL SetEnvironmentVariable( 

       PCTSTR pszName, 

       PCTSTR pszValue); 

     

    此函数将pszName所标识的一个变量设为pszValue参数所标识的值。如果已经存在具有指定名称的一个变量,SetEnvironmentVariable函数会修改它的值。如果指定的变量不存在,就添加这个变量。如果pszValueNULL,变量会从环境块中删除.

  • 相关阅读:
    excel多个工作表数据快速合并到一个工作表方法
    客商申请单客商编码自动编码
    如何实现Excel多人共享与协作
    商家推销技巧-将广告做成实用信息
    如何实现扫码填报信息
    DBSync如何连接并同步MySQL
    如何在微信中发布动态信息
    一款数据库比较与同步软件的设计与实现
    【原创】在 ASP.NET Core 3.1 中使用 Senparc.Weixin.Work 企业微信 SDK —— 发送文本消息
    【原创】在 .NET Core 3.1 中使用 Senparc.Weixin.Work 企业微信 SDK —— 发送文本消息
  • 原文地址:https://www.cnblogs.com/forlina/p/2131105.html
Copyright © 2011-2022 走看看