كيف يمكن لعملية 64 بت أن يكون لها عرض 32 بت من نظام الملفات والسجل؟

StackOverflow https://stackoverflow.com/questions/3724038

  •  03-10-2019
  •  | 
  •  

سؤال

للتوافق مع الوراء ، تحتاج عملية 64 إلى رؤية عرض 32 بت لنظام الملفات والسجل.

أعرف كيفية إجراء عملية 32 بت انظر عرض 64 بت من نظام الملفات والسجل (باستخدام WOW64DISABLEWOW64FSREDIRECTION

ولكن كيف يمكنني إجراء عملية 64 بت لديها عرض 32 بت من نظام الملفات والسجل؟

هل كانت مفيدة؟

المحلول 4

key_wow64_32key يعمل لعملية 64 بت و 32 بت.

من التجربة ، لا يبدو أن WOW64ENABLEWOW64FSREDIRECTION/WOW64DISABLEWOW64FSREDIRECITIONS لا يعمل في عملية 64 بت - ويشير الاسم إلى أنه يبدو أنه يعمل فقط في عملية WOW64.

لذلك من أجل الحصول على "عرض" 32 بت من نظام الملفات من عملية 64 بت ، سيتم تغيير المسارات إلى الإشارة إلى المواقع الصحيحة

هذا أمر قبيح حقًا ، ولكن هنا عينة رمز C ++ لكيفية تنفيذ إعادة توجيه نظام الملفات وفقًا لـ مايكروسوفت. يتطلب التعزيز.

#include"boost/filesystem.hpp"
#include"wstring"
#include"shfolder.h"
#include"Shlobj.h"
bool redirectPathRoot( boost::filesystem::wpath pathFromRoot, boost::filesystem::wpath pathToRoot, boost::filesystem::wpath & pathToRedirect )
{
bool bPathWasRedirected = false;
boost::filesystem::wpath theNewPath;
boost::filesystem::wpath::iterator iPathToRedirect = pathToRedirect.begin();
boost::filesystem::wpath::iterator iFromRoot = pathFromRoot.begin();
bool bMatch = true;
while( iPathToRedirect != pathToRedirect.end() && iFromRoot != pathFromRoot.end() && bMatch )
{
    //
    // see if the root of the path we are checking matches 
    //
    bMatch = ( std::wstring(*iPathToRedirect++) == std::wstring(*iFromRoot++) );
}
if( bMatch && iFromRoot == pathFromRoot.end() )
{
    theNewPath = pathToRoot;
    //
    // these guys need to be redirected
    //
    while( iPathToRedirect != pathToRedirect.end() )
    {
        theNewPath /= *iPathToRedirect++;
    }
    bPathWasRedirected = true;
    pathToRedirect = theNewPath;
}
return bPathWasRedirected;
}
std::wstring adjustPathFor32BitOn64BitProcess( LPCWSTR thePath )
{
std::wstring strPath(thePath);
boost::to_lower(strPath);
//
// default to the original path
//
boost::filesystem::wpath theNewPath(strPath.c_str());
theNewPath.normalize();
//
// init the supplied path
//
boost::filesystem::wpath pathToCheck( strPath.c_str() );
pathToCheck.normalize();
//
// get the path for the 32 bit folder on a 64 bit system
//
wchar_t strTemp[MAX_PATH] = L"\0";
GetSystemWow64Directory( strTemp, MAX_PATH );
std::wstring strSysWow64 = strTemp;
boost::to_lower( strSysWow64 );
boost::filesystem::wpath pathSysWow64( strSysWow64.c_str() );
pathSysWow64.normalize();

//
// get the path for the system directory
//
GetSystemDirectory( strTemp, MAX_PATH );
std::wstring strSys = strTemp;
boost::to_lower( strSys );
boost::filesystem::wpath pathSys( strSys.c_str() );
pathSys.normalize();

//
// get the path for the Program Files directory
//
SHGetFolderPath( NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strPrograms = strTemp;
boost::to_lower( strPrograms );
boost::filesystem::wpath pathPrograms( strPrograms.c_str() );
pathPrograms.normalize();

//
// get the path for the Program Files x86 directory
//
SHGetFolderPath( NULL, CSIDL_PROGRAM_FILESX86, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strProgramsX86 = strTemp;
boost::to_lower( strProgramsX86 );
boost::filesystem::wpath pathProgramsX86( strProgramsX86.c_str() );
pathProgramsX86.normalize();

//
// get the path for the Windows\lastgood\system32 directory
//
SHGetFolderPath( NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strWindows = strTemp;
boost::to_lower( strWindows );
boost::filesystem::wpath pathWindows( strWindows.c_str() );
pathWindows.normalize();

boost::filesystem::wpath pathWindowsLastGoodSystem32( strWindows.c_str() );
pathWindowsLastGoodSystem32 /= L"lastgood";
pathWindowsLastGoodSystem32 /= L"system32";
pathWindowsLastGoodSystem32.normalize();

boost::filesystem::wpath pathWindowsLastGoodSysWOW64( strWindows.c_str() );
pathWindowsLastGoodSysWOW64 /= L"lastgood";
pathWindowsLastGoodSysWOW64 /= L"syswow64";
pathWindowsLastGoodSysWOW64.normalize();


//
// finally, regedit...
//
boost::filesystem::wpath pathRegedit( strWindows.c_str() );
pathRegedit /= L"regedit.exe";
pathRegedit.normalize();

boost::filesystem::wpath pathRegeditSysWOW64( pathSysWow64 );
pathRegeditSysWOW64 /= L"regedit.exe";
pathRegeditSysWOW64.normalize();

//
// now see if the supplied path matches system directoy
//
boost::filesystem::wpath::iterator iPathToCheck = pathToCheck.begin();
boost::filesystem::wpath::iterator iSys = pathSys.begin();
bool bMatch = true;
while( iPathToCheck != pathToCheck.end() && iSys != pathSys.end() && bMatch )
{
    //
    // see if the beginning of the path we are checking matches the system path
    //
    bMatch = ( std::wstring(*iPathToCheck++) == std::wstring(*iSys++) );
}
if( bMatch && iSys == pathSys.end() )
{
    //
    // the supplied path matches at least as far as the system dir...
    //
    if( iPathToCheck == pathToCheck.end() )
    {
        //
        // ...actually its an exact match, so redirect it
        //
        theNewPath = pathSysWow64;
    }
    else
    {
        //
        // ...however, there are a few exceptions....
        //
        boost::filesystem::wpath::iterator iTemp = iPathToCheck;
        if( 
                !(
                    std::wstring(*iTemp) == L"drivers" && 
                    ( 
                        (++iTemp) != pathToCheck.end()  && 
                        std::wstring(*(iTemp)) == L"etc" 
                        )
                    ) 
                &&
                (std::wstring(*iPathToCheck) != L"catroot") &&
                (std::wstring(*iPathToCheck) != L"catroot2") &&
                (std::wstring(*iPathToCheck) != L"logfiles") &&
                (std::wstring(*iPathToCheck) != L"spool")
                )
        {
            //
            // all but the above dirs should be redirected
            //
            theNewPath = pathSysWow64;
            while( iPathToCheck != pathToCheck.end() )
            {
                theNewPath /= *iPathToCheck++;
            }
        }
    }
}
else
{
    //
    // didn't match the system dir... see if it matches the Program Files dir
    //
    if(!redirectPathRoot(  pathPrograms, pathProgramsX86, theNewPath ))
    {
        //
        // now try %windir%/lastgood/system32
        //
        if(!redirectPathRoot(  pathWindowsLastGoodSystem32, pathWindowsLastGoodSysWOW64, theNewPath ))
        {
            //
            // finally, regedit
            //
            redirectPathRoot(  pathRegedit, pathRegeditSysWOW64, theNewPath );
        }
    }

}
return theNewPath.file_string();}

نصائح أخرى

تحتاج إلى البحث صراحة في مفاتيح/الدلائل "WOW64". في الواقع ، لا يوجد سجل "64 بت" ، فهناك مجرد "السجل" وإعادة توجيه WOW64 يعيد توجيه عملية 32 بت إلى مفتاح فرعي مختلف. لذلك عندما تسأل عملية 32 بت عن "HKLM Software Foo" يقول API التسجيل بالفعل ، "انتظر ، أنت 32 بت ، لذا سأتظاهر بأنك طلبت" HKLM Software "wow6432nodeفو "بدلا من ذلك".

لذلك مع وضع ذلك في الاعتبار ، لا توجد طريقة لإلقاء نظرة على 64 بت في السجل "32 بت" ، لأنه لا يوجد شيء مثل "سجل 32 بت". بدلاً من ذلك ، سيكون عليك فقط القيام بما يفعله منطق إعادة توجيه WOW64 تلقائيًا.

تعديل

للسجل ، هناك في الواقع KEY_WOW64_32KEY المفتاح الذي يمكنك تحديده في مكالمات طريقة مختلفة.

بالنسبة لنظام الملفات ، قد تكون قادرًا على المحاولة WOW64ENABLEWOW64FSREDIRECTION, ، لكنني لست متأكدًا مما إذا كان سيعمل أم لا ...

إذا كنت ترغب في رؤية السجل 32 بت ، يمكنك استخدام key_wow64_32key كما هو موضح هنا

إذا كنت ترغب في الوصول إلى دليل Syswow64 ، يمكنك استخدام GetSystemWow64Directory كما هو موضح هنا

متأخراً قليلاً عن الحفلة ، ولكن هل يمكنك إنشاء عملية صغيرة 32 بت تعمل على 32 بت؟ ثم كل من بني في الخير من WOW64 سوف يعمل.

لست متأكدًا من شكل لغة التنمية/وقت التشغيل الخاص بك ، لذلك غير قادر على تقديم المزيد من الاقتراحات حول شكل التواصل بين العملية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top