237 lines
5.9 KiB
C
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);
|
||
|
}
|
||
|
}
|
||
|
|