mysql版本wow64平台_WOW64最佳实现

article/2025/9/26 8:34:34

WOW64简介

WOW64(Windows 32-bit On Windows 64-bit)是x64平台上运行win32应用程序的模拟器,它在系统层提供了中间层,将win32的系统调用转换成x64进行调用,并且将x64返回的结果转换成win32形式返回给win32程序。下图描述了win32程序如何在x64系统上运行的。

acf43755a042

How a 32-bit process runs on 64-bit Windows

WOW64局限性:

地址空间默认是2G,使用/LARGEADDRESSAWARE开关可以达到4G。

32位进程无法加载64位DLL(除了指定的系统DLL)。

不支持16位进程的运行。

无法使用DOS虚拟机(VDM, Vitrual DOS Machine)。

Intel安腾系列处理器不支持 AWE, Vectored I/O, PAE 以及DirectX硬件加速API。

注册表机制

众所周知,注册表是windows系统的数据库,系统本身以及安装的程序都依赖注册表。当Windows进化到64位,还要兼容大量的32位应用程序,便碰到了注册表冲突的问题。

注册表树最大可以有512级深度,通过注册表API一次可以创建32级深的键值。

为了解决64位系统的兼容性问题,Windows使用了三套方案,共享(Shared)、注册表重定向(Registry Redirector)和注册表反射(Registry Reflection)。

1. 共享

保存可以被32位和64位共同使用的注册表。

2. 注册表反射

注册表反射是在64位注册表视图和32位注册表视图之间复制某些特定的注册表项和项值。简单的说就是备份和同步,把同一份注册表保存到两个物理位置,分别被32位或64位程序使用。保存发生在RegCloseKey调用结束。

使用RegDisableReflectionKey和RegEnableReflectionKey方法可以禁用/启用反射机制。

该方案只用于Windows Server 2008, Windows Vista, Windows Server 2003 和 Windows XP,从 Windows 7 和 Windows Server 2008 R2 开始被移除。

举例:在X64系统中安装64位Microsoft Office后,64位的winword.exe将注册.doc这个扩展名并把这个扩展名关联到winword.exe程序,根据X64的运行机制,64位程序修改的是64位的注册表键值,但是WOW64会自动的把这个修改会同步到32位的注册表键下面,这样32位和64位的应用程序都可以使用64位winword.exe打开.doc文件。

但是,并不是所有的键值都会受到注册表反射机制的影响。实验证明,如果我们使用32位的注册表编辑器在HKEY_LOCAL_MACHINE/Software下新建一个项,然后使用64位的注册表编辑器查看,会发现这个项只会出现在HKEY_LOCAL_MACHINE/Software/Wow6432Node键下而不会出现在HKEY_LOCAL_MACHINE/Software键下,因为HKEY_LOCAL_MACHINE/Software键是专门用于存放64位程序所使用的注册表数据的,而HKEY_LOCAL_MACHINE/Software/Wow6432Node键是专门用于存放32位程序所使用的注册表数据的。

注册表中受到反射机制影响的有:

HKEY_LOCAL_MACHINE/Software/Classes

HKEY_LOCAL_MACHINE/Software/COM3

HKEY_LOCAL_MACHINE/Software/EventSystem

HKEY_LOCAL_MACHINE/Software/Ole

HKEY_LOCAL_MACHINE/Software/Rpc

HKEY_USERS/*/Software/Classes

HKEY_USERS/*_Classes

3. 注册表重定向

注册表重定向为32位和64位程序分别提供不同的注册表物理存储位置,但会映射成同一个逻辑视图,这个过程对程序本身是透明的。也就是说,一个32位程序可以像在32位系统中一样来使用注册表,虽然它们在64位系统上被存储在不同的物理位置。

32位程序重定向的注册表存放在Wow6432Node下,例如, HKEY_LOCAL_MACHINE\Software 会被重定向到 HKEY_LOCAL_MACHINE\Software\Wow6432Node。

需要重定向的注册表项如下所示:

// 64位程序的注册信息存储键

HKLM/Software

HKEY_CLASSES_ROOT

HKEY_CURRENT_USER/Software/Classes

HKEY_LOCAL_MACHINE/Software

HKEY_USERS/*/Software/Classes

HKEY_USERS/*_Classes

//32位程序的注册信息重定向存储键

HKLM/Software/WOW6432node

HKEY_CLASSES_ROOT/WOW6432node

HKEY_CURRENT_USER/Software/Classes/WOW6432node

HKEY_LOCAL_MACHINE/Software/WOW6432node

HKEY_USERS/*/Software/Classes/WOW6432node

HKEY_USERS/*_Classes/WOW6432node

注册表重定向机制对系统的影响

下列程序调用没有问题:

32位应用程序A调用32位应用程序B并访问B的注册表信息。由于注册表重定向机制,32位应用程序B的注册信息在HKLM/Software/Wow6432Node中,而32位应用程序A访问注册表也会被重定向到HKLM/Software/Wow6432Node中,所以访问正常。

64位应用程序A调用64位应用程序B并访问B的注册表信息。64位应用程序B的注册信息在HKLM/Software,64位应用程序A访问注册表时直接访问HKLM/Software,所以访问正常。

在下列情况时会出现问题:

64位应用程序调用32位应用程序并访问其注册表信息。因为32位应用程序的注册信息在HKLM/Software/Wow6432Node中,而64位应用程序访问注册表时直接范围HKLM/Software,所以访问异常。

解决方案:在写注册表时,32位应用程序要将该注册信息写到64位程序的注册表项中,即HKLM/Software下。

32位应用程序调用64位应用程序并访问其注册表信息。同上。

应用程序如何访问注册表

下面对32位与64位应用程序分别访问注册表进行简单总结:

64位程序如何访问64位的注册表(HKLM/Software)

64位程序访问64位的注册表,直接到 HKLM/Software。

32位程序如何访问32位的注册表(HKLM/Software/Wow6432Node)

32位程序访问32位的注册表,WOW64将会截取对HKLM/Software访问,并重定向到HKLM/Software/Wow6432Node。

32位程序如何访问64位的注册表(HKLM/Software)

在调用函数RegCreateKeyEx创建注册表项时,对第六个参数REGSAM samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现对64位注册表的访问;

在调用函数RegOpenKeyEx打开注册表项时,对第四个参数REGSAM samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现对64位注册表的访问;

64位程序如何访问32位的注册表(HKLM/Software/Wow6432Node)

在调用函数RegCreateKeyEx创建注册表项时,对第六个参数REGSAM samDesired设置中添加参数KEY_WOW64_32KEY,这样可以实现对32位注册表的访问;

在调用函数RegOpenKeyEx打开注册表项时,对第四个参数REGSAM samDesired设置中添加参数KEY_WOW64_32KEY,这样可以实现对32位注册表的访问;

文件系统重定向

与注册表类似,系统为了解决文件冲突的问题,引入了文件系统重定向的机制,文件系统重定向使32位程序和64位程序的文件与数据分开存放,%systemroot%/system32 目录被保留给64位文件使用,而32位文件会被重定向到%systemroot%/SysWOW64目录。任何32位程序试图访问%systemroot%/system32 目录都会被重定向到%systemroot%/SysWOW64目录。这是系统默认行为,除非程序的线程明确的指明需要关闭文件系统重定向机制。

文件系统重定向开关

针对%windir%\system32,如果我们用32位程序去访问%windir%\system32,不管我们用硬编码还是其它的方式,系统都会自动地给我们转向到%windir%\syswow64目录。这种转向对于每个32位应用程序默认都是打开的,但是这种转向并不总是需要的。因此,系统提供了相关的API来控制文件重定向的打开与关闭。常用的函数有3个,如下所示

注意:Wow64EnableWow64FsRedirection在嵌套使用的时候不可靠,所以通常用上面的 Wow64RevertWow64FsRedirection来打开文件系统转向功能。

文件与变量的引用

应用程序必须确保对文件名与变量(包括系统变量,环境变量,系统特殊路径等)的引用适用于当前的操作系统,否则会引起如下问题:

有些变量只适用于64位操作系统,比如:%ProgramW6432%和FOLDERID_ProgramFilesX64。

有些变量只适用于32位操作系统,比如:%windir%\Sysnative。

有些变量在不同位数的操作系统下数值不同,比如:%ProgramFiles%和FOLDERID_ProgramFiles。

注意:我们在使用上述变量时必须先判定当前系统的位数信息以确保引用正确。

同理,注册表信息中包含环境变量时也会出现类似问题。比如REG_EXPAND_SZ指向包含环境变量的注册表信息,系统会自动解析键值中包含的%xxx%环境变量。而REG_SZ键值中的%xxx%不会被自动解析。但是可以通过ExpandEnvironmentStrings等系统API进行扩展。当程序调用RegGetValue获取注册表键值的时候,系统会根据当前操作系统的位数信息对环境变量进行扩展,但是应用程序也可以覆盖这种扩展方式。

因此,在64位操作系统中我们要避免使用32位和64位系统不通用的变量,比如:

%ProgramFiles%, FOLDERID_ProgramFiles(CSIDL_PROGRAM_FILES), FOLDERID_ProgramFilesCommon(CSIDL_PROGRAM_FILES_COMMON)

FOLDERID_ProgramFilesX64, FOLDERID_ProgramFilesCommonX64

下面对上述的文件与变量的引用以及文件目录重定向进行简单总结。

acf43755a042

Summary of Rules for Referencing Files and Variables

acf43755a042

Summary of Defaults for Variables and Paths

应用程序安装与启动

64位操作系统上的应用程序分为三种:

32位应用程序

安装目录:C:\Program Files (x86)

64位应用程序

安装目录:C:\Program Files

双重版本应用程序(Dual-bitness application)

安装目录:参考上述目录

这种方式必须保证32位版本与64位版本兼容。

acf43755a042

Behavior of Applications and Interpreted Files at Process Startup

补充说明:

针对文件重定向,只有32位程序访问64位目录时才会被重定向,例如32位程序访问64位目录C:\Windows\system32;而64位程序则可以直接访问32位目录,不存在重定向,例如64位程序可以直接访问C:\Windows\syswow64

文件系统重定向只是存在system32和systemWOW64的重定向,而不存在program files和ProgramFiles(x86)的重定向一说,直接硬编码绝对路径即可。

获取系统信息代码片段

// 判断应用程序是否运行在X64系统下

BOOL IsX64System()

{

BOOL bIsWow64 = FALSE;

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);

LPFN_ISWOW64PROCESS pfnIsWow64 = NULL;

// 32位系统的kernel32没有IsWow64Process导出函数,直接使用会有问题

pfnIsWow64 = (LPFN_ISWOW64PROCESS)GetProcAddress(

GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");

if (pfnIsWow64)

{

if (!pfnIsWow64(GetCurrentProcess(), &bIsWow64))

{

// handle error

}

}

return bIsWow64;

}

// 获取系统信息

BOOL GetSystemInfoEx(SYSTEM_INFO *pSystemInfo)

{

BOOL bRet = FALSE;

if (!pSystemInfo)

{

goto Exit0;

}

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);

PGNSI pfnGNSI = NULL;

ZeroMemory(pSystemInfo, sizeof(SYSTEM_INFO));

if (IsX64System())

{

// x64下要调用这个API

pfnGNSI = (PGNSI)GetProcAddress(

GetModuleHandle(_T("kernel32.dll")), "GetNativeSystemInfo");

if (!pfnGNSI)

{

goto Exit0;

}

pfnGNSI(pSystemInfo);

}

else

{

// 32位系统调用下面的API

GetSystemInfo(pSystemInfo);

}

bRet = TRUE;

Exit0:

return bRet;

}

Bibliography


http://chatgpt.dhexx.cn/article/daSKcZyH.shtml

相关文章

WOW64机制

WOW64: Windows On Windows64 是一种在64位OS中支持运行的32位应用程序的机制. 64位Windows中, 64位应用程序会加载64位的kernel32.dll, ntdll.dll, 32位应用程序会加载32位的kernel32.dll, ntdll.dll. WOW64则会将32位的dll文件的API请求重定向到64位的dll文件. 注意内核模式…

java for数组遍历数组_Java foreach操作(遍历)数组

语法: 我们分别使用 for 和 foreach 语句来遍历数组 运行结果: 练习: import java.util.Arrays; public class HelloWorld {public static void main(String[] args) {// 定义一个整型数组,保存成绩信息 int[] scores = { 89, 72, 64, 58, 93 }; // 对Arrays类对数组进行排…

【有趣的实验】JAVA 遍历数组的几种方式的耗时对比

一、前言 出于对遍历方式的耗时想法&#xff0c;是普通for循环、fori、foreach、迭代器 iterator、还是steam流的形式哪种耗时更少呢&#xff1f; 首先添加一个List 集合&#xff0c;这边采用ArraryList ArrayList<Integer> list new ArrayList<Integer>();list …

Java高逼格遍历数组的方式

在普通for循环遍历或取数组元素或做其他操作时&#xff0c;总会以将要超出数组最大索引作为循环结束的标志&#xff0c;也就是说每一次循环都要去判断此条件是否满足 而forEach强就强在它无需这一步流程&#xff0c;所以效率要高 但在今天我无意写出了一种这样的遍历方式&…

java遍历数组的三种方式

for循环遍历 用for循环遍历数组是很常见的一种方法&#xff0c;Java语言中通过数组的length属性可获得数组的长度。 package demo; publicclasstest{ public static void main(String[] args){ int [] array {1,2,3,4,5};for(int i 0;i < array.length;i){ System.out.print…

Java基础-遍历数组

Java基础-遍历数组 1、语法简介2、一维数组3、二维数组4、三维数组 1、语法简介 在Java中&#xff0c;对for语句的功能给予了扩充、加强&#xff0c;以便更好的遍历数组。 语法格式如下&#xff1a; for(声明循环变量:数组的名字){......... }其中&#xff0c;声明的循环变量…

JAVA 遍历数组求平均值与最大值

求平均值与最大值 实现前需要懂得如何获取数组长度实现数组遍历 例如&#xff1a; int[] array {2,3,6,8,18}; for(int i 0 ; i<array.length; i){ System.out.print(array[i] ","); } 输出结果&#xff1a;2,3,6,8,18 求最大值时则采用擂台制现默认一个数…

java遍历数组(Java遍历数组拿取对应的)

java中怎样遍历数组对象的值 int[] a {1,2,3}; for(int i0;i System.out.println(a[i]); }//定义一个string类型的一维数组 string[] namesnew string[5]; //为数组赋值 for (int i 0; i < names.length; i) { names[i]integer.tostring(i); //使用foreach遍历数组 int in…

java遍历数组最简洁的方法,java遍历数组的方式有哪些?

我们也了解Java也已经很久了&#xff0c;那今天小编想问大家是否知道java遍历数组的方式有哪些?是不是内心已经已经有答案了?让就跟着小编的步伐一起看看吧。 1. for循环遍历 这是最基本的遍历方式 通常遍历数组都是使用for循环来实现。遍历一维数组很简单&#xff0c;遍历二…

java中遍历数组方法

1循环遍历数组方法 在main主函数中给数组赋值即可调用该方法 public static void fun07(int[] array) {System.out.print("[");//输出一个左中括号if (array ! null) { //如果数组不为空&#xff0c;执行下面的语句for (int i 0; i < array.length; i) { /…

Java中数组遍历的五种方法

遍历&#xff1a;Stream遍历&#xff0c;循环遍历 //TODO 为Java提供的一种书签import java.util.Vector; import java.util.Enumeration; import java.util.Iterator; import java.util.Random;/*** 数组多种遍历偶数方法* * author 轩**/ public class Main {public static v…

Java:遍历数组的三种方法

1、for循环遍历数组 用for循环遍历数组是很常见的一种方法&#xff0c;Java语言中通过数组的length属性可获得数组的长度。 package demo;public class test {public static void main(String[] args) {int [] array {1,2,3,4,5};for(int i 0;i < array.length;i) {Syste…

java中数组遍历的三种方式

1.for循环遍历 通常遍历数组都是使用for循环来实现。遍历一维数组很简单&#xff0c;遍历二维数组需要使用双层for循环&#xff0c;通过数组的length属性可获得数组的长度。 2.Arrays工具类中toString静态方法遍历 利用Arrays工具类中的toString静态方法可以将一维数组转化为字…

Oracle--常用数据库对象(视图、序列、索引、同义词)详解

常见的数据库对象 对象描述表基本的数据存储集合&#xff0c;由行和列组成视图从表中抽出的逻辑上相关的数据集合序列提供有规律的数值索引提高查询的效率同义词给对象起别名 视图 什么是视图&#xff1f; 视图是一个 虚 表 \color{red}{虚表} 虚表视图建立在已有表的基础上…

Oracle【基础函数、视图、索引】

1. 认识oracle数据库 Oracle是非常强大的数据库软件。默认端口&#xff1a;1521。与MySQL不同的是&#xff0c;Oracle数据库的概念是一个操作系统装的就是一个大的数据库。一个数据库可以有很多个实例&#xff0c;每个实例占用一系列的进程和内存。通常一台机器只用一个实例。每…

主要是sql查询符合在圆形,多边形区域经纬度的数据

主要是sql查询符合在圆形&#xff0c;多边形区域经纬度的数据 查询 圆形 中心点 距离 drop table if exists demo; CREATE TABLE demo (id int(5) NOT NULL AUTO_INCREMENT COMMENT 主键,shop_name varchar(50) DEFAULT NULL COMMENT 商品名称,lng DECIMAL( 11, 8 ) DEFA…

mysql计算相关系数_用sql实现相关系数的计算

登录后查看更多精彩内容~ 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 本帖最后由 静言_GRMC 于 2018-5-25 13:07 编辑 平时工作中要用到好多统计查询功能,一直用sql比较顺手,最近需要做相关系数方面的统计,发现除了Oracle自带了函数外,ms sql和mysql都没有自带计…

【SQL数据库基础05-2】常见约束与标识列

文章目录 常见约束01 基本概念1.1 含义&#xff1a;1.2 分类&#xff1a;六大约束1.3 添加约束的时机&#xff1a;1.4 约束的添加分类&#xff1a;1.5 主键和唯一的大对比&#xff1a;1.6 外键&#xff1a; 02 具体讲解2.1 创建表时添加约束1.添加列级约束2.添加表级约束 2.2 修…

关系数据库标准语言SQL视图模块

目录 一. 视图的特点 二. 基于视图的操作 2.1 建立视图 1&#xff09;行列子集视图举例&#xff1a; 2&#xff09;基于多个基表的视图&#xff1a; 3&#xff09;基于视图的视图&#xff1a; 4&#xff09;带表达式的视图&#xff1a; 5&#xff09;建立分组视图&am…

Oracle的视图,索引,约束,事务,数据库范式

&#x1f345;程序员小王的博客&#xff1a;程序员小王的博客 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 如有编辑错误联系作者&#xff0c;如果有比较好的文章欢迎分享给我&#xff0c;我会取其精华去其糟粕 &#x1f345;java自学的学习…