windows-nt/Source/XPSP1/NT/shell/shlwapi/apithk.c
2020-09-26 16:20:57 +08:00

237 lines
5.9 KiB
C

//
// APITHK.C
//
// This file has API thunks that allow shlwapi to load and run on
// multiple versions of NT or Win95. Since this component needs
// to load on the base-level NT 4.0 and Win95, any calls to system
// APIs introduced in later OS versions must be done via GetProcAddress.
//
// Also, any code that may need to access data structures that are
// post-4.0 specific can be added here.
//
// NOTE: this file does *not* use the standard precompiled header,
// so it can set _WIN32_WINNT to a later version.
//
#include "priv.h" // Don't use precompiled header here
#define _USERENV_ // Disable the declspec(dllimport)
#include <userenv.h> // for ExpandEnvironmentStringsForUser
// the IsOS code is now centralized in shell\inc since shlwapi and those who cannot
// link to shlwapi.dll both need to include it.
#include <isos.c>
typedef BOOL (* PFNGFAXW) (LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID );
STDAPI_(BOOL) MyGetLastWriteTime (LPCWSTR pszPath, FILETIME *pft)
{
if (g_bRunningOnNT5OrHigher)
{
static PFNGFAXW s_pfn = NULL;
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!s_pfn)
{
s_pfn = (PFNGFAXW) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetFileAttributesExW");
}
ASSERT(s_pfn);
if (s_pfn && s_pfn(pszPath, GetFileExInfoStandard, &fad))
{
*pft = fad.ftLastWriteTime;
return TRUE;
}
}
else
{
HANDLE hFile = CreateFileW(pszPath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
GetFileTime(hFile, NULL, NULL, pft);
CloseHandle(hFile);
return TRUE;
}
}
return FALSE;
}
STDAPI_(BOOL) NT5_ExpandEnvironmentStringsForUserW (HANDLE hToken, LPCWSTR lpSrc, LPWSTR lpDest, DWORD dwSize)
{
RIPMSG(g_bRunningOnNT5OrHigher, "Cannot invoke NT5_ExpandEnvironmentStringsForUserW when not on NT5 or higher");
return(ExpandEnvironmentStringsForUserW(hToken, lpSrc, lpDest, dwSize));
}
typedef BOOL (* PFNSETFILEPOINTEREX) (HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD);
STDAPI_(BOOL) NT5_SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistance, PLARGE_INTEGER pliNewPos, DWORD dwMoveMethod)
{
static PFNSETFILEPOINTEREX s_pfn = (PFNSETFILEPOINTEREX)-1;
if (s_pfn == (PFNSETFILEPOINTEREX)-1)
{
s_pfn = (PFNSETFILEPOINTEREX) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "SetFilePointerEx");
}
if (s_pfn)
{
return s_pfn(hFile, liDistance, pliNewPos, dwMoveMethod);
}
else
{
DWORD dwCurrent = SetFilePointer(hFile, liDistance.LowPart, NULL, dwMoveMethod);
if (pliNewPos)
{
pliNewPos->LowPart = dwCurrent;
pliNewPos->HighPart = 0;
}
// Because the high value is null, this return indicates failure.
if (dwCurrent == INVALID_SET_FILE_POINTER)
{
return FALSE;
}
}
return TRUE;
}
typedef LONG (* PFNREGOPENCURRENTUSER) (REGSAM, HKEY *);
STDAPI_(LONG) NT5_RegOpenCurrentUser(REGSAM sam, HKEY *phk)
{
static PFNREGOPENCURRENTUSER s_pfn = (PFNREGOPENCURRENTUSER)-1;
if (s_pfn == (PFNREGOPENCURRENTUSER)-1)
{
if (g_bRunningOnNT5OrHigher)
s_pfn = (PFNREGOPENCURRENTUSER) GetProcAddress(GetModuleHandle(TEXT("advapi32")), "RegOpenCurrentUser");
else
s_pfn = NULL;
}
if (s_pfn)
{
return s_pfn(sam, phk);
}
else
{
*phk = NULL;
return ERROR_CAN_NOT_COMPLETE;
}
}
typedef BOOL (__stdcall *PFNACTCTX)(HANDLE, ULONG_PTR *);
typedef BOOL (__stdcall *PFNDEACTCTX)(DWORD, ULONG_PTR );
typedef HANDLE (__stdcall *PFNCREATECTX)(ACTCTX*);
typedef void (__stdcall *PFNRELCTX)(HANDLE);
static PFNACTCTX s_pfnAct = (PFNACTCTX)-1;
static PFNDEACTCTX s_pfnDeact = (PFNDEACTCTX)-1;
static PFNCREATECTX s_pfnCreateact = (PFNCREATECTX)-1;
static PFNRELCTX s_pfnReleaseact = (PFNRELCTX)-1;
HANDLE XP_CreateActCtx(ACTCTX* p)
{
if (s_pfnCreateact == (PFNCREATECTX)-1)
{
#ifdef UNICODE
s_pfnCreateact = (PFNCREATECTX)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "CreateActCtxW");
#else
s_pfnCreateact = (PFNCREATECTX)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "CreateActCtxA");
#endif
}
if (s_pfnCreateact)
return s_pfnCreateact(p);
return NULL;
}
void XP_ReleaseActCtx(HANDLE h)
{
if (s_pfnReleaseact == (PFNRELCTX)-1)
{
s_pfnReleaseact = (PFNRELCTX)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "ReleaseActCtx");
}
if (s_pfnReleaseact)
s_pfnReleaseact(h);
}
BOOL XP_ActivateActCtx(HANDLE h, ULONG_PTR* p)
{
if (s_pfnAct == (PFNACTCTX)-1)
{
s_pfnAct = (PFNACTCTX)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "ActivateActCtx");
}
*p = 0;
if (s_pfnAct)
{
return s_pfnAct(h, p);
}
return TRUE;
}
BOOL XP_DeactivateActCtx(ULONG_PTR p)
{
if (s_pfnDeact == (PFNDEACTCTX)-1)
{
s_pfnDeact = (PFNDEACTCTX)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "DeactivateActCtx");
}
if (s_pfnDeact && p)
return s_pfnDeact(0, p);
return TRUE;
}
STDAPI_(HANDLE) XP_CreateAndActivateContext(ULONG_PTR* pul)
{
HANDLE hActCtx;
ACTCTX act = {0};
TCHAR szPath[MAX_PATH];
GetModuleFileName(g_hinst, szPath, ARRAYSIZE(szPath));
act.cbSize = sizeof(act);
act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName = MAKEINTRESOURCE(123);
act.lpSource = szPath;
hActCtx = XP_CreateActCtx(&act);
if (hActCtx)
{
XP_ActivateActCtx(hActCtx, pul);
}
return hActCtx;
}
STDAPI_(void) XP_DeactivateAndDestroyContext(HANDLE hActCtx, ULONG_PTR ul)
{
if (hActCtx != INVALID_HANDLE_VALUE)
{
if (ul != 0)
XP_DeactivateActCtx(ul);
XP_ReleaseActCtx(hActCtx);
}
}