📄 tffs2lnx.c
字号:
if (copy_to_user(tmp, &output, sizeof(output))) \ return -EFAULT; \ return 0; \ }#define USR2KRN01(theHandle,typeOut,pSoc) \ USR2KRN_O_START(typeOut) \ ioreq.irHandle = theHandle; \ flIOctl(&ioreq); \ USR2KRN_END#define USR2KRN11(theHandle,typeIn,typeOut,pSoc) \ USR2KRN_IO_START(typeIn,typeOut) \ ioreq.irHandle = theHandle; \ flIOctl(&ioreq); \ USR2KRN_END/* returns: 0 - OK, 1 - no TFFS ioctl, <0 - error */int TffsIoctl(DeviceInfo*pDevice,int cmd,unsigned long arg){#ifdef FL_IOCTL_INTERFACE unsigned char bdtlVolume=pDevice->bHandle; IOreq ioreq; flIOctlRecord ioctlRecord; static unsigned int handle_for_ioctls = 0xffff; if ((cmd < FL_IOCTL_LNX) || (cmd > FL_IOCTL_IPL_HW_PROTECTION)) { PrintkError ("unknown IOCTL code %d passed to TrueFFS", cmd); return 1; } /* map flIOctlRecord */ if(!access_ok(VERIFY_WRITE|VERIFY_READ,(void*)arg,sizeof(flIOctlRecord))) return -EFAULT; if(copy_from_user(&ioctlRecord,(void*)arg,sizeof(flIOctlRecord))) return -EFAULT; ioreq.irData=&ioctlRecord; ioreq.irFlags=cmd; switch(cmd) { case FL_IOCTL_GET_INFO: { struct hd_geometry geometry; USR2KRN_O_START(flDiskInfoOutput); ioreq.irHandle = bdtlVolume; flIOctl(&ioreq); geometry.heads = pDevice->bHead; geometry.sectors = pDevice->bSect; geometry.cylinders = pDevice->wCyl; ((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.cylinders=geometry.cylinders; ((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.heads=geometry.heads; ((flDiskInfoOutput*)(ioctlRecord.outputRecord))->info.sectors=geometry.sectors; USR2KRN_END; } case FL_IOCTL_DEFRAGMENT: USR2KRN11(bdtlVolume,flDefragInput,flDefragOutput,pSoc); case FL_IOCTL_MOUNT_VOLUME: USR2KRN11(bdtlVolume,flMountInput,flOutputStatusRecord,pSoc);#ifdef BDK_ACCESS case FL_IOCTL_BDK_OPERATION: { void*tmp1=NULL,*tmpIn=NULL; flBDKOperationInput input; flOutputStatusRecord output; void*tmp; if(!access_ok(VERIFY_READ|VERIFY_WRITE,ioctlRecord.inputRecord,sizeof(flBDKOperationInput))) { PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok(inputRecord)"); return -EFAULT; } if(copy_from_user(&input,ioctlRecord.inputRecord,sizeof(flBDKOperationInput))) { PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_from_user(inputRecord)"); return -EFAULT; } if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord))) { PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok(outputRecord)"); return -EFAULT; } tmp=ioctlRecord.outputRecord; tmpIn=ioctlRecord.inputRecord; ioctlRecord.inputRecord=&input; ioctlRecord.outputRecord=&output; if(input.bdkStruct.bdkBuffer!=NULL) { tmp1=input.bdkStruct.bdkBuffer; input.bdkStruct.bdkBuffer=VMalloc(input.bdkStruct.length); if(input.bdkStruct.bdkBuffer==NULL) { PrintkDebug("FL_IOCTL_BDK_OPERATION:vmalloc"); return -ENOMEM; } if(!access_ok(VERIFY_WRITE|VERIFY_READ,tmp1,input.bdkStruct.length)) { vfree(input.bdkStruct.bdkBuffer); PrintkDebug("FL_IOCTL_BDK_OPERATION:access_ok"); return -EFAULT; } if(copy_from_user(input.bdkStruct.bdkBuffer,tmp1,input.bdkStruct.length)) { vfree(input.bdkStruct.bdkBuffer); PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_from_user"); return -EFAULT; } } ioreq.irHandle = handle_for_ioctls; flIOctl(&ioreq); if(input.bdkStruct.bdkBuffer!=NULL) { if(copy_to_user(tmp1,input.bdkStruct.bdkBuffer,input.bdkStruct.length)) { PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_to_user(bdkBuffer)"); vfree(input.bdkStruct.bdkBuffer); return -EFAULT; } vfree(input.bdkStruct.bdkBuffer); } /* copy flBDKOperationInput */ input.bdkStruct.bdkBuffer=tmp1; if(copy_to_user(tmpIn,&input,sizeof(flBDKOperationInput))) { if(input.bdkStruct.bdkBuffer!=NULL) vfree(input.bdkStruct.bdkBuffer); PrintkDebug("FL_IOCTL_BDK_OPERATION:copy_to_user(inputRecord)"); return -EFAULT; } if(copy_to_user(tmp,&output,sizeof(output))) return -EFAULT; return 0; }#endif /* BDK_ACCESS */ case FL_IOCTL_DELETE_SECTORS: case FL_IOCTL_READ_SECTORS: case FL_IOCTL_WRITE_SECTORS: return -EINVAL; case FL_IOCTL_BDTL_HW_PROTECTION: case FL_IOCTL_IPL_HW_PROTECTION:#ifdef BDK_ACCESS case FL_IOCTL_BINARY_HW_PROTECTION:#endif#ifdef HW_PROTECTION { flProtectionInput my_prot_in, *usr_prot_in = (flProtectionInput *)ioctlRecord.inputRecord; flProtectionOutput my_prot_out, *usr_prot_out = (flProtectionOutput *)ioctlRecord.outputRecord; if( !access_ok((VERIFY_WRITE | VERIFY_READ), usr_prot_in, sizeof(flProtectionInput)) ) return -EFAULT; if( !access_ok(VERIFY_WRITE, usr_prot_out, sizeof(flProtectionOutput))) return -EFAULT; if( copy_from_user(&my_prot_in, usr_prot_in, sizeof(flProtectionInput)) ) return -EFAULT; ioctlRecord.inputRecord = &my_prot_in; ioctlRecord.outputRecord = &my_prot_out;# ifdef BDK_ACCESS if (cmd == FL_IOCTL_BINARY_HW_PROTECTION) ioreq.irHandle = handle_for_ioctls; else# endif ioreq.irHandle = ((handle_for_ioctls != 0xffff) ? handle_for_ioctls : bdtlVolume); flIOctl (&ioreq); if( copy_to_user(usr_prot_in, &my_prot_in, sizeof(flProtectionInput)) ) return -EFAULT; if( copy_to_user(usr_prot_out, &my_prot_out,sizeof(flProtectionOutput)) ) return -EFAULT; return 0; }#else /* !HW_PROTECTION */ return -EINVAL;#endif case FL_IOCTL_OTP:#ifdef HW_OTP { void*tmp1; USR2KRN_IO_START(flOtpInput,flOutputStatusRecord); tmp1=input.buffer; input.buffer=KMalloc(input.length); if(input.buffer==NULL) return -ENOMEM; if(!access_ok(VERIFY_WRITE|VERIFY_READ,tmp1,input.length)) { kfree(input.buffer); return -EFAULT; } if(copy_from_user(input.buffer,tmp1,input.length)) { kfree(input.buffer); return -EFAULT; } ioreq.irHandle = (bdtlVolume & 0x0f); flIOctl(&ioreq); if(copy_to_user(tmp1,input.buffer,input.length)) { kfree(input.buffer); return -EFAULT; } kfree(input.buffer); USR2KRN_END; }#else /* HW_OTP */ return -EINVAL;#endif /* HW_OTP */ case FL_IOCTL_CUSTOMER_ID:#ifdef HW_OTP USR2KRN01(bdtlVolume&0x0f,flCustomerIdOutput,pSoc);#else /* HW_OTP */ return -EINVAL;#endif case FL_IOCTL_UNIQUE_ID:#ifdef HW_OTP USR2KRN01(bdtlVolume&0x0f,flUniqueIdOutput,pSoc);#else /* HW_OTP */ return -EINVAL;#endif case FL_IOCTL_NUMBER_OF_PARTITIONS: USR2KRN01(bdtlVolume&0x0f,flCountPartitionsOutput,pSoc); case FL_IOCTL_WRITE_IPL:#ifndef NO_IPL_CODE { flIPLInput iplInput; flOutputStatusRecord outputStatusRecord; void*outputStatusRecordSave,*bBufPtrSave; if(!access_ok(VERIFY_READ,ioctlRecord.inputRecord,sizeof(flIPLInput))) return -EFAULT; if(copy_from_user(&iplInput,ioctlRecord.inputRecord,sizeof(flIPLInput))) return -EFAULT; if(!access_ok(VERIFY_WRITE,ioctlRecord.outputRecord,sizeof(flOutputStatusRecord))) return -EFAULT; outputStatusRecordSave=ioctlRecord.outputRecord; ioctlRecord.inputRecord=&iplInput; ioctlRecord.outputRecord=&outputStatusRecord; bBufPtrSave=iplInput.bBufPtr; iplInput.bBufPtr=KMalloc(iplInput.sdwLength); if(iplInput.bBufPtr==NULL) return -ENOMEM; if(!access_ok(VERIFY_READ,bBufPtrSave,iplInput.sdwLength)) { kfree(iplInput.bBufPtr); return -EFAULT; } if(copy_from_user(iplInput.bBufPtr,bBufPtrSave,iplInput.sdwLength)) { kfree(iplInput.bBufPtr); return -EFAULT; } ioreq.irHandle=bdtlVolume&0x0f; flIOctl (&ioreq); kfree(iplInput.bBufPtr); if(copy_to_user(outputStatusRecordSave,&outputStatusRecord,sizeof(flOutputStatusRecord))) return -EFAULT; return 0; }#else /* NO_IPL_CODE */ return -EINVAL;#endif /* NO_IPL_CODE */ case FL_IOCTL_DEEP_POWER_DOWN_MODE: USR2KRN11(bdtlVolume&0x0f,flPowerDownInput,flOutputStatusRecord,pSoc); case FL_IOCTL_EXTENDED_ENVIRONMENT_VARIABLES:#ifdef FL_ENVIRONMENT_VARS USR2KRN11(bdtlVolume,flExtendedEnvVarsInput,flExtendedEnvVarsOutput,pSoc);#else return -EINVAL;#endif /* FL_ENVIRONMENT_VARS */ case FL_IOCTL_VERIFY_VOLUME:#ifdef VERIFY_VOLUME USR2KRN11(bdtlVolume,flVerifyVolumeInput,flVerifyVolumeOutput,pSoc);#endif case FL_IOCTL_SET_ACCESS_ROUTINE: return -EINVAL; case FL_IOCTL_GET_ACCESS_ROUTINE: return -EINVAL; case FL_IOCTL_IS_QUICK_MOUNT_VALID:# ifndef FL_NO_QUICK_MOUNT_FEATURE USR2KRN01(bdtlVolume,flGetQuickMountOutput,pSoc);# else return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */ case FL_IOCTL_WRITE_QUICK_MOUNT_INFO:# ifndef FL_NO_QUICK_MOUNT_FEATURE USR2KRN01(bdtlVolume,flOutputStatusRecord,pSoc);# else return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */ case FL_IOCTL_CLEAR_QUICK_MOUNT_INFO:# ifndef FL_NO_QUICK_MOUNT_FEATURE USR2KRN01(bdtlVolume,flOutputStatusRecord,pSoc);# else return -EINVAL;# endif /* FL_NO_QUICK_MOUNT_FEATURE */ case FL_IOCTL_FLASH_FORMAT:# ifndef FL_FORMAT_VOLUME return -EINVAL;# else { FormatParams3 formatParams3; BDTLPartitionFormatParams3 bdtl_fp [FL_VOLUMES];# ifdef BDK_ACCESS BinaryPartitionFormatParams3 bin_fp [FL_BINARY_PARTITIONS];# endif flFlashFormatInput flashFormatInput; flOutputStatusRecord outputStatusRecord; void * user_outputStatusRecord; int bdtls; /* BDTL partitions to create */ int bins; /* binary partitions to create */ PrintkDebug("TffsIoctl:FL_IOCTL_FLASH_FORMAT"); if( !access_ok(VERIFY_WRITE, ioctlRecord.outputRecord, sizeof(flOutputStatusRecord)) ) return -EFAULT; user_outputStatusRecord = ioctlRecord.outputRecord; ioctlRecord.outputRecord = &outputStatusRecord; if( !access_ok(VERIFY_READ, ioctlRecord.inputRecord, sizeof(flFlashFormatInput)) ) return -EFAULT; if( copy_from_user(&flashFormatInput, ioctlRecord.inputRecord, sizeof(flFlashFormatInput)) ) return -EFAULT; ioctlRecord.inputRecord = &flashFormatInput; if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr, sizeof(FormatParams3)) ) return -EFAULT; if( copy_from_user(&formatParams3, flashFormatInput.fpPtr, sizeof(FormatParams3)) ) return -EFAULT; /* BDTL partitions layout */ bdtls = flashFormatInput.fpPtr->noOfBDTLPartitions; if (bdtls > FL_VOLUMES) return -EINVAL; if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr->BDTLPartitionInfo, (sizeof(BDTLPartitionFormatParams3) * bdtls)) ) return -EFAULT; if( copy_from_user(bdtl_fp, flashFormatInput.fpPtr->BDTLPartitionInfo, (sizeof(BDTLPartitionFormatParams3) * bdtls)) ) return -EFAULT; flashFormatInput.fpPtr->BDTLPartitionInfo = bdtl_fp; /* binary partitions layout */ bins = flashFormatInput.fpPtr->noOfBinaryPartitions; if (bins > 0) {# ifdef BDK_ACCESS if( !access_ok(VERIFY_READ, flashFormatInput.fpPtr->binaryPartitionInfo, (sizeof(BinaryPartitionFormatParams3) * bins)) ) return -EFAULT; if( copy_from_user(bin_fp, flashFormatInput.fpPtr->binaryPartitionInfo, (sizeof(BinaryPartitionFormatParams3) * bins)) ) return -EFAULT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -