?? ul_wdbase.c
字號:
/******************************************************************* uLan Communication - uL_DRV - multiplatform uLan driver ul_wdbase.c - common Windows NT KDM and Win2k WDM driver code (C) Copyright 1996-2004 by Pavel Pisa - project originator http://cmp.felk.cvut.cz/~pisa (C) Copyright 1996-2004 PiKRON Ltd. http://www.pikron.com (C) Copyright 2002-2004 Petr Smolik The uLan driver project can be used and distributed in compliance with any of next licenses - GPL - GNU Public License See file COPYING for details. - LGPL - Lesser GNU Public License - MPL - Mozilla Public License - and other licenses added by project originator Code can be modified and re-distributed under any combination of the above listed licenses. If contributor does not agree with some of the licenses, he/she can delete appropriate line. WARNING: if you delete all lines, you are not allowed to distribute code or sources in any form. *******************************************************************/// This variable has to be initialized by RtlConvertLongToLargeInteger(0) in DriverEntryLARGE_INTEGER ULD_LARGE_INTEGER_0;//-------------------------------------------------------------------// Memory check#ifdef ENABLE_UL_MEM_CHECKvoid * ul_mem_check_malloc(size_t size){ void *ptr; ptr=ExAllocatePool(NonPagedPool,size); if(ptr) InterlockedIncrement(&ul_mem_check_counter); return ptr;}void ul_mem_check_free(void *ptr){ if(ptr) InterlockedDecrement(&ul_mem_check_counter); ExFreePool(ptr);}#endif /* ENABLE_UL_MEM_CHECK *///-------------------------------------------------------------------//// Begin FUNCTIONS//NTSTATUSulan_GetRegistryDword( IN PWCHAR RegPath, IN PWCHAR ValueName, IN OUT PULONG Value )/*++Routine Description: Obtain a Dword value from the registryArguments: RegPath -- supplies absolute registry path ValueName - Supplies the Value Name. Value - receives the REG_DWORD value.Return Value: TRUE if successfull, FALSE on fail.--*/{ UNICODE_STRING path; RTL_QUERY_REGISTRY_TABLE paramTable[2]; //zero'd second table terminates parms ULONG lDef = *Value; // default NTSTATUS status; WCHAR wbuf[ MAXIMUM_FILENAME_LENGTH ]; path.Length = 0; path.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof( WCHAR ); // MAXIMUM_FILENAME_LENGTH defined in wdm.h path.Buffer = wbuf; RtlZeroMemory(path.Buffer, path.MaximumLength); RtlMoveMemory(path.Buffer, RegPath, wcslen( RegPath) * sizeof( WCHAR )); RtlZeroMemory(paramTable, sizeof(paramTable)); paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[0].Name = ValueName; paramTable[0].EntryContext = Value; paramTable[0].DefaultType = REG_DWORD; paramTable[0].DefaultData = &lDef; paramTable[0].DefaultLength = sizeof(ULONG); status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, path.Buffer, paramTable, NULL, NULL); return status;}//-------------------------------------------------------------------// ScanForPCICard for WinNT KMD// WDM uses different technique to query VENDOR_ID and DEVICE_ID// for example PCI\VEN_1415&DEV_950A&SUBSYS_00001415&REV_00#ifdef UL_WITH_PCI#ifdef FOR_WIN_WDMBOOLEAN FindPciHWID(PWCHAR HWID, OUT pci_device_id_t **Ppci_device_id ){ PWCHAR pwcH, pwcM; WCHAR fldName; USHORT vendorID=0; USHORT deviceID=0; USHORT subvendorID=0; USHORT subdeviceID=0; ULONG val, i, c; static WCHAR PciHWIDMask[]=L"PCI\\VEN_vvvv&DEV_xxxx&SUBSYS_sssswwww"; pci_device_id_t *device_id; *Ppci_device_id=NULL; if(HWID==NULL) return FALSE; pwcH=HWID; pwcM=PciHWIDMask; while(*pwcH&&*pwcM) { if(*pwcH==*pwcM){ pwcH++; pwcM++; continue; } fldName=*pwcM; if((fldName!='v')&&(fldName!='x')&& (fldName!='s')&&(fldName!='w')) break; val=0; for(i=4;i--;){ c=*(pwcH++); pwcM++; if(c<='9') c-='0'; else if(c<='F') c=c-'A'+10; else if(c<='f') c=c-'a'+10; if(c>15) {val=0;break;} val<<=4; val+=c; } switch (fldName) { case 'v': vendorID=(USHORT)val; break; case 'x': deviceID=(USHORT)val; break; case 'w': subvendorID=(USHORT)val; break; case 's': subdeviceID=(USHORT)val; break; } }#if DBG uLan_DbgPrint("uLan: PCI - Ven %04X Dev %04X SubVen %04X SubDev %04X\n", vendorID,deviceID,subvendorID,subdeviceID);#endif for(device_id=ulan_pci_tbl;device_id->vendor;device_id++){ if((device_id->vendor!=PCI_ANY_ID)&&(device_id->vendor!=vendorID)) continue; if((device_id->device!=PCI_ANY_ID)&&(device_id->device!=deviceID)) continue; if((device_id->subvendor!=PCI_ANY_ID)&&(device_id->vendor!=subvendorID)) continue; if((device_id->subdevice!=PCI_ANY_ID)&&(device_id->device!=subdeviceID)) continue; *Ppci_device_id=device_id; return TRUE; } return FALSE;}#else /* !FOR_WIN_WDM */BOOLEAN ScanForPCICard(IN OUT PULONG PBusNumber, IN OUT PPCI_SLOT_NUMBER PSlotNumber, IN BOOLEAN FindFirst, OUT pci_device_id_t **Ppci_device_id ){ ULONG BusNumber=*PBusNumber; PCI_SLOT_NUMBER SlotNumber=*PSlotNumber; UCHAR Buffer[2*sizeof(USHORT)]; ULONG Readed=sizeof(Buffer); pci_device_id_t *device_id; while(1){ if(FindFirst){ BusNumber=0; SlotNumber.u.AsULONG=0; FindFirst=0; }else{ if(Readed>2){ SlotNumber.u.bits.FunctionNumber= (SlotNumber.u.bits.FunctionNumber+1)&7; }else{ SlotNumber.u.bits.FunctionNumber=0; } if(!SlotNumber.u.bits.FunctionNumber){ if(!Readed&&!SlotNumber.u.bits.DeviceNumber) break; SlotNumber.u.bits.DeviceNumber= (SlotNumber.u.bits.DeviceNumber+1)&0x1f; if(!SlotNumber.u.bits.DeviceNumber) BusNumber++; } } Readed=HalGetBusData(PCIConfiguration,BusNumber,SlotNumber.u.AsULONG, Buffer,sizeof(Buffer)); if(Readed==sizeof(Buffer)){ for(device_id=&ulan_pci_tbl[0];device_id->vendor;device_id++){ if((((PPCI_COMMON_CONFIG)Buffer)->VendorID==device_id->vendor)&& (((PPCI_COMMON_CONFIG)Buffer)->DeviceID==device_id->device)){ *PBusNumber=BusNumber; *PSlotNumber=SlotNumber; if(Ppci_device_id) *Ppci_device_id=device_id; return TRUE; } } } } return FALSE;} #endif /* FOR_WIN_WDM */#endif /*UL_WITH_PCI*///-------------------------------------------------------------------// WDM uses different technique to query VENDOR_ID and DEVICE_ID// for example USB\Vid_dead&Pid_1001&REV_0001#ifdef UL_WITH_USBBOOLEAN FindUsbHWID(PWCHAR HWID, OUT usb_device_id_t **Pusb_device_id ){ PWCHAR pwcH, pwcM; WCHAR fldName; USHORT vendorID=0; USHORT productID=0; ULONG val, i, c; static WCHAR UsbHWIDMask[]=L"USB\\Vid_vvvv&Pid_pppp"; usb_device_id_t *device_id; *Pusb_device_id=NULL; if(HWID==NULL) return FALSE; pwcH=HWID; pwcM=UsbHWIDMask; while(*pwcH&&*pwcM) { if(*pwcH==*pwcM){ pwcH++; pwcM++; continue; } fldName=*pwcM; if((fldName!='v')&&(fldName!='p')) break; val=0; for(i=4;i--;){ c=*(pwcH++); pwcM++; if(c<='9') c-='0'; else if(c<='F') c=c-'A'+10; else if(c<='f') c=c-'a'+10; if(c>15) {val=0;break;} val<<=4; val+=c; } switch (fldName) { case 'v': vendorID=(USHORT)val; break; case 'p': productID=(USHORT)val; break; } }#if DBG uLan_DbgPrint("uLan: USB - Ven %04X Dev %04X\n", vendorID,productID);#endif for(device_id=ulan_usb_tbl;device_id->idVendor;device_id++){ if((device_id->idVendor!=vendorID)) continue; if((device_id->idProduct!=productID)) continue; *Pusb_device_id=device_id; return TRUE; } return FALSE;}#endif /* UL_WITH_USB *///-------------------------------------------------------------------//// Initialize and free driver///* initialize new driver from given parameters */NTSTATUS ul_drv_init_ext(ul_drv *udrv, int port, int irq, int baud, long baudbase, int chip_options, int buffer_size, int my_adr){ int ret; int test_cnt; unsigned long probe_irqs; udrv->flag_IN_ISR=0; udrv->flag_ASK_ISR=0; udrv->flag_NACTIV=0; udrv->flag_CHIPOK=0; udrv->flag_IN_BOTTOM=0; udrv->flag_ASK_BOTTOM=0; udrv->flag_CHECK_FILT=0; udrv->flag_KWTKILL=0; if(buffer_size<0x2000) buffer_size=0x2000; /* init sequencer */ ul_drv_new_init_state(udrv,my_adr); /* init chip driver */ #ifdef UL_WITH_USB if((chip_options&~0xff)==UL_USB_HW_PS1){ if((ret=ul_usb_ps1_init(udrv, port, irq, baud, baudbase, chip_options))>=0){ UL_PRINTF("uLan ul_drv_new : usb_ps1\n"); } } else { #else { #endif /* UL_WITH_USB */ #ifdef UL_WITH_PCI if((chip_options&~0xff)==0x16954000){ if((ret=u950pci_init(udrv, port, irq, baud, baudbase, chip_options))>=0){ UL_PRINTF("uLan ul_drv_new : 16C954 at 0x%x\n",port); } }else #endif /* UL_WITH_PCI */ { if((ret=u510_init(udrv, port, irq, baud, baudbase, chip_options))>=0){ UL_PRINTF("uLan ul_drv_new : 82510 found at 0x%x\n",port); }else if((ret=u450_init(udrv, port, irq, baud, baudbase, chip_options))>=0){ UL_PRINTF("uLan ul_drv_new : 16450 found at 0x%x\n",port); }; } } if(ret>=0) { /* setups buffers, ports and first part of irq for sucesfully detected device */ if(ul_drv_new_start(udrv,buffer_size)>=0) return STATUS_SUCCESS; } UL_PRINTF("uLan ul_drv_new : failed to init\n"); return STATUS_INSUFFICIENT_RESOURCES;};/* destroy driver */void ul_drv_done_ext(ul_drv *udrv){ int old_CHIPOK; if(!udrv) return; old_CHIPOK=udrv->flag_CHIPOK; udrv->flag_CHIPOK=0; if(old_CHIPOK&&udrv->irq){ /* free_irq(udrv->irq,udrv)*/; /* synchronize_irq(); */ } DONE_UDRV_WDTIM(udrv); /* schedule(); */ ul_mem_done(udrv); if(old_CHIPOK) { udrv->fnc_cctrl(udrv,UL_CC_PDONE,0); };};//-------------------------------------------------------------------//// File operations//NTSTATUS ul_drv_open(ul_drv *udrv,ul_opdata *opdata){ opdata->magic=ULOP_MAGIC; opdata->message=NULL; opdata->udrv=udrv; /* init_waitqueue_head(&opdata->wqrec); */ opdata->opprew=NULL; opdata->opnext=NULL; opdata->recchain=NULL; opdata->filtchain=NULL; opdata->wait_irp=NULL; { /* add us onto list of clients of udrv */ ul_opdata *opptr; UL_DRV_LOCK_FINI UL_DRV_LOCK; opptr=udrv->operators; if(opptr) {opptr->opprew=opdata;opdata->opnext=opptr;}; UL_MB(); udrv->operators=opdata; UL_DRV_UNLOCK; }; return 0;}NTSTATUS ul_drv_close(ul_drv *udrv,ul_opdata *opdata){ ul_opchain *opmember; KIRQL OldIrql; if (opdata->message) ulan_freemsg(opdata); KeRaiseIrql(DISPATCH_LEVEL,&OldIrql); {while(InterlockedExchange(&udrv->flag_IN_BOTTOM,1))/* spinlock loop*/;} { /* delete us from list of clients of udrv */ ul_drv *udrv=opdata->udrv; ul_opdata *opptr; UL_DRV_LOCK_FINI UL_DRV_LOCK; if((opptr=opdata->opnext)) opptr->opprew=opdata->opprew; if((opptr=opdata->opprew)) opptr->opnext=opdata->opnext; else udrv->operators=opdata->opnext; UL_DRV_UNLOCK; }; InterlockedExchange(&udrv->flag_IN_BOTTOM,0); ulan_bottom_dpc(NULL,udrv,NULL,NULL); KeLowerIrql(OldIrql); while((opmember=opdata->recchain)) { del_from_opchain(&opdata->recchain,opmember); if(opmember->message) ul_dec_ref_cnt(opmember->message); FREE(opmember); }; while((opmember=opdata->filtchain)) { del_from_opchain(&opdata->filtchain,opmember); FREE(opmember); }; return 0;};NTSTATUS ulan_read(ul_drv *udrv,ul_opdata *opdata, uchar *buf, ULONG count, LARGE_INTEGER pos, PULONG pcount){ int cn; int len; if(!opdata->message) return -ENOMSG; if(opdata->data.pos+count>UL_BLK_HEAD(opdata->data.head_blk).len) count=UL_BLK_HEAD(opdata->data.head_blk).len-opdata->data.pos; cn=count; while(cn>0) { if(!ul_di_adjust(&opdata->data)) { RtlZeroMemory(buf,cn); cn=0; break; }; len=ul_di_atonce(&opdata->data); if(len>cn) len=cn; RtlCopyMemory(buf,ul_di_byte(&opdata->data),len); ul_di_add(&opdata->data,len); buf+=len; cn-=len; }; *pcount=count-cn; return 0;};NTSTATUS ulan_write(ul_drv *udrv,ul_opdata *opdata, const uchar *buf, ULONG count, LARGE_INTEGER pos, PULONG pcount){ int cn; int len; ul_mem_blk *blk; if(!opdata->message) return -ENOMSG;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -