📄 devfsd.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.
//
#include <windows.h>
#include <devload.h>
#include <extfile.h>
#include "devmgrp.h"
#include "devmgrif.h"
#include "devzones.h"
#ifdef DEBUG
#define SETFNAME(x) LPCWSTR pszFname = L##x
#else // DEBUG
#define SETFNAME(x)
#endif // DEBUG
#if !defined(INVALID_AFS)
#if OID_FIRST_AFS != 0
#define INVALID_AFS 0
#else
#define INVALID_AFS -1
#endif
#endif
// file system types
#define FST_LEGACY 1 // e.g., "com1:"
#define FST_DEVICE 2 // rooted in $device
#define FST_BUS 3 // rooted in $bus
// this structure manages state for file searches
typedef struct _SearchState_tag {
DeviceSearchType searchType; // how to look for a match
fsdev_t *lpdev; // last device examined
struct _SearchState_tag *pNext; // linked list of search state structures
union {
WCHAR szName[MAX_PATH]; // name or bus name
GUID guidClass; // advertised interfaces
HANDLE hParent; // parent bus driver (or NULL)
} u;
} DEVICESEARCHSTATE, *PDEVICESEARCHSTATE;
// filesystem APIs
BOOL WINAPI DEVFS_CloseVolume(DWORD dwContext);
HANDLE WINAPI DEVFS_CreateFileW(DWORD dwContext, HANDLE hProc, PCWSTR pwsFileName, DWORD dwAccess, DWORD dwShareMode, PSECURITY_ATTRIBUTES pSecurityAttributes, DWORD dwCreate, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
HANDLE WINAPI DEVFS_FindFirstFileW(DWORD dwContext, HANDLE hProc, PCWSTR pwsFileSpec, PDEVMGR_DEVICE_INFORMATION pdi);
// file searching APIs
BOOL WINAPI DEVFS_FindClose(PDEVICESEARCHSTATE pss);
BOOL WINAPI DEVFS_FindNextFileW(PDEVICESEARCHSTATE pss, PDEVMGR_DEVICE_INFORMATION pdi);
// stub functions
DWORD DEVFS_StubFunction(void);
// Device Manager filesystem APIs
static CONST PFNVOID gpfnDevFSAPIs[] = {
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)NULL,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_CreateFileW,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_FindFirstFileW,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
(PFNVOID)DEVFS_StubFunction,
};
static CONST DWORD gDevFSSigs[] = {
FNSIG1(DW), // CloseVolume
FNSIG0(), //
FNSIG0(), // CreateDirectoryW
FNSIG0(), // RemoveDirectoryW
FNSIG0(), // GetFileAttributesW
FNSIG0(), // SetFileAttributesW
FNSIG9(DW, DW, PTR, DW, DW, PTR, DW, DW, DW), // CreateFileW
FNSIG0(), // DeleteFileW
FNSIG0(), // MoveFileW
FNSIG4(DW, DW, PTR, PTR), // FindFirstFileW
FNSIG0(), // CeRegisterFileSystemNotification
FNSIG0(), // CeOidGetInfo
FNSIG0(), // PrestoChangoFileName
FNSIG0(), // CloseAllFiles
FNSIG0(), // GetDiskFreeSpace
FNSIG0(), // Notify
FNSIG0(), // CeRegisterFileSystemFunction
FNSIG0(), // FindFirstChangeNotification
FNSIG0(), // FindNextChangeNotification
FNSIG0(), // FindCloseNotification
FNSIG0(), // CeGetFileNotificationInfo
FNSIG0(), // FsIoControlW
};
static CONST PFNVOID gpfnDevFindAPIs[] = {
(PFNVOID)DEVFS_FindClose,
(PFNVOID)NULL,
(PFNVOID)DEVFS_FindNextFileW,
};
static CONST DWORD gDevFindSigs[] = {
FNSIG1(DW), // FindClose
FNSIG0(), //
FNSIG2(DW, PTR) // FindNextFileW
};
// global variables
HANDLE ghDevFSAPI;
HANDLE ghDevFileAPI;
HANDLE ghDevFindAPI;
PDEVICESEARCHSTATE gpDeviceSearchList;
extern const PFNVOID DevFileApiMethods[12];
extern const DWORD DevFileApiSigs[12];
// This routine is called when a device is deactivated. It is responsible
// for removing the device from any searches currently underway. The caller
// of this routine must hold the device manager critical section.
void
RemoveDeviceFromSearchList(fsdev_t *lpdev)
{
PDEVICESEARCHSTATE pssTrav;
for(pssTrav = gpDeviceSearchList; pssTrav != NULL; pssTrav = pssTrav->pNext) {
if(pssTrav->lpdev == lpdev) {
pssTrav->lpdev = (fsdev_t *) lpdev->list.Flink;
}
}
}
// This routine searches for a device matching the search criteria in the
// pss parameter. If it finds one, it returns information about it in pdi.
// The caller to this routine must hold the device manager critical section.
static DWORD
I_FindNextDevice(PDEVICESEARCHSTATE pss, PDEVMGR_DEVICE_INFORMATION pdi)
{
DWORD dwStatus = ERROR_SUCCESS;
fsdev_t *lpdev;
DEBUGCHK(pss != NULL);
DEBUGCHK(pdi != NULL);
// figure out where to start searching
DEBUGCHK(pss->searchType == DeviceSearchByBusName || pss->searchType == DeviceSearchByDeviceName
|| pss->searchType == DeviceSearchByGuid || pss->searchType == DeviceSearchByLegacyName
|| pss->searchType == DeviceSearchByParent);
if(pss->lpdev == NULL) {
// start search with the first device
lpdev = (fsdev_t *) g_DevChain.Flink;
} else {
// pick up where we left off
lpdev = pss->lpdev;
}
// look for a match
while(lpdev != (fsdev_t *) &g_DevChain) {
// is this device a match?
if(pss->searchType == DeviceSearchByDeviceName) {
if(lpdev->pszDeviceName != NULL) {
if(MatchesWildcardMask(wcslen(pss->u.szName), pss->u.szName, wcslen(lpdev->pszDeviceName), lpdev->pszDeviceName)) {
break;
}
} else if(pss->u.szName[0] == 0) {
break;
}
}
else if(pss->searchType == DeviceSearchByBusName) {
if(lpdev->pszBusName != NULL) {
if(MatchesWildcardMask(wcslen(pss->u.szName), pss->u.szName, wcslen(lpdev->pszBusName), lpdev->pszBusName)) {
break;
}
} else if(pss->u.szName[0] == 0) {
break;
}
}
else if(pss->searchType == DeviceSearchByLegacyName) {
if(lpdev->pszLegacyName != NULL) {
if(MatchesWildcardMask(wcslen(pss->u.szName), pss->u.szName, wcslen(lpdev->pszLegacyName), lpdev->pszLegacyName)) {
break;
}
} else if(pss->u.szName[0] == 0) {
break;
}
}
else if(pss->searchType == DeviceSearchByParent) {
if(lpdev->hParent == pss->u.hParent) {
break;
}
}
else if(pss->searchType == DeviceSearchByGuid) {
if(FindDeviceInterface(lpdev, &pss->u.guidClass) != NULL) {
break;
}
}
// on to the next device structure
lpdev = (fsdev_t *) lpdev->list.Flink;
}
if(lpdev == (fsdev_t *) &g_DevChain) {
dwStatus = ERROR_NO_MORE_FILES;
} else {
__try {
// pass back device information to the caller
dwStatus = I_GetDeviceInformation(lpdev, pdi);
if(dwStatus == ERROR_SUCCESS) {
pss->lpdev = (fsdev_t *) lpdev->list.Flink; // record where to start the next search
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
return dwStatus;
}
// This routine deallocates resources associated with a filesystem. In general
// it shouldn't be called unless there's an error during initialization.
BOOL WINAPI
DEVFS_CloseVolume(DWORD dwContext)
{
SETFNAME("DEVFS_CloseVolume");
DEBUGMSG(ZONE_FSD, (_T("%s: closing volume context %d\r\n"), pszFname, dwContext));
DEBUGCHK(dwContext == FST_DEVICE || dwContext == FST_BUS);
return TRUE;
}
// This routine opens a file handle for a device and returns it if
// successful. During the process of opening this handle the device's
// Open() entry point is invoked, so the device has the opportunity to
// create context information for this handle. This routine creates
// a handle structure for use by the device manager as well.
HANDLE WINAPI
DEVFS_CreateFileW(DWORD dwContext, HANDLE hProc, PCWSTR pwsFileName,
DWORD dwAccess, DWORD dwShareMode, PSECURITY_ATTRIBUTES pSecurityAttributes,
DWORD dwCreate, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE h = INVALID_HANDLE_VALUE;
DWORD dwStatus = ERROR_SUCCESS;
SETFNAME("DEVFS_CreateFileW");
DEBUGCHK(pwsFileName != NULL);
DEBUGMSG(ZONE_FSD, (_T("+%s('%s'): context %d, hProc 0x%08x, access 0x%x, share 0x%x, sa 0x%08x, cr/disp 0x%x, flags 0x%x, hTemplate 0x%08x\r\n"),
pszFname, pwsFileName, dwContext, hProc, dwAccess, dwShareMode, pSecurityAttributes,
dwCreate, dwFlagsAndAttributes, hTemplateFile));
if(pwsFileName == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
// skip the leading directory separator
DEBUGCHK(*pwsFileName == L'\\');
pwsFileName++;
// start checking parameters -- filesys has already done basic validation
if((dwContext != FST_DEVICE && dwContext != FST_BUS)
|| pSecurityAttributes != NULL
|| dwCreate != OPEN_EXISTING
|| hTemplateFile != NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
} else if(wcschr(pwsFileName, L'\\') != NULL) {
dwStatus = ERROR_BAD_PATHNAME;
}
// ok to open the device?
if(dwStatus == ERROR_SUCCESS) {
NameSpaceType nameType;
if(dwContext == FST_BUS) {
nameType = NtBus;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -