windows核心编程1-4笔记

来源:互联网 发布:node.js实战pdf 编辑:程序博客网 时间:2024/05/18 01:23
DBCS。在双字节字符集中,一个字符串中的每个字符都由1个或2个字节组成。


typedef char CHAR;
typedef wchar_t WCHAR;
//////////////
typedef CHAR *PCHAR;
typedef CHAR *PSTR;
typedef CONST CHAR *PCSTR;


typedef WCHAR *PWCHAR;
typedef WCHAR *PWSTR;
typedef CONST WCHAR *PCWSTR;


//////////////////////


#ifdef UNICODE
typedef WCHAR TCHAR, *PTCHAR, PTSTR;
typedef CONST WCHAR *PCTSTR;
#else
typedef CHAR TCHAR, *PTCHAR, PTSTR;
typedef CONST CHAR * PCTSTR;
#endif


在使用WinExec和OpenFile调用的地方,应该用CreateProcess和CreateFile函数调用来代替。
所有需要字符串作为参数的COM接口方法都只接受Unicode字符串。
#ifdef _UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif


最好定义一个宏:
#define chmalloc(nCharacters) (TCHAR *)malloc(nCharacters * sizeof(TCHAR))


UNICODE和_UNICODE符号要么同时指定,要么都不指定。


ANSI,UNICODE,UTF-8相互转换时用到MultiByteToWideChar,WideCharToMultiByte函数,只有UNICODE是宽字节,代码页用来指示多字节的编码方式。


为了增强操作系统的可靠性,这些句柄值是与进程相关的。所以,如果将句柄值传给另一个进程中的线程,那么另一个进程用我们的进程的句柄值来发出调用时,就可能失败。


很难区别用户/GDI对象和内核对象,最简单的方式是查看创建这个对象的函数是否允许我们指定安全属性信息的参数。


一个进程在初始化时,系统将为它分配一个句柄表。这个句柄表仅供内核对象使用,不适用于用户对象或GDI对象。
由于句柄值实际是作为进程句柄表的索引来使用的,所有这些句柄是与当前这个进程相关的,无法供其他进程使用。


无论以什么方式创建内核对象,我们都要调用CloseHandle向系统表明我们已经结束使用对象。


内核对象的内容被保存在内核地址空间中,系统上运行的所有进程都共享这个空间。对于32位系统,这是0x80000000到0xffffffff之间的内存空间。对于64位系统,则是0x00000400'00000000到0xffffffff'ffffffff之间的内存空间。


共享内核对象
1.只有在进程之间有一个父子关系的时候,才可以使用对象句柄继承。
可以调用SetHandleInformation函数来改变内核对象句柄的继承标志。
GetHandleInformation
2.可以用命名对象的方法。许多(但不是全部)内核对象都可以进行命名。
3.最后一招是DuplicateHandle函数。


一般将进程定义成一个正在运行的一个实例,它由以下两部分构成:
1.一个内核对象,操作系统用它来管理进程。内核对象也是系统保存进程统计信息的地方。
2.一个地址空间,其中包含所有可执行文件或DLL模块的代码和数据。此外,它还包含动态内存分配,比如线程堆栈和堆的分配。


操作系统实际并不调用我们所写的入口点函数。相反,它会调用由C/C++运行库实现并在链接时使用-entry:命令行选项来设置的一个C/C++运行时启动函数。该函数将初始化C/C++运行库,使我们能调用malloc和free之类的函数。它还确保了在我们的代码开始执行之前,我们声明的任何全局和静态C++对象都被正确地构造。


我们完全可以从自己的项目中移除/subsystem链接器开关。一旦这样做,链接器就会自动判断应该将应用程序设为哪一个子系统。链接时,链接器会检查代码中包括4个函数中的哪一个(WinMain,wWinMain,main,wmain),并据此推算可执行文件应该是哪个子系统,以及应该在可执行文件中嵌入哪个C/C++启动函数。


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


DWORD GetModuleFileName(HMODULE hInstModule, PTSTR pszPath, DWORD cchPath);
HMODULE GetModuleHandle(PCTSTR pszModule);若参数为NULL,则值回可执行文件的基地址,即使调用这个函数的代码在一个DLL文件中。
使用Microsoft链接器的/BASE:address链接器开关,可以更改要将应用程序加载到哪个基地址。
如果主调进程没有使用任何通用对话框函数,那么一旦调用GetModuleHandle,并向其传递ComDlg32,就会导致返回NULL--即使ComDlg32.dll也许已经加载到其他进程的地址空间。


GetEnvironmentStrings() FreeEnvironmentStrings()
GetEnvironmentVariable() SetEnvironmentVariable()
GetCurrentDirectory() SetCurrentDirectory()
系统在内部跟踪记录着一个进程的当前驱动器和目录,这种信息是以进程为单位来维护的。
GetCurrentProcessId(),GetCurrentThreadId(),GetProcessId(),GetThreadId().
CreateProcess函数的fdwCreate参数可以有的标志有DEBUG_PROCESS,CREATE_SUSPENDED,CREATE_NO_WINDOW等。
ExitProcess造成进程“当场终止运行”:C/C++运行时没有机会执行清理工作。
当一个进程使用提升后的权限启动时,它每次用CreateProcess来生成另一个进程时,子进程都会获得和它的父进程一样的提后的权限。



自动提升进程的权限,manifest
手动提升进程的权限,ShellExecuteEx,runas


0 0