📄 lfapi.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
// Abstract: Location framework user-mode DLL - marshalls API calls
// into location framework service in services.exe.
#include <windows.h>
#include <lfApi.h>
#include <svsutil.hxx>
#include <..\inc\locIoctl.hpp>
ce::psl_proxy<>* pProxy;
extern "C" HLOCATION LocationOpen(DWORD version, VOID *pReserved, DWORD flags) {
HLOCATION hRet = 0;
// PSL marshaller class returns GetLastError() code, so add the return
// HANDLE as an extra paramater for internal calls.
DWORD err = pProxy->call(IOCTL_LF_OPEN,version,pReserved,flags,&hRet);
if (err == ERROR_SUCCESS) {
ASSERT(hRet != NULL);
return hRet;
}
// PSL marshaller already has SetLastError to err code, so don't repeat here.
return NULL;
}
extern "C" DWORD LocationClose(HLOCATION hLocation) {
return pProxy->call(IOCTL_LF_CLOSE,hLocation);
}
extern "C" DWORD LocationRegisterForReport(HLOCATION hLocation, HANDLE hNewLocationReport,
HANDLE hStateChangeEvent, REFGUID reportType,
DWORD flags)
{
return pProxy->call(IOCTL_LF_REGISTER_FOR_REPORT,hLocation, hNewLocationReport,
hStateChangeEvent, &reportType, flags);
}
extern "C" DWORD LocationUnRegisterForReport(HLOCATION hLocation, REFGUID reportType, DWORD flags)
{
return pProxy->call(IOCTL_LF_UN_REGISTER_FOR_REPORT, hLocation, &reportType, flags);
}
// If report appears to have been generated 10 seconds or more in the future,
// then clean up its filetime. If report is farther ahead in future than this
// then assume it's not the result of clock skew
const __int64 g_maxFutureSkew = (10 * 1000 * SVS_FILETIME_TO_MILLISECONDS);
// Potentially fix up creationTime of report. The WinCE real-time clock
// has the strange behavior that different processes calling GetCurrentFT
// to retrieve its value may get unexpectedly different values. In particular,
// it is possible that the time the report was generated as marked in
// services.exe appears to this user-mode process's clock to have been
// generated in the future! If the report is a little in the future, using
// this app's clock put the time to be reasonable.
void FixupFileTimeIfNeeded(FILETIME *pReportTime) {
__int64 currentTime;
GetCurrentFT((FILETIME*)¤tTime);
__int64 reportAge = currentTime - *((__int64*)(pReportTime));
if ((reportAge < 0) && (g_maxFutureSkew + reportAge >= 0)) {
// The report's creationTime is 10 seconds or less ahead in the future
// compared to this process's RTC. Use this proc's RTC as creationTime
// in this case so as not to confuse application
memcpy(pReportTime,¤tTime,sizeof(FILETIME));
}
}
extern "C" DWORD LocationGetReport(HLOCATION hLocation, REFGUID reportType, DWORD maximumAge, LOCATION_REPORT *pLocationReport,
DWORD *pcbLocationReport, DWORD flags)
{
if (NULL == pcbLocationReport)
return ERROR_INVALID_PARAMETER;
DWORD err = pProxy->call(IOCTL_LF_GET_REPORT,hLocation,&reportType, maximumAge,
ce::psl_buffer(pLocationReport,*pcbLocationReport),
pcbLocationReport, flags);
if (err != ERROR_SUCCESS)
return err;
LOCATION_REPORT_BASE *pReportBase = (LOCATION_REPORT_BASE*)pLocationReport;
FixupFileTimeIfNeeded(&pReportBase->creationTime);
return ERROR_SUCCESS;
}
extern "C" DWORD LocationGetServiceState(HLOCATION hLocation, LOCATION_SERVICE_STATE *pServiceState)
{
return pProxy->call(IOCTL_LF_GET_SERVICE_STATE,hLocation, pServiceState);
}
extern "C" DWORD LocationGetPluginInfoForReport(HLOCATION hLocation, REFGUID reportType, PLUGIN_STATE *pPluginState, GUID *pPluginGuid)
{
return pProxy->call(IOCTL_LF_GET_PLUGIN_INFO_FOR_REPORT,hLocation, &reportType, pPluginState,pPluginGuid);
}
extern "C" DWORD LocationGetProvidersInfo(HLOCATION hLocation, PROVIDER_INFORMATION *pProviders, DWORD *pcbBuffer)
{
if (pcbBuffer == NULL)
return ERROR_INVALID_PARAMETER;
DWORD err = pProxy->call(IOCTL_LF_GET_PROVIDERS_INFO, hLocation,
ce::psl_buffer(pProviders, *pcbBuffer), pcbBuffer);
if (err != ERROR_SUCCESS)
return err;
// Number of bytes returned should be even multiple of PROVIDER_INFORMATION
ASSERT((*pcbBuffer) % sizeof(PROVIDER_INFORMATION) == 0);
DWORD numProviders = (*pcbBuffer) / sizeof(PROVIDER_INFORMATION);
for (DWORD i = 0; i < numProviders; i++)
FixupFileTimeIfNeeded(&pProviders[i].pluginInfo.lastUpdate);
return ERROR_SUCCESS;
}
extern "C" DWORD LocationGetResolversInfo(HLOCATION hLocation, RESOLVER_INFORMATION *pResolvers, DWORD *pcbBuffer)
{
if (pcbBuffer == NULL)
return ERROR_INVALID_PARAMETER;
DWORD err = pProxy->call(IOCTL_LF_GET_RESOLVERS_INFO, hLocation,
ce::psl_buffer(pResolvers, *pcbBuffer),pcbBuffer);
if (err != ERROR_SUCCESS)
return err;
// Number of bytes returned should be even multiple of RESOLVER_INFORMATION
ASSERT((*pcbBuffer) % sizeof(RESOLVER_INFORMATION) == 0);
DWORD numResolvers = (*pcbBuffer) / sizeof(RESOLVER_INFORMATION);
for (DWORD i = 0; i < numResolvers; i++)
FixupFileTimeIfNeeded(&pResolvers[i].pluginInfo.lastUpdate);
return ERROR_SUCCESS;
}
extern "C" HLOCATIONPLUGIN LocationPluginOpen(HLOCATION hLocation, REFGUID pluginGuid) {
HLOCATIONPLUGIN hRet = 0;
// PSL marshaller class returns GetLastError() code, so add the return
// HANDLE as an extra paramater for internal calls.
DWORD err = pProxy->call(IOCTL_LF_PLUGIN_OPEN,hLocation,&pluginGuid,&hRet);
if (err == ERROR_SUCCESS) {
ASSERT(hRet != NULL);
return hRet;
}
return NULL;
}
extern "C" DWORD LocationPluginIOCTL(HLOCATION hLocation, HLOCATIONPLUGIN hPlugin,
DWORD dwCode, BYTE *pbIn, DWORD cbIn,
BYTE *pbOut, DWORD *pcbOut)
{
return pProxy->call(IOCTL_LF_PLUGIN_IOCTL,hLocation,hPlugin,dwCode,
ce::psl_buffer(pbIn,cbIn),
ce::psl_buffer(pbOut, pcbOut ? *pcbOut : 0),
pcbOut);
}
extern "C" DWORD LocationPluginClose(HLOCATION hLocation, HLOCATIONPLUGIN hPlugin) {
return pProxy->call(IOCTL_LF_PLUGIN_CLOSE,hLocation,hPlugin);
}
extern "C" BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE)hInstDll);
pProxy = new ce::psl_proxy<>(LOC_DEV_NAME, IOCTL_LF_INVOKE, NULL);
return (pProxy != NULL);
break;
case DLL_PROCESS_DETACH:
if (pProxy)
delete pProxy;
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -