Windows2003-3790/windows/appcompat/shims/layer/emulatecreatefilemapping.cpp
2020-09-30 16:53:55 +02:00

272 lines
6.8 KiB
C++

/*++
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
EmulateCreateFileMapping.cpp
Abstract:
Win9x defaults to SEC_COMMIT when the SEC_NOCACHE flag is set.
NT fails the call.
File mapping names, can't contain backslashes.
Notes:
This is a general purpose shim.
History:
02/17/2000 linstev Created
05/26/2001 robkenny Replace all \ to _ in map names.
02/28/2002 robkenny Security review, was clobbering Global\ and Local\ namespaces.
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(EmulateCreateFileMapping)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(CreateFileMappingA)
APIHOOK_ENUM_ENTRY(CreateFileMappingW)
APIHOOK_ENUM_ENTRY(OpenFileMappingA)
APIHOOK_ENUM_ENTRY(OpenFileMappingW)
APIHOOK_ENUM_END
/*++
Correct the flag and name
--*/
HANDLE
APIHOOK(CreateFileMappingW)(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
)
{
HANDLE hRet = ORIGINAL_API(CreateFileMappingW)(hFile, lpAttributes,
flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
if (!hRet) {
//
// The call failed, so try correcting the parameters
//
DWORD flNewProtect = flProtect;
if ((flProtect & SEC_NOCACHE) &&
(!((flProtect & SEC_COMMIT) || (flProtect & SEC_RESERVE)))) {
// Add the SEC_COMMIT flag
flNewProtect |= SEC_COMMIT;
}
CSTRING_TRY {
// Replace backslashes
CString csName(lpName);
int nCount = 0;
if (csName.ComparePart(L"Global\\", 0, 7) == 0)
{
// This event exists in the global namespace
csName.Delete(0, 7);
nCount = csName.Replace(L'\\', '_');
csName = L"Global\\" + csName;
}
else if (csName.ComparePart(L"Local\\", 0, 6) == 0)
{
// This event exists in the Local namespace
csName.Delete(0, 6);
nCount = csName.Replace(L'\\', '_');
csName = L"Local\\" + csName;
}
else
{
nCount = csName.Replace(L'\\', '_');
}
LPCWSTR lpCorrectName = csName;
if (nCount || (flProtect != flNewProtect)) {
// Something happened, so log it
if (nCount) {
LOGN(eDbgLevelError,
"[CreateFileMapping] Corrected event name from (%S) to (%S)", lpName, lpCorrectName);
}
if (flProtect != flNewProtect) {
LOGN(eDbgLevelError, "[CreateFileMapping] Adding SEC_COMMIT flag");
}
// Call again with fixed parameters
hRet = ORIGINAL_API(CreateFileMappingW)(hFile, lpAttributes, flNewProtect,
dwMaximumSizeHigh, dwMaximumSizeLow, lpCorrectName);
}
}
CSTRING_CATCH {
// Do nothing
}
}
return hRet;
}
/*++
Pass through to CreateFileMappingW.
--*/
HANDLE
APIHOOK(CreateFileMappingA)(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCSTR lpName
)
{
HANDLE hRet;
CSTRING_TRY {
// Convert to unicode
CString csName(lpName);
LPCWSTR lpwName = csName;
hRet = APIHOOK(CreateFileMappingW)(hFile, lpAttributes, flProtect,
dwMaximumSizeHigh, dwMaximumSizeLow, lpwName);
}
CSTRING_CATCH {
// Fall back as gracefully as possible
hRet = ORIGINAL_API(CreateFileMappingA)(hFile, lpAttributes, flProtect,
dwMaximumSizeHigh, dwMaximumSizeLow, lpName);
}
return hRet;
}
/*++
Correct the name
--*/
HANDLE
APIHOOK(OpenFileMappingW)(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName
)
{
HANDLE hRet = ORIGINAL_API(OpenFileMappingW)(dwDesiredAccess, bInheritHandle,
lpName);
if (!hRet) {
//
// The call failed, so try correcting the parameters
//
CSTRING_TRY {
// Replace backslashes
CString csName(lpName);
int nCount = 0;
if (csName.ComparePart(L"Global\\", 0, 7) == 0)
{
// This event exists in the global namespace
csName.Delete(0, 7);
nCount = csName.Replace(L'\\', '_');
csName = L"Global\\" + csName;
}
else if (csName.ComparePart(L"Local\\", 0, 6) == 0)
{
// This event exists in the Local namespace
csName.Delete(0, 6);
nCount = csName.Replace(L'\\', '_');
csName = L"Local\\" + csName;
}
else
{
nCount = csName.Replace(L'\\', '_');
}
LPCWSTR lpCorrectName = csName;
if (nCount) {
// Something happened, so log it
LOGN(eDbgLevelError,
"OpenFileMappingW corrected event name from (%S) to (%S)", lpName, lpCorrectName);
// Call again with fixed parameters
hRet = ORIGINAL_API(OpenFileMappingW)(dwDesiredAccess, bInheritHandle,
lpCorrectName);
}
}
CSTRING_CATCH
{
// Do nothing
}
}
return hRet;
}
/*++
Pass through to OpenFileMappingW.
--*/
HANDLE
APIHOOK(OpenFileMappingA)(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCSTR lpName
)
{
HANDLE hRet;
CSTRING_TRY {
// Convert to unicode
CString csName(lpName);
LPCWSTR lpwName = csName;
hRet = APIHOOK(OpenFileMappingW)(dwDesiredAccess, bInheritHandle,
lpwName);
}
CSTRING_CATCH {
// Fall back as gracefully as possible
hRet = ORIGINAL_API(OpenFileMappingA)(dwDesiredAccess, bInheritHandle,
lpName);
}
return hRet;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileMappingA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileMappingW)
APIHOOK_ENTRY(KERNEL32.DLL, OpenFileMappingA)
APIHOOK_ENTRY(KERNEL32.DLL, OpenFileMappingW)
HOOK_END
IMPLEMENT_SHIM_END