📄 devfile.c
字号:
}
return retval;
}
// This routine implements ReadFile() for device drivers. It calls
// the device's Read() entry point to obtain the data and manages
// the driver's refcount appropriately.
BOOL
DM_DevReadFile(fsopendev_t *fsodev, LPVOID buffer, DWORD nBytesToRead, LPDWORD lpNumBytesRead,
LPOVERLAPPED lpOverlapped)
{
BOOL retval = FALSE;
DWORD dodec = 0;
LPEXCEPTION_POINTERS pep;
buffer = MapCallerPtr(buffer,nBytesToRead);
__try {
if (!fsodev->lpDev)
SetLastError(ERROR_INVALID_HANDLE_STATE);
else {
OpenAddRef(fsodev);
dodec = 1;
if (fsodev->lpDev->wFlags & DF_DYING) { //Dying Device.
*lpNumBytesRead = 0xffffffff;
SetLastError(ERROR_DEVICE_REMOVED);
}
else {
*lpNumBytesRead = fsodev->lpDev->fnRead(fsodev->dwOpenData,buffer,nBytesToRead);
}
OpenDelRef(fsodev);
dodec = 0;
if (*lpNumBytesRead == 0xffffffff) {
retval = FALSE;
*lpNumBytesRead = 0;
} else
retval = TRUE;
}
} __except (pep = GetExceptionInformation(), ReportFault(pep,0), EXCEPTION_EXECUTE_HANDLER) {
if (dodec)
OpenDelRef(fsodev);
SetLastError(ERROR_INVALID_PARAMETER);
}
return retval;
}
// This routine implements WriteFile() for device drivers. It calls
// the device's Write() entry point to send the data and manages
// the driver's refcount appropriately.
BOOL
DM_DevWriteFile(fsopendev_t *fsodev, LPCVOID buffer, DWORD nBytesToWrite, LPDWORD lpNumBytesWritten,
LPOVERLAPPED lpOverlapped)
{
BOOL retval = FALSE;
DWORD dodec = 0;
LPEXCEPTION_POINTERS pep;
buffer =(LPCVOID)MapCallerPtr((LPVOID)buffer,nBytesToWrite);
__try {
if (!fsodev->lpDev)
SetLastError(ERROR_INVALID_HANDLE_STATE);
else {
OpenAddRef(fsodev);
dodec = 1;
if (fsodev->lpDev->wFlags & DF_DYING) { //Dying Device.
*lpNumBytesWritten = 0xffffffff;
retval = FALSE;
SetLastError(ERROR_DEVICE_REMOVED);
}
else {
*lpNumBytesWritten = fsodev->lpDev->fnWrite(fsodev->dwOpenData,buffer,nBytesToWrite);
}
OpenDelRef(fsodev);
dodec = 0;
if (*lpNumBytesWritten == 0xffffffff)
*lpNumBytesWritten = 0;
else
retval = TRUE;
}
} __except (pep = GetExceptionInformation(), ReportFault(pep,0), EXCEPTION_EXECUTE_HANDLER) {
if (dodec)
OpenDelRef(fsodev);
SetLastError(ERROR_INVALID_PARAMETER);
}
return retval;
}
// This routine implements SetFilePointer() for device drivers. It calls
// the device's Seek() entry point and manages the driver's refcount
// appropriately.
DWORD DM_DevSetFilePointer(fsopendev_t *fsodev, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod) {
DWORD retval = 0xffffffff;
DWORD dodec = 0;
__try {
if (!fsodev->lpDev)
SetLastError(ERROR_INVALID_HANDLE_STATE);
else {
OpenAddRef(fsodev);
dodec = 1;
if (fsodev->lpDev->wFlags & DF_DYING) { //Dying Device.
retval = 0xffffffff;
SetLastError(ERROR_DEVICE_REMOVED);
}
else {
retval = fsodev->lpDev->fnSeek(fsodev->dwOpenData,lDistanceToMove,dwMoveMethod);
}
OpenDelRef(fsodev);
dodec = 0;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
if (dodec)
OpenDelRef(fsodev);
SetLastError(ERROR_INVALID_PARAMETER);
}
return retval;
}
// This routine implements DeviceIoControl() for device drivers. It calls
// the device's IOControl() entry point and manages the driver's refcount
// appropriately. Note that some IOCTLs (such as IOCTL_DEVICE_AUTODEREGISTER)
// are handled by the Device Manager and are not passed on to the driver.
BOOL
DM_DevDeviceIoControl(fsopendev_t *fsodev, DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
BOOL retval = FALSE;
DWORD dodec = 0;
LPEXCEPTION_POINTERS pep;
lpInBuf = MapCallerPtr(lpInBuf,nInBufSize);
lpOutBuf = MapCallerPtr(lpOutBuf,nOutBufSize);
__try {
if (!fsodev->lpDev)
SetLastError(ERROR_INVALID_HANDLE_STATE);
else {
if(dwIoControlCode == IOCTL_DEVICE_AUTODEREGISTER) {
fsopendev_t *fsTrav;
EnterCriticalSection(&g_devcs);
// Only allow the auto-unload if we were loaded with RegisterDevice() and if
// the caller is trusted.
for(fsTrav = g_lpOpenDevs; fsTrav != NULL; fsTrav = fsTrav->nextptr) {
if(fsTrav == fsodev) {
break;
}
}
// do sanity checks
if(fsTrav == NULL) {
// can't find the handle
SetLastError(ERROR_INVALID_HANDLE);
} else if(PSLGetCallerTrust() != OEM_CERTIFY_TRUST) {
// untrusted caller can't set the auto-deregistered flag
SetLastError(ERROR_ACCESS_DENIED);
} else if((fsodev->lpDev->wFlags & DF_REGISTERED) == 0) {
// only devices loaded by RegisterDevice() can be auto-deregistered
SetLastError(ERROR_INVALID_PARAMETER);
} else {
// NOTE: This IOCTL is here to avoid a deadlock between (a) a DllMain calling
// DeregisterDevice (and hence trying to acquire the device CS *after* the
// loader CS and (b) Various other paths in this file where we acquire the
// device CS *before* the Loader CS (by calling LoadLib, FreeLib etc).
// See WinCE#4165. Hence this code path must NOT acquire the device CS!!
DEBUGMSG(ZONE_DYING, (L"DM_DevDeviceIoControl:IOCTL_DEVICE_AUTODEREGISTER. lpdev=%x\r\n", fsodev->lpDev));
fsodev->lpDev->wFlags |= DF_AUTO_DEREGISTER;
retval = TRUE;
// signal the main device (dying-devs-handler) thread
SetEvent(g_hCleanEvt);
}
LeaveCriticalSection(&g_devcs);
}
else {
OpenAddRef(fsodev);
dodec = 1;
if (fsodev->lpDev->wFlags & DF_DYING) { //Dying Device.
retval = FALSE;
SetLastError(ERROR_DEVICE_REMOVED);
}
else {
retval = fsodev->lpDev->fnControl(fsodev->dwOpenData,dwIoControlCode,lpInBuf,nInBufSize,lpOutBuf,nOutBufSize,lpBytesReturned);
}
OpenDelRef(fsodev);
dodec = 0;
}
}
} __except (pep = GetExceptionInformation(), ReportFault(pep,0), EXCEPTION_EXECUTE_HANDLER) {
if (dodec)
OpenDelRef(fsodev);
SetLastError(ERROR_INVALID_PARAMETER);
}
return retval;
}
// unimplemented handle-based PSL function
DWORD DM_DevGetFileSize(fsopendev_t *fsodev, LPDWORD lpFileSizeHigh) {
SetLastError(ERROR_INVALID_FUNCTION);
return 0xffffffff;
}
// unimplemented handle-based PSL function
BOOL DM_DevGetDeviceInformationByFileHandle(fsopendev_t *fsodev, PDEVMGR_DEVICE_INFORMATION pdi)
{
fsopendev_t *fsTrav;
DWORD dwStatus;
BOOL fOk;
if(fsodev == NULL || pdi == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
EnterCriticalSection(&g_devcs);
// look for the device file handle in the list
dwStatus = ERROR_INVALID_HANDLE;
for(fsTrav = g_lpOpenDevs; fsTrav != NULL; fsTrav = fsTrav->nextptr) {
if(fsTrav == fsodev) {
if(fsodev->lpDev != NULL) {
dwStatus = ERROR_SUCCESS;
}
break;
}
}
// load the information structure
if(dwStatus == ERROR_SUCCESS) {
dwStatus = I_GetDeviceInformation(fsodev->lpDev, pdi);
}
LeaveCriticalSection(&g_devcs);
if(dwStatus != ERROR_SUCCESS) {
SetLastError(dwStatus);
fOk = FALSE;
} else {
fOk = TRUE;
}
return fOk;
}
// unimplemented handle-based PSL function
BOOL DM_DevFlushFileBuffers(fsopendev_t *fsodev) {
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
// unimplemented handle-based PSL function
BOOL DM_DevGetFileTime(fsopendev_t *fsodev, LPFILETIME lpCreation, LPFILETIME lpLastAccess, LPFILETIME lpLastWrite) {
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
// unimplemented handle-based PSL function
BOOL DM_DevSetFileTime(fsopendev_t *fsodev, CONST FILETIME *lpCreation, CONST FILETIME *lpLastAccess, CONST FILETIME *lpLastWrite) {
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
// unimplemented handle-based PSL function
BOOL DM_DevSetEndOfFile(fsopendev_t *fsodev) {
SetLastError(ERROR_INVALID_FUNCTION);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -