📄 devcore.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#define _DEVMGRDATA_DEF
#include <windows.h>
#include <devload.h>
#include <console.h>
#include <errorrep.h>
#include "devmgrp.h"
#include "celogdev.h"
#include "devmgrif.h"
#include "pmif.h"
#include "iormif.h"
#include "devzones.h"
#ifdef DEBUG
//
// These defines must match the ZONE_* defines in devmgr.h
//
#define DBG_ERROR 1
#define DBG_WARNING 2
#define DBG_FUNCTION 4
#define DBG_INIT 8
#define DBG_BUILTIN 16
#define DBG_ACTIVE 64
#define DBG_RESMGR 128
#define DBG_FSD 256
#define DBG_DYING 512
#define DBG_BOOTSEQ 1024
#define DBG_PNP 2048
DBGPARAM dpCurSettings = {
TEXT("DEVLOAD"), {
TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"),TEXT("Initialization"),
TEXT("Built-In Devices"),TEXT("Undefined"),TEXT("Active Devices"),TEXT("Resource Manager"),
TEXT("File System Drvr"),TEXT("Dying Devs"),TEXT("Boot Sequence"),TEXT("PnP"),
TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined") },
DBG_ERROR | DBG_WARNING | DBG_INIT
};
#endif // DEBUG
// global variables
CRITICAL_SECTION g_devcs;
LIST_ENTRY g_DevChain;
LIST_ENTRY g_ActivatingDevs;
LIST_ENTRY g_DyingDevs;
LIST_ENTRY g_CandidateDevs;
fsopendev_t *g_lpOpenDevs;
fsopendev_t *g_lpDyingOpens;
HANDLE g_hDevApiHandle, g_hDevFileApiHandle, g_hCleanEvt;
BOOL g_bSystemInitd;
// Boot phase measure where we are in the boot process.
// Zero means we haven't started the device manager yet;
// One is used to find the registry;
// Two is used during initial device driver loading;
// Three is normal run mode.
DWORD g_BootPhase = 0;
const TCHAR s_DllName_ValName[] = DEVLOAD_DLLNAME_VALNAME;
const TCHAR s_ActiveKey[] = DEVLOAD_ACTIVE_KEY;
const TCHAR s_BuiltInKey[] = DEVLOAD_BUILT_IN_KEY;
const PFNVOID FDevApiMethods[] = {
//xref ApiSetStart
(PFNVOID)DM_DevProcNotify, // 0
(PFNVOID)0, // 1
(PFNVOID)DM_RegisterDevice, // 2
(PFNVOID)DM_DeregisterDevice, // 3
(PFNVOID)0, // 4 - was CloseAllDeviceHandles
(PFNVOID)DM_CreateDeviceHandle, // 5
(PFNVOID)0, // 6
(PFNVOID)0, // 7
(PFNVOID)DM_DeactivateDevice, // 8
(PFNVOID)0, // 9
(PFNVOID)DM_GetDeviceByIndex, // 10
(PFNVOID)DM_CeResyncFilesys, // 11
(PFNVOID)DM_ActivateDeviceEx, // 12
(PFNVOID)0, // 13 - moved to filesys - was RequestDeviceNotifications
(PFNVOID)0, // 14 - moved to filesys - was StopDeviceNotifications
(PFNVOID)0, // 15 - was GetDevicePathFromPnp
(PFNVOID)IORM_ResourceCreateList, // 16
(PFNVOID)IORM_ResourceAdjust, // 17
(PFNVOID)PM_GetSystemPowerState, // 18
(PFNVOID)PM_SetSystemPowerState, // 19
(PFNVOID)PM_SetPowerRequirement, // 20
(PFNVOID)PM_ReleasePowerRequirement, // 21
(PFNVOID)PM_RequestPowerNotifications, // 22
(PFNVOID)PM_StopPowerNotifications, // 23
(PFNVOID)0, // 24 - deprecated - VetoPowerNotification
(PFNVOID)PM_DevicePowerNotify, // 25
(PFNVOID)PM_RegisterPowerRelationship, // 26
(PFNVOID)PM_ReleasePowerRelationship, // 27
(PFNVOID)PM_SetDevicePower, // 28
(PFNVOID)PM_GetDevicePower, // 29
(PFNVOID)0, // 30 - moved to filesys - was AdvertiseInterface
(PFNVOID)IORM_ResourceMarkAsShareable, // 31
(PFNVOID)IORM_ResourceDestroyList, // 32
(PFNVOID)IORM_ResourceRequestEx, // 33
(PFNVOID)DM_GetDeviceInformationByDeviceHandle, // 34
(PFNVOID)DM_EnumDeviceInterfaces // 35
//xref ApiSetEnd
};
#define NUM_FDEV_APIS (sizeof(FDevApiMethods)/sizeof(FDevApiMethods[0]))
const DWORD FDevApiSigs[NUM_FDEV_APIS] = {
FNSIG3(DW, DW, DW), // ProcNotify
FNSIG0(),
FNSIG4(PTR, DW, PTR, DW), // RegisterDevice
FNSIG1(DW), // DeregisterDevice
FNSIG0(), // CloseAllDeviceHandles - deleted; was unused and a security risk
FNSIG4(PTR, DW, DW, DW), // CreateDeviceHandle
FNSIG0(), // unsupported and moved to thunk - was LoadFSD
FNSIG0(), // ActivateDevice - obsolete; translated in coredll
FNSIG1(DW), // DeactivateDevice
FNSIG0(), // unsupported and moved to thunk - was LoadFSDEx
FNSIG2(DW, PTR), // GetDeviceByIndex
FNSIG1(DW), // CeResyncFilesys
FNSIG4(PTR, PTR, DW, PTR),// ActivateDeviceEx
FNSIG0(), // moved to filesys - was RequestDeviceNotifications
FNSIG0(), // moved to filesys - was StopDeviceNotifications
FNSIG0(), // GetDevicePathFromPnp - obsolete; implemented in coredll
FNSIG3(DW, DW, DW), // ResourceCreateList
FNSIG4(DW, DW, DW, DW), // ResourceAdjust
FNSIG3(PTR, DW, PTR), // GetSystemPowerState
FNSIG3(PTR, DW, DW), // SetSystemPowerState
FNSIG5(PTR, DW, DW, PTR, DW), // SetPowerRequirement
FNSIG1(DW), // ReleasePowerRequirement
FNSIG2(DW, DW), // RequestPowerNotifications
FNSIG1(DW), // StopPowerNotifications
FNSIG0(), // deprecated - VetoPowerNotification
FNSIG3(PTR, DW, DW), // DevicePowerNotify
FNSIG4(PTR, PTR, PTR, DW), // RegisterPowerRelationship
FNSIG1(DW), // ReleasePowerRelationship
FNSIG3(PTR, DW, DW), // SetDevicePower
FNSIG3(PTR, DW, PTR), // GetDevicePower
FNSIG0(), // moved to filesys - was AdvertiseInterface
FNSIG4(DW, DW, DW, DW), // ResourceMarkAsShareable
FNSIG4(DW, DW, DW, DW), // ResourceRequestEx
FNSIG1(DW), // ResourceDestroyList
FNSIG2(DW, PTR), // GetDeviceInformationByDeviceHandle
FNSIG5(DW, DW, PTR, PTR, PTR), // EnumDeviceInterfaces
};
const PFNVOID DevFileApiMethods[] = {
(PFNVOID)DM_DevCloseFileHandle,
(PFNVOID)0,
(PFNVOID)DM_DevReadFile,
(PFNVOID)DM_DevWriteFile,
(PFNVOID)DM_DevGetFileSize,
(PFNVOID)DM_DevSetFilePointer,
(PFNVOID)DM_DevGetDeviceInformationByFileHandle,
(PFNVOID)DM_DevFlushFileBuffers,
(PFNVOID)DM_DevGetFileTime,
(PFNVOID)DM_DevSetFileTime,
(PFNVOID)DM_DevSetEndOfFile,
(PFNVOID)DM_DevDeviceIoControl,
};
#define NUM_FAPIS (sizeof(DevFileApiMethods)/sizeof(DevFileApiMethods[0]))
const DWORD DevFileApiSigs[NUM_FAPIS] = {
FNSIG1(DW), // CloseFileHandle
FNSIG0(),
FNSIG5(DW,PTR,DW,PTR,PTR), // ReadFile
FNSIG5(DW,PTR,DW,PTR,PTR), // WriteFile
FNSIG2(DW,PTR), // GetFileSize
FNSIG4(DW,DW,PTR,DW), // SetFilePointer
FNSIG2(DW,PTR), // GetDeviceInformationByFileHandle
FNSIG1(DW), // FlushFileBuffers
FNSIG4(DW,PTR,PTR,PTR), // GetFileTime
FNSIG4(DW,PTR,PTR,PTR), // SetFileTime
FNSIG1(DW), // SetEndOfFile,
FNSIG8(DW, DW, PTR, DW, PTR, DW, PTR, PTR), // DeviceIoControl
};
// This routine initializes low memory thresholds based on the amount
// of memory available when the device manager is loaded.
void InitOOMSettings()
{
SYSTEM_INFO SysInfo;
GetSystemInfo (&SysInfo);
// Calling this will set up the initial critical memory handlers and
// enable memory scavenging in the kernel
SetOOMEvent (NULL, 30, 15, 0x4000 / SysInfo.dwPageSize,
(0x2000 / SysInfo.dwPageSize) > 2 ?
(0x2000 / SysInfo.dwPageSize) : 2);
}
//
// ProcessAutoDeregisterDevs - called from the main thread as part of periodic clean up.
//
// Auto deregister devices are devices that need to be deregistered in a context that will
// avoid a deadlock between the device CS and the loader CS.
// A device gets marked as auto-deregister when DeviceIoControl is called with
// dwControlCode==IOCTL_DEVICE_AUTODEREGISTER.
// An example of an auto deregister device is the console device driver.
//
void ProcessAutoDeregisterDevs(void)
{
BOOL bFreedOne;
fsdev_t* lpdev;
do {
EnterCriticalSection(&g_devcs);
bFreedOne = FALSE;
// walking the chain of *active* devs, looking for ALL that want to deregister
// don't care about refcount. That's handled by deregister & the dying-devs list
DEBUGMSG(ZONE_DYING, (L"Device:ProcessAutoDeregisterDevs About to walk main list\r\n"));
for (lpdev = (fsdev_t *)g_DevChain.Flink;
lpdev != (fsdev_t *)&g_DevChain;
lpdev = (fsdev_t *)(lpdev->list.Flink)) {
if (lpdev->wFlags & DF_AUTO_DEREGISTER) {
LeaveCriticalSection(&g_devcs);
// don't remove from list. DeregisterDevice will do that
DEBUGMSG(ZONE_DYING, (L"Device:ProcessAutoDeregisterDevs FOUND auto-deregister lpdev=%x\r\n", lpdev));
DM_DeregisterDevice((HANDLE)lpdev);
bFreedOne = TRUE;
break;
// break out of inner loop, because after letting go of critsec &
// freeing lpdev, our loop traversal is not valid anymore. So start over
}
}
if (lpdev == (fsdev_t *)&g_DevChain) {
LeaveCriticalSection(&g_devcs);
break;
}
} while (bFreedOne);
// keep looping as long as we have something to do
} // ProcessAutoDeregisterDevs
//
// ProcessDyingDevs - called from the main thread as part of periodic clean up.
//
// Dying devices are devices for which DeregisterDevice has been called while there are
// still open handles to the device. This can occur when a PC card storage device has been
// removed. A filesystem driver may be in the middle of mounting the device, so we can't free
// the device structure just yet; it is put on the g_DyingDevs list.
//
void ProcessDyingDevs(void)
{
BOOL bFreedOne;
fsdev_t* lpdev;
LPEXCEPTION_POINTERS pep;
DEBUGMSG(ZONE_DYING, (L"Device:ProcessDyingDevs About to walk dying list\r\n"));
while (!IsListEmpty(&g_DyingDevs))
{
EnterCriticalSection(&g_devcs);
bFreedOne = FALSE;
// walk the chain of dying devs (already deregistered. just waiting to be unloaded)
for (lpdev = (fsdev_t *)g_DyingDevs.Flink;
lpdev != (fsdev_t *)&g_DyingDevs;
lpdev = (fsdev_t *)lpdev->list.Flink) {
if (!lpdev->dwRefCnt) {
RemoveEntryList((PLIST_ENTRY)lpdev);
LeaveCriticalSection(&g_devcs);
DEBUGMSG(ZONE_DYING, (L"Device:ProcessDyingDevs FOUND dying dev lpdev=%x\r\n", lpdev));
if(lpdev->fnPreDeinit != NULL) {
__try {
lpdev->fnDeinit(lpdev->dwData);
}
__except(pep = GetExceptionInformation(), ReportFault(pep,0), EXCEPTION_EXECUTE_HANDLER ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -