核心编程随笔2 分类: VC++ 2013-0...

Note 1:
以前版本的Windows设计的一些应用程序之所以在Windows Vista上不能正常工作,就是因为在实现这些程序时,没有充分考虑安全性.假定一个应用程序在启动时要从一个注册表子项中读取一些数据.正确的做法是调用RegOpenKeyEx,向其传入KEY_QUERY_VALUE,从而指定查询子项数据的权限.然而许多应用程序对安全性没有任何考虑.有的软件开发人员还是按照老习惯,在调用RegOpenKeyEx函数的时候,传入KEY_ALL_ACCESS作为期望的访问权限.这样做的问题在于,对于一个不是管理员的标准用户,注册表项(比如HKLM)也许是只读的.所以,当这样的应用程序在Windows Vista上面运行时,调用RegOpenKeyEx函数并传递KEY_ALL_ACCESS就会失败.

Note 2:
不同进程中运行的线程需要共享内核对象.下面罗列了一些理由.

利用文件映射对象,可以在同一台机器上运行的两个不同进程之间共享数据块.
借助mailslots和named pipes,在网络中的不同计算机上运行的进程可以相互发送数据块.
mutexes、semaphores和事件允许不同进程中的线程同步执行.例如,一个应用程序可能需要在完成某个任务之后,向另一个应用程序发出通知.
用三种不同的机制来允许进程共享内核对象:使用对象句柄继承,为对象命名,以及复制对象句柄;

Note 3:
如果你写的一个服务要同这些应用程序通信,就不能假定它和用户应用程序在同一个会话中运行.要想更多地了解Session0隔离问题,及其对服务开发人员的影响,请阅读"Impact of Session 0 Isolation on Services and Drivers in Windows Vista"一文,网址是http://www.microsoft.com/whdc/system/vista/services.mspx.

Note 4:

复制对象句柄的函数:
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
PHANDLE phTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions);
(hyp:这个一个可以用来做很多邪恶事情的函数,比如你可以打开一个文件然后把句柄复制到系统进程里面,这样子文件就删不掉了)

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

Note 6:
进程要做任何事情,都必须让一个线程在它的上下文中运行.该线程要执行进程地址空间包含的代码.一个进程可以有多个线程,所有线程都在进程的地址空间中"同时"执行代码.因此每个线程都有它自己的一组CPU寄存器和它自己的堆栈.每个进程至少要有一个线程执行进程地址空间包含的代码.一个进程创建的时候,系统会自动创建它的第一个线程,这称为主线程(primary thread).然后这个线程再创建更多的线程,如果没有线程要执行进程地址空间包含的代码,进程就失去了继续存在的理由.所以,系统会自动销毁进程及其地址空间.(hyp:所以结束一个进程的所有线程将会导致进程被结束)

Note 7:
如果你的代码在一个DLL中,那么可利用两个办法来了解代码正在什么模块中运行:
第一个办法是利用链接器提供的伪变量__ImageBase,它指向当前正在运行的模块的基地址.
第二个办法是调用GetModuleHandleEx,将GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS作为它的第一个参数,将当前方法的地址作为第二个参数.最后一个参数是指向一个HMODULE的指针,该指针将由GetModuleHandleEx来填充,它就是包含了传入函数的那个DLL的基地址.
以下代码对这两个办法都进行了演示:
extern "C" const IMAGE_DOS_HEADER __ImageBase;
void DumpModule() {
// Get the base address of the running application.
// Can be different from the running module if this code is in a DLL.
HMODULE hModule = GetModuleHandle(NULL);
_tprintf(TEXT("with GetModuleHandle(NULL) = 0x%x\r\n"), hModule);
// Use the pseudo-variable __ImageBase to get
// the address of the current module hModule/hInstance.
_tprintf(TEXT("with __ImageBase = 0x%x\r\n"), (HINSTANCE)&__ImageBase);
// Pass the address of the current method DumpModule
// as parameter to GetModuleHandleEx to get the address
// of the current module hModule/hInstance.
hModule = NULL;
GetModuleHandleEx(
   GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
   (PCTSTR)DumpModule,
   &hModule);
_tprintf(TEXT("with GetModuleHandleEx = 0x%x\r\n"), hModule);
}
int _tmain(int argc, TCHAR* argv[]) {
DumpModule();
return(0);
}
Note 8:
调用GetCommandLine函数可以获得一个指向进程完整命令行的指针.
应用程序可以使用全局变量__argc和__argv(或__wargv)来访问对命令行的各个单独的组件,不过这些变量现在已经不提倡使用了.
利用在ShellAPI.h文件中声明并由Shell32.dll导出的函数CommandLineToArgvW可以将任何Unicode字符串分解成单独的标记:
PWSTR* CommandLineToArgvW(
PWSTR pszCmdLine,
int* pNumArgs);
CommandLineToArgvW在内部分配内存.许多应用程序不会释放这个内存——它们指望操作系统在进程终止时释放内存.这是完全可以接受的.不过,如果你想自己释放内存,正确的做法就是像下面这样调用HeapFree:
int nNumArgs;
PWSTR *ppArgv = CommandLineToArgvW(GetCommandLineW(), &nNumArgs);
// Use the arguments…
if (*ppArgv[1] == L'x') {
...
}
// Free the memory block
HeapFree(GetProcessHeap(), 0, ppArgv);
Note 9:
每个进程都有一个与它关联的环境块(environment block).这是在进程地址空间内分配的一个内存块.其中包含和下面相似的一组字符串:
=::=::\ ...
VarName1=VarValue1\0
VarName2=VarValue2\0
VarName3=VarValue3\0 ...
VarNameX=VarValueX\0
\0
每个字符串的第一部分是一个环境变量的名称,后跟一个等号,等号之后是希望赋给此变量的值.
注意,除了第一个=::=::\字符串,块中可能还有其他字符串是以等号(=)开头的.

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/mao0504/p/4706780.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中提供的代码,可以使用toUnixTimestamp函数将日期对象转换为Unix时间戳。根据引用中的说明,刷新间隔时间是指从服务器检查域数据文件是否需要更新的时间间隔。根据引用中的示例,可以将域数据文件复制到指定的目录下。根据您提供的时间戳"2023-09-03T08:38:43.548 00:00",您可以使用toUnixTimestamp函数将其转换为Unix时间戳。请注意,时间戳应该是一个数字,表示从Unix纪元(1970年1月1日)开始的秒数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [to-unix-timestamp:将日期转换为Unix时间戳](https://download.csdn.net/download/weixin_42160425/18164877)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Linux随笔16-主从DNS服务搭建以及智能DNS服务搭建、基于CentOS7.6编译安装MySQL-5.7.32](https://blog.csdn.net/ikkyphoenix/article/details/118445272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值