// // 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 // 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 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); } }