📄 ul_wdbase.c
字号:
cn=count; while(cn>0) { while(!ul_di_adjust(&opdata->data)) { if(!(blk=ul_alloc_blk(opdata->udrv))) {count-=cn;cn=0;break;}; RtlZeroMemory(UL_BLK_NDATA(blk),UL_BLK_SIZE); opdata->data.blk->next=blk; }; len=ul_di_atonce(&opdata->data); if(len>cn) len=cn; RtlCopyMemory(ul_di_byte(&opdata->data),buf,len); ul_di_add(&opdata->data,len); buf+=len; cn-=len; }; if((unsigned)opdata->data.pos>UL_BLK_HEAD(opdata->data.head_blk).len) UL_BLK_HEAD(opdata->data.head_blk).len=opdata->data.pos; *pcount=count-cn; return 0;};//-------------------------------------------------------------------//// deffered proccessing///* notice about new message in udrv->proc_bll */VOID ulan_bottom_dpc(IN PKDPC Dpc,IN PVOID contex, IN PVOID arg1,IN PVOID arg2){ ul_mem_blk *message; ul_drv *udrv=(ul_drv *)contex; if(udrv->magic!=UL_DRV_MAGIC) { UL_PRINTF("ulan_bottom_dpc : BAD udrv magic !!!"); return; } #ifdef ENABLE_UL_IRQ_STALE_WDG ul_irq_stale_wdg_cnt=0; #endif /* ENABLE_UL_IRQ_STALE_WDG */ LOG_MESSAGES("ulan_bottom_dpc : announcing messages\n"); while(udrv->proc_bll.first||uld_test_dfl(udrv,ASK_BOTTOM)) { /* more Dpc can be started simultaneously on NT SMP box */ if(uld_test_and_set_dfl(udrv,IN_BOTTOM)) { LOG_MESSAGES("ulan_bottom_dpc : else is already in"); return; } uld_clear_dfl(udrv,ASK_BOTTOM); if(uld_test_dfl(udrv,CHECK_FILT)){ uld_clear_dfl(udrv,CHECK_FILT); check_for_filtnew(udrv); } while((message=udrv->proc_bll.first)) { int i; ul_bll_move_mes(&udrv->opan_bll,message); i=ulan_proc_arrived(udrv,message); LOG_MESSAGES("ulan_bottom_dpc : message sent to %d recchains\n",i); }; uld_atomic_clear_dfl(udrv,IN_BOTTOM); }};PIRP xch_pending_irp(PIRP *irp_ptr, PIRP new_irp){ PIRP old_irp; UL_DRV_LOCK_FINI UL_DRV_LOCK; old_irp=*irp_ptr; *irp_ptr=new_irp; UL_DRV_UNLOCK; return old_irp;}void del_pending_irp(PIRP *irp_ptr, PIRP del_irp){ PIRP old_irp; UL_DRV_LOCK_FINI UL_DRV_LOCK; if(del_irp==*irp_ptr) *irp_ptr=NULL; UL_DRV_UNLOCK;}void wake_and_xch_pending_irp(PIRP *irp_ptr, PIRP new_irp, NTSTATUS status){ PIRP old_irp; old_irp=xch_pending_irp(irp_ptr,new_irp); if(old_irp!=NULL){ old_irp->IoStatus.Status=status; IoCompleteRequest(old_irp,IO_NO_INCREMENT); }}/* PDRIVER_CANCEL IoSetCancelRoutine(Irp,CancelRoutine);*/void ulan_cancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION irpStack; ul_opdata *opdata; PIRP old_irp; LOG_FILEIO("uLan: Irp Cancelled\n"); irpStack = IoGetCurrentIrpStackLocation (Irp); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); }else if(Irp==opdata->wait_irp){ del_pending_irp(&opdata->wait_irp,Irp); } Irp->IoStatus.Information = 0; Irp->IoStatus.Status=STATUS_CANCELLED; IoCompleteRequest(Irp,IO_NO_INCREMENT);}//---------------------------------------------------------------------------////// Routine Description:// // Process the IRPs sent to this device.// // Arguments:// // DeviceObject - pointer to a device object// // Irp - pointer to an I/O Request Packet// // Return Value:// // NTSTATUS DispatchRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION irpStack; PULAN_DEVICE_EXTENSION extension; PVOID ioBuffer; ULONG inputBufferLength; ULONG outputBufferLength; ULONG ioControlCode; NTSTATUS ntStatus=0; KIRQL OldIrql; LARGE_INTEGER CurrentSystemTime; LARGE_INTEGER ElapsedTime; ul_opdata *opdata; ul_msginfo msginfo; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; // // Get a pointer to the current location in the Irp. This is where // the function codes and parameters are located. // irpStack = IoGetCurrentIrpStackLocation (Irp); // // Get a pointer to the device extension // extension = DeviceObject->DeviceExtension; #ifdef FOR_WIN_WDM if(!extension||(extension->State<=STATE_ALL_BELOW_FAIL)||!extension->flag_CHIPOK){ uLan_DbgPrint ("uLan: DeviceObject initialization not finished\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } #endif /* FOR_WIN_WDM */ // // Get the pointer to the input/output buffer and it's length // switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: { LOG_FILEIO("uLan: IRP_MJ_CREATE\n"); if(irpStack->FileObject==NULL) { uLan_DbgPrint ("uLan: Open called without FileObject\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } if(irpStack->FileObject->FsContext) { uLan_DbgPrint ("uLan: FsContext already used\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } if(!(opdata=MALLOC(sizeof(ul_opdata)))) { uLan_DbgPrint ("uLan: Cannot allocate op_data\n"); Irp->IoStatus.Status=STATUS_NO_MEMORY; break; } irpStack->FileObject->FsContext=opdata; opdata->file=irpStack->FileObject; if((ntStatus=ul_drv_open(extension,opdata))) { LOG_FILEIO ("uLan: ul_drv_open failed\n"); Irp->IoStatus.Status=ntStatus; FREE(opdata); irpStack->FileObject->FsContext=NULL; break; } break; } case IRP_MJ_CLOSE: { LOG_FILEIO("uLan: IRP_MJ_CLOSE\n"); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } wake_and_xch_pending_irp(&opdata->wait_irp,NULL,STATUS_UNSUCCESSFUL); if((ntStatus=ul_drv_close(extension,opdata))) { LOG_FILEIO("uLan: ul_drv_close failed\n"); Irp->IoStatus.Status=ntStatus; } irpStack->FileObject->FsContext=NULL; FREE(opdata); break; } case IRP_MJ_READ: { LOG_FILEIO("uLan: IRP_MJ_READ\n"); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } ntStatus=ulan_read(extension,opdata, Irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.Read.Length, irpStack->Parameters.Read.ByteOffset, &Irp->IoStatus.Information); if(ntStatus) { LOG_FILEIO("uLan: ul_drv_read failed\n"); Irp->IoStatus.Status=ntStatus; } break; } case IRP_MJ_WRITE: { LOG_FILEIO("uLan: IRP_MJ_WRITE\n"); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } ntStatus=ulan_write(extension,opdata, Irp->AssociatedIrp.SystemBuffer, irpStack->Parameters.Read.Length, irpStack->Parameters.Read.ByteOffset, &Irp->IoStatus.Information); if(ntStatus) { LOG_FILEIO("uLan: ul_drv_write failed\n"); Irp->IoStatus.Status=ntStatus; } break; } case IRP_MJ_CLEANUP: { LOG_FILEIO("uLan: IRP_MJ_CLEANUP\n"); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } wake_and_xch_pending_irp(&opdata->wait_irp,NULL,STATUS_UNSUCCESSFUL); break; } case IRP_MJ_DEVICE_CONTROL: { LOG_FILEIO("uLan: IRP_MJ_DEVICE_CONTROL - "); opdata=irpStack->FileObject->FsContext; if(!opdata||(opdata->magic!=ULOP_MAGIC)) { uLan_DbgPrint ("uLan: corrupted opdata !!!!\n"); Irp->IoStatus.Status=STATUS_UNSUCCESSFUL; break; } ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; ioBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (ioControlCode) { case UL_DRV_VER : LOG_FILEIO("UL_DRV_VER\n"); if (outputBufferLength < sizeof(ULONG)) { Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } *(ULONG *)ioBuffer = UL_DRV_VERCODE; Irp->IoStatus.Information = sizeof(ULONG); break; case UL_NEWMSG : LOG_FILEIO("UL_NEWMSG\n"); if (inputBufferLength < sizeof(ul_msginfo)) { LOG_FILEIO("uLan: newmsg shorten msginfo !!!!\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } if((ntStatus=ulan_newmsg(opdata,ioBuffer))) { LOG_FILEIO("uLan: newmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } break; case UL_TAILMSG : LOG_FILEIO("UL_TAILMSG\n"); if (inputBufferLength < sizeof(ul_msginfo)) { LOG_FILEIO("uLan: tailmsg shorten msginfo !!!!\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } if((ntStatus=ulan_tailmsg(opdata,ioBuffer))) { LOG_FILEIO("uLan: tailmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } break; case UL_FREEMSG : LOG_FILEIO("UL_FREEMSG\n"); if((ntStatus=ulan_freemsg(opdata))&~0x7fffffff) { LOG_FILEIO("uLan: freemsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } if (outputBufferLength >= sizeof(ULONG)) { *(ULONG *)ioBuffer = ntStatus; Irp->IoStatus.Information = sizeof(ULONG); } break; case UL_ACCEPTMSG : LOG_FILEIO("UL_ACCEPTMSG\n"); if (outputBufferLength < sizeof(ul_msginfo)) { LOG_FILEIO("uLan: acceptmsg shorten msginfo !!!!\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } if((ntStatus=ulan_acceptmsg(opdata,ioBuffer))) { LOG_FILEIO("uLan: acceptmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } else Irp->IoStatus.Information = sizeof(ul_msginfo); break; case UL_ACTAILMSG : LOG_FILEIO("UL_ACTAILMSG\n"); if (outputBufferLength < sizeof(ul_msginfo)) { LOG_FILEIO("uLan: actailmsg shorten msginfo !!!!\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } if((ntStatus=ulan_actailmsg(opdata,ioBuffer))) { LOG_FILEIO("uLan: actailmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } else Irp->IoStatus.Information = sizeof(ul_msginfo); break; case UL_ADDFILT : LOG_FILEIO("UL_ADDFILT\n"); if (inputBufferLength < sizeof(ul_msginfo)) { LOG_FILEIO("uLan: addfilt shorten msginfo !!!!\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } if((ntStatus=ulan_addfilt(opdata,ioBuffer))) { LOG_FILEIO("uLan: addfilt failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } break; case UL_ABORTMSG : LOG_FILEIO("UL_ABORTMSG\n"); if((ntStatus=ulan_abortmsg(opdata))) { LOG_FILEIO("uLan: abortmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } break; case UL_REWMSG : LOG_FILEIO("UL_REWMSG\n"); if((ntStatus=ulan_rewmsg(opdata))) { LOG_FILEIO("uLan: rewmsg failed !!!!\n"); Irp->IoStatus.Status = ntStatus; } break; case UL_INEPOLL : LOG_FILEIO("UL_INEPOLL\n"); if (outputBufferLength < sizeof(ULONG)) { Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } *(ULONG *)ioBuffer = ulan_inepoll(opdata); Irp->IoStatus.Information = sizeof(ULONG); break; case UL_WAITREC : LOG_FILEIO("UL_WAITREC\n"); if(ulan_inepoll(opdata)) break; { KIRQL OldIrql; IoAcquireCancelSpinLock(&OldIrql); IoSetCancelRoutine(Irp,&ulan_cancel); IoReleaseCancelSpinLock(OldIrql); } IoMarkIrpPending(Irp); wake_and_xch_pending_irp(&opdata->wait_irp,Irp,STATUS_UNSUCCESSFUL); return STATUS_PENDING ; case UL_KLOGBLL : LOG_FILEIO("UL_KLOGBLL\n"); printudrvbll(extension); #ifdef ENABLE_UL_MEM_CHECK printudrvoperators(extension); #endif /* ENABLE_UL_MEM_CHECK */ break; case UL_STROKE : LOG_FILEIO("UL_STROKE\n"); ulan_stroke(extension, 1); break; case UL_DEBFLG : LOG_FILEIO("UL_DEBFLG\n"); if (inputBufferLength >= sizeof(ULONG)) { uld_debug_flg=*(ULONG *)ioBuffer; break; } break; case UL_HWTEST : LOG_FILEIO("UL_HWTEST\n"); if ((outputBufferLength < sizeof(ULONG))|| (inputBufferLength < sizeof(ULONG))) { Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; break; } *(LONG *)ioBuffer = ulan_hwtest(opdata,*(ULONG *)ioBuffer); if(*(LONG *)ioBuffer<0) Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = sizeof(ULONG); break; default: { LOG_FILEIO("uLan: Unknown IRP_MJ_DEVICE_CONTROL\n"); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } } break; } default: { uLan_DbgPrint ("uLan: Unhandled IRP_MJ function\n"); Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; break; } } // // DON'T get cute and try to use the status field of // the irp in the return status. That IRP IS GONE as // soon as you call IoCompleteRequest. // ntStatus = Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); LOG_FILEIO("uLan: DisptachRoutine exit.\n"); // // We never have pending operation so always return the status code. // return ntStatus;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -