📄 devfsd.c
字号:
} else {
nameType = NtDevice;
}
h = I_CreateDeviceHandle(pwsFileName, nameType, dwAccess, dwShareMode, hProc);
DEBUGMSG(h == INVALID_HANDLE_VALUE && ZONE_WARNING,
(_T("%s: I_CreateDeviceHandle('%s') failed for name type '%s'\r\n"),
pszFname, pwsFileName, nameType == NtBus ? L"bus" : L"device"));
}
// pass back error code if there was a problem
if(dwStatus != ERROR_SUCCESS) {
DEBUGCHK(h == INVALID_HANDLE_VALUE);
SetLastError(dwStatus);
}
DEBUGMSG(ZONE_FSD, (_T("-%s: returning handle 0x%08x, error status is %d\r\n"),
pszFname, h, dwStatus));
return h;
}
//
// This routine is used to enumerate activated devices. It can also be used to
// find devices loaded with RegisterDevice(). Even though we are registered
// as a filesys mount point, we don't want to support the "standard" file search
// because the data returned in WIN32_FIND_DATA is pretty much useless -- so
// we screen out these calls by looking for certain patterns in the name string
// and by checking the size of the pfd parameter.
//
HANDLE WINAPI DEVFS_FindFirstFileW(DWORD dwContext, HANDLE hProc, PCWSTR pwsFileSpec, PDEVMGR_DEVICE_INFORMATION pdi)
{
PDEVICESEARCHSTATE pss = NULL;
DWORD dwStatus = ERROR_INVALID_PARAMETER;
HANDLE hFind = INVALID_HANDLE_VALUE;
PCWSTR pwsSearchParam;
DWORD dwLen;
if(pdi == NULL || pwsFileSpec == NULL || *pwsFileSpec != L'\\' || dwContext != FST_DEVICE) {
goto done;
}
pwsFileSpec++; // skip leading separator
// set up search state structure
pss = LocalAlloc(0, sizeof(*pss));
pss->lpdev = NULL;
pwsSearchParam = wcschr(pwsFileSpec, L'+');
if(pwsSearchParam == NULL) {
goto done;
}
pwsSearchParam++;
dwLen = (pwsSearchParam - pwsFileSpec) - 1; // get the length of the search type without the +
DEBUGCHK(dwLen != 0);
if(wcsncmp(pwsFileSpec, L"byLegacyName", dwLen) == 0) {
pss->searchType = DeviceSearchByLegacyName;
wcsncpy(pss->u.szName, pwsSearchParam, ARRAYSIZE(pss->u.szName));
pss->u.szName[ARRAYSIZE(pss->u.szName) - 1] = 0;
}
else if(wcsncmp(pwsFileSpec, L"byDeviceName", dwLen) == 0) {
pss->searchType = DeviceSearchByDeviceName;
wcsncpy(pss->u.szName, pwsSearchParam, ARRAYSIZE(pss->u.szName));
pss->u.szName[ARRAYSIZE(pss->u.szName) - 1] = 0;
}
else if(wcsncmp(pwsFileSpec, L"byBusName", dwLen) == 0) {
pss->searchType = DeviceSearchByBusName;
wcsncpy(pss->u.szName, pwsSearchParam, ARRAYSIZE(pss->u.szName));
pss->u.szName[ARRAYSIZE(pss->u.szName) - 1] = 0;
}
else if(wcsncmp(pwsFileSpec, L"byInterfaceClass", dwLen) == 0) {
pss->searchType = DeviceSearchByGuid;
if(!ConvertStringToGuid (pwsSearchParam, &pss->u.guidClass)) {
goto done;
}
}
else if(wcsncmp(pwsFileSpec, L"byParent", dwLen) == 0) {
PWSTR pwsEnd;
pss->searchType = DeviceSearchByParent;
pss->u.hParent = (HANDLE) wcstol(pwsSearchParam, &pwsEnd, 16);
if(*pwsEnd != 0) {
goto done;
}
} else {
goto done;
}
EnterCriticalSection(&g_devcs);
// Add this search structure to the list -- do this now so
// we are notified if the currently searched device is deactivated
// while we are creating the API handle.
pss->pNext = gpDeviceSearchList;
gpDeviceSearchList = pss;
// search for the first match
__try {
dwStatus = I_FindNextDevice(pss, pdi);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
LeaveCriticalSection(&g_devcs);
// if we found a match then set up appropriately to continue
// searching with the find-next function.
if(dwStatus == ERROR_SUCCESS) {
hFind = CreateAPIHandle(ghDevFindAPI, pss);
if (hFind == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto done;
}
}
done:
if(dwStatus != ERROR_SUCCESS) {
if(pss != NULL) {
// remove it from the list
if(!DEVFS_FindClose(pss)) {
LocalFree(pss); // free memory
}
}
SetLastError(dwStatus);
hFind = INVALID_HANDLE_VALUE;
}
return hFind;
}
// ------------- file searching functions ------------------------
BOOL
DEVFS_FindNextFileW(PDEVICESEARCHSTATE pss, PDEVMGR_DEVICE_INFORMATION pdi)
{
DWORD dwStatus = ERROR_SUCCESS;
PDEVICESEARCHSTATE pssTrav;
if(pdi == NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
goto done;
}
EnterCriticalSection(&g_devcs);
// validate the search parameter
for(pssTrav = gpDeviceSearchList; pssTrav != NULL; pssTrav = pssTrav->pNext) {
if(pssTrav == pss) {
break;
}
}
if(pssTrav != pss) {
dwStatus = ERROR_INVALID_HANDLE;
} else {
__try {
dwStatus = I_FindNextDevice(pss, pdi);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
LeaveCriticalSection(&g_devcs);
done:
if(dwStatus != ERROR_SUCCESS) {
SetLastError(dwStatus);
}
return(dwStatus == ERROR_SUCCESS ? TRUE : FALSE);
}
BOOL
DEVFS_FindClose(PDEVICESEARCHSTATE pss)
{
DWORD dwStatus = ERROR_SUCCESS;
PDEVICESEARCHSTATE pssTrav, pssPrev;
DEBUGCHK(pss != NULL);
EnterCriticalSection(&g_devcs);
// validate the search state parameter
pssPrev = NULL;
for(pssTrav = gpDeviceSearchList; pssTrav != NULL; pssTrav = pssTrav->pNext) {
if(pssTrav == pss) {
break;
}
pssPrev = pssTrav;
}
// did we find it?
if(pssTrav != pss) {
dwStatus = ERROR_INVALID_HANDLE;
} else {
// remove it from the list
if(pssPrev == NULL) {
gpDeviceSearchList = pss->pNext; // first in list
} else {
pssPrev->pNext = pss->pNext; // middle or end of list
}
}
LeaveCriticalSection(&g_devcs);
// free resources if present
if(dwStatus == ERROR_SUCCESS) {
LocalFree(pss);
} else {
SetLastError(dwStatus);
}
return(dwStatus == ERROR_SUCCESS ? TRUE : FALSE);
}
// ------------- miscellaneous functions ------------------------
DWORD DEVFS_StubFunction(void)
{
return 0;
}
// this routine registers the filesystems used to access devices
BOOL
InitDeviceFilesystems(void)
{
BOOL fOk = TRUE;
SETFNAME("InitDeviceFileSystems");
DEBUGMSG(ZONE_INIT, (_T("+%s\r\n"), pszFname));
// register API sets
ghDevFSAPI = CreateAPISet("DMFS", ARRAYSIZE(gpfnDevFSAPIs), (const PFNVOID *) gpfnDevFSAPIs, gDevFSSigs);
ghDevFileAPI = CreateAPISet("DMFA", ARRAYSIZE(DevFileApiMethods), (const PFNVOID *) DevFileApiMethods, DevFileApiSigs);
RegisterAPISet(ghDevFileAPI, HT_FILE | REGISTER_APISET_TYPE);
ghDevFindAPI = CreateAPISet("DMFF", ARRAYSIZE(gpfnDevFindAPIs), (const PFNVOID *) gpfnDevFindAPIs, gDevFindSigs);
RegisterAPISet(ghDevFindAPI, HT_FIND | REGISTER_APISET_TYPE);
gpDeviceSearchList = NULL;
// did we succeed?
if(ghDevFSAPI == NULL || ghDevFileAPI == NULL || ghDevFindAPI == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("%s: couldn't register API sets\r\n"), pszFname));
if(ghDevFSAPI != NULL) CloseHandle(ghDevFSAPI);
if(ghDevFileAPI != NULL) CloseHandle(ghDevFileAPI);
if(ghDevFindAPI != NULL) CloseHandle(ghDevFindAPI);
fOk = FALSE;
}
if(fOk) {
struct {
LPCWSTR pszFSName;
DWORD dwFSContext;
int iFSIndex;
} fsInfo[] = {
{ L"$device", FST_DEVICE, INVALID_AFS },
{ L"$bus", FST_BUS, INVALID_AFS },
};
int i;
// register filesystems
for(i = 0; fOk && i < ARRAYSIZE(fsInfo); i++) {
// register filesystems
fsInfo[i].iFSIndex = RegisterAFSName(fsInfo[i].pszFSName);
if(fsInfo[i].iFSIndex == INVALID_AFS) {
DEBUGMSG(ZONE_ERROR, (_T("%s: RegisterAFSName('%s') failed %d\r\n"), pszFname,
fsInfo[i].pszFSName, GetLastError()));
fOk = FALSE;
} else {
fOk = RegisterAFSEx(fsInfo[i].iFSIndex, ghDevFSAPI, fsInfo[i].dwFSContext, AFS_VERSION, AFS_FLAG_HIDDEN);
DEBUGMSG(!fOk && ZONE_ERROR, (_T("%s: RegisterAFSEx() failed for '%s' (error %d)\r\n"),
pszFname, fsInfo[i].pszFSName, GetLastError()));
if(!fOk) {
DeregisterAFSName(fsInfo[i].iFSIndex);
}
}
}
// did we succeed?
if(!fOk) {
DEBUGCHK(i > 0);
while(i > 0) {
i--;
DeregisterAFS(fsInfo[i].iFSIndex);
DeregisterAFSName(fsInfo[i].iFSIndex);
}
}
}
DEBUGMSG(ZONE_INIT, (_T("-%s: status is %d\r\n"), pszFname, fOk));
DEBUGCHK(fOk);
return fOk;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -