diff --git a/BasiliskII/src/Windows/b2ether/driver/DEBUG.H b/BasiliskII/src/Windows/b2ether/driver/DEBUG.H new file mode 100755 index 00000000..0a12c737 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/DEBUG.H @@ -0,0 +1,43 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if DBG + +#define IF_PACKETDEBUG(f) if (PacketDebugFlag & (f)) +extern ULONG PacketDebugFlag; + +#define PACKET_DEBUG_LOUD 0x00000001 // debugging info +#define PACKET_DEBUG_VERY_LOUD 0x00000002 // excessive debugging info + +#define PACKET_DEBUG_INIT 0x00000100 // init debugging info + +#define IF_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_LOUD ) { A } +#define IF_VERY_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { A } +#define IF_INIT_LOUD(A) IF_PACKETDEBUG( PACKET_DEBUG_INIT ) { A } + +#else + +#define IF_LOUD(A) +#define IF_VERY_LOUD(A) +#define IF_INIT_LOUD(A) + +#endif diff --git a/BasiliskII/src/Windows/b2ether/driver/MAKEFILE b/BasiliskII/src/Windows/b2ether/driver/MAKEFILE new file mode 100755 index 00000000..9c985f57 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/MAKEFILE @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF b/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF new file mode 100755 index 00000000..18a21ce7 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/OEMSETUP.INF @@ -0,0 +1,430 @@ +[Identification] +OptionType = NetService + +[Options] +B2ETHER + +[FileConstants] +UtilityInf = "UTILITY.INF" +subroutineinf = "SUBROUTN.INF" +SoftwareType = "service" +Exit_Code = 0 +NetEventDLL = "%SystemRoot%\System32\netevent.dll" +Manufacturer = "Microsoft" +ProductMajorVersion = "4" +ProductMinorVersion = "0" +ProductVersion = $(ProductMajorVersion)"."$(ProductMinorVersion) + +ProductSoftwareName = "B2Ether" +ProductSoftwareImagePath = "\SystemRoot\System32\drivers\B2Ether.sys" + +NetRuleSoftwareType = "B2Ether lmNetService ndisTransport" +NetRuleSoftwareClass = {"rasCapableTransport ndisTransport"} + +NetRuleSoftwareUse = "service yes yes" +NetRuleSoftwareBindForm = """B2Ether"" yes yes simple" + +ProductKeyName = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(ProductSoftwareName)"\CurrentVersion" +ParamKeyName = $(!NTN_ServiceBase)"\"$(ProductSoftwareName)"\Parameters" + +[GeneralConstants] +from = "" +to = "" +ExitCodeOk = 0 +ExitCodeCancel = 1 +ExitCodeFatal = 2 +KeyNull = "" +MAXIMUM_ALLOWED = 33554432 +RegistryErrorIndex = NO_ERROR +KeyProduct = "" +KeyParameters = "" +TRUE = 1 +FALSE = 0 +NoTitle = 0 +ExitState = "Active" +OldVersionExisted = $(FALSE) +DriverPath = $(!STF_NTPATH)\drivers + +[date] +Now = {} ? $(!LIBHANDLE) GetSystemDate + +[Identify] +read-syms Identification +set Status = STATUS_SUCCESSFUL +set Identifier = $(OptionType) +set Media = #("Source Media Descriptions", 1, 1) +Return $(Status) $(Identifier) $(Media) + +[ReturnOptions] + set Status = STATUS_FAILED + set OptionList = {} + set OptionTextList = {} + set LanguageList = ^(LanguagesSupported, 1) + Ifcontains(i) $($0) in $(LanguageList) + goto returnoptions + else + set Status = STATUS_NOLANGUAGE + goto finish_ReturnOptions + endif +returnoptions = + + set OptionList = ^(Options, 1) + set OptionTextList = ^(OptionsText$($0), 1) + set Status = STATUS_SUCCESSFUL +finish_ReturnOptions = + + Return $(Status) $(OptionList) $(OptionTextList) + +[InstallOption] + set Option = $($1) + set SrcDir = $($2) + set AddCopy = $($3) + set DoCopy = $($4) + set DoConfig = $($5) + set LanguageList = ^(LanguagesSupported, 1) + Ifcontains(i) $($0) NOT-IN $(LanguageList) + Return STATUS_NOLANGUAGE + endif + Debug-Output "OEMSETUP.INF: STF_CWDDIR is: "$(!STF_CWDDIR) + Debug-Output "OEMSETUP.INF: STF_LANGUAGE is: "$(!STF_LANGUAGE) + set-subst LF = "\n" + read-syms GeneralConstants + read-syms FileConstants + read-syms DialogConstants$(!STF_LANGUAGE) + ifstr(i) $(!NTN_Origination) == "NCPA" + set Continue = $(OK) + endif + read-syms FileConstants$(!STF_LANGUAGE) + detect date + set-title $(FunctionTitle) + set to = Begin + set from = Begin + set CommonStatus = STATUS_SUCCESSFUL + EndWait +Begin = + + Ifstr(i) $(!NTN_InstallMode) == deinstall + set StartLabel = removeadapter + else-Ifstr(i) $(!NTN_InstallMode) == Update + set StartLabel = UpgradeSoftware + else-Ifstr(i) $(!NTN_InstallMode) == bind + set StartLabel = bindingadapter + else-Ifstr(i) $(!NTN_InstallMode) == configure + Shell $(UtilityInf),RegistryErrorString,CANNOT_CONFIGURE_SOFTWARE + ifint $($ShellCode) != $(!SHELL_CODE_OK) + Debug-Output "OEMSETUP.INF: ShellCode error: cannot get an error string." + goto ShellCodeError + endif + set Error = $($R0) + set from = end + set to = end + goto nonfatalinfo + else + set StartLabel = installadapter + endif + set RadioDefault = 2 + set RadioIn = {$(RadioDefault)} + set from = $(fatal) + set to = $(fatal) + goto $(StartLabel) +installadapter = + + OpenRegKey $(!REG_H_LOCAL) "" $(ProductKeyName) $(MAXIMUM_ALLOWED) KeyProduct + Ifstr $(KeyProduct) != $(KeyNull) + CloseRegKey $(KeyProduct) + Shell $(UtilityInf), VerExistedDlg, $(ProductSoftwareTitle),+ + $(ProductVersion) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + Debug-Output "ShellCode error: cannot get an error string." + goto ShellCodeError + endif + goto end + endif + CloseRegKey $(KeyProduct) + goto installproduct +installproduct = + + StartWait + ifint $(OldVersionExisted) == $(FALSE) + Ifstr(i) $(DoCopy) == "YES" + Shell $(UtilityInf), DoAskSource, $(!STF_CWDDIR), $(SrcDir) YES + Ifint $($ShellCode) != $(!SHELL_CODE_OK) + Goto ShellCodeError + Else-Ifstr(i) $($R0) == STATUS_FAILED + Shell $(UtilityInf) RegistryErrorString "ASK_SOURCE_FAIL" + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + set Error = $($R0) + Goto fatal + Else-Ifstr(i) $($R0) == STATUS_USERCANCEL + Goto successful + Endif + Set SrcDir = $($R1) + Endif + install "Install-Option" + ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS + Shell $(UtilityInf) RegistryErrorString "UNABLE_COPY_FILE" + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + set Error = $($R0) + goto fatal + endif + set OEM_ABANDON_ON = TRUE + Shell $(UtilityInf), AddSoftwareComponent, $(Manufacturer), + + $(ProductSoftwareName), + + $(ProductSoftwareName), + + $(ProductSoftwareDisplayName), $(STF_CONTEXTINFNAME), + + $(ProductSoftwareImagePath), "kernel", "TDI", {}, "",+ + $(NetEventDLL) + set RegistryErrorIndex = $($R0) + Ifstr(i) $(RegistryErrorIndex) != NO_ERROR + EndWait + CloseRegKey $($R1) + CloseRegKey $($R2) + CloseRegKey $($R3) + CloseRegKey $($R4) + CloseRegKey $($R5) + goto fatalRegistry + endif + Set SoftProductKey = $($R1) + Set SoftNetRuleKey = $($R2) + Set SoftServiceKey = $($R3) + set KeyParameters = $($R4) + Set SoftLinkageKey = $($R5) + set NewValueList = {{SoftwareType,$(NoTitle),$(!REG_VT_SZ),$(SoftwareType)},+ + {MajorVersion,$(NoTitle),$(!REG_VT_DWORD),$(ProductMajorVersion)},+ + {MinorVersion,$(NoTitle),$(!REG_VT_DWORD),$(ProductMinorVersion)},+ + {Title,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareTitle)},+ + {Description,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareDescription)},+ + {ServiceName,$(NoTitle),$(!REG_VT_SZ),$(ProductSoftwareName)},+ + {InstallDate,$(NoTitle),$(!REG_VT_DWORD),*($(Now),1)}} + Shell $(UtilityInf), AddValueList, $(SoftProductKey), $(NewValueList) + set RegistryErrorIndex = $($R0) + Ifstr $(RegistryErrorIndex) != NO_ERROR + CloseRegKey $(SoftProductKey) + CloseRegKey $(SoftNetRuleKey) + CloseRegKey $(SoftServiceKey) + CloseRegKey $(SoftLinkageKey) + CloseRegKey $(KeyParameters) + goto fatalRegistry + endif + set NewValueList = {{type ,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareType)}, + + {use ,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareUse)}, + + {bindform,$(NoTitle),$(!REG_VT_SZ),$(NetRuleSoftwareBindForm)}, + + {InfOption,$(NoTitle),$(!REG_VT_SZ),$(Option)}} + Shell $(UtilityInf), AddValueList, $(SoftNetRuleKey), $(NewValueList) + set RegistryErrorIndex = $($R0) + Ifstr $(RegistryErrorIndex) != NO_ERROR + CloseRegKey $(SoftProductKey) + CloseRegKey $(SoftNetRuleKey) + CloseRegKey $(SoftServiceKey) + CloseRegKey $(SoftLinkageKey) + CloseRegKey $(KeyParameters) + goto fatalRegistry + endif + Set NewValueList = {{Author,$(NoTitle),$(!REG_VT_SZ),"Lauri Pesonen"}} + Shell $(UtilityInf), AddValueList, $(KeyParameters), $(NewValueList) + Ifstr $(RegistryErrorIndex) != NO_ERROR + CloseRegKey $(SoftProductKey) + CloseRegKey $(SoftNetRuleKey) + CloseRegKey $(SoftServiceKey) + CloseRegKey $(SoftLinkageKey) + goto fatalRegistry + endif + CloseRegKey $(SoftProductKey) + CloseRegKey $(SoftNetRuleKey) + CloseRegKey $(SoftServiceKey) + CloseRegKey $(SoftLinkageKey) + endif + goto writeparameters +writeparameters = + + CloseRegKey $(KeyParameters) + EndWait + goto successful +bindingadapter =+ + set Error = "Binding: Sorry, not yet implemented." + goto fatal +removeadapter = + + Shell $(UtilityInf), RemoveSoftwareComponent, $(Manufacturer), + + $(ProductSoftwareName) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + Debug-Output "ShellCode error" + goto ShellCodeError + endif + set RegistryErrorIndex = $($R0) + Ifstr(i) $(RegistryErrorIndex) != NO_ERROR + goto fatalregistry + endif + goto end +UpgradeSoftware = + + ifstr(i) $(ProductKeyName) == $(!NTN_RegBase) + OpenRegKey $(!REG_H_LOCAL) "" $(ProductKeyName) $(MAXIMUM_ALLOWED) KeyProduct + Ifstr $(KeyProduct) != $(KeyNull) + GetRegValue $(KeyProduct),"MajorVersion", VersionInfo + set Version = *($(VersionInfo), 4) + Shell $(UtilityInf), GetInfFileNameFromRegistry, $(KeyProduct) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + Debug-Output "ShellCode error" + goto ShellCodeError + endif + set !UG_Filename = $($R0) + ifstr(i) $(!UG_Filename) != "" + install "Install-Update" + ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS + goto fatal + endif + endif + SetRegValue $(KeyProduct) {MajorVersion,$(NoTitle),$(!REG_VT_SZ),$(ProductMajorVersion)} + SetRegValue $(KeyProduct) {MinorVersion,$(NoTitle),$(!REG_VT_SZ),$(ProductMinorVersion)} + ifint $(Version) != $(ProductVersion) + endif + CloseRegKey $(KeyProduct) + else + goto fatalregistry + endif + endif + goto end +successful = + + goto end +warning = + + Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), "WARNING", $(Error) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + ifstr(i) $($R1) == "OK" + goto $(to) + else-ifstr(i) $($R1) == "CANCEL" + goto $(from) + else + goto "end" + endif +nonfatalinfo = + + Set CommonStatus = STATUS_USERCANCEL + Set Severity = STATUS + goto nonfatalmsg +nonfatal = + + Set Severity = NONFATAL + goto nonfatalmsg +nonfatalmsg = + + ifstr(i) $(Error) == "" + Shell $(UtilityInf) RegistryErrorString "SETUP_FAIL" + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + set Error = $($R0) + endif + Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), $(Severity), $(Error) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + ifstr(i) $($R1) == "OK" + goto $(from) + else + goto "end" + endif +fatalregistry = + + Shell $(UtilityInf) RegistryErrorString $(RegistryErrorIndex) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + set Error = $($R0) + goto fatal +fatal = + + ifstr(i) $(Error) == "" + Shell $(UtilityInf) RegistryErrorString "SETUP_FAIL" + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + set Error = $($R0) + endif + Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), "FATAL", $(Error) + ifint $($ShellCode) != $(!SHELL_CODE_OK) + goto ShellCodeError + endif + goto setfailed +ShellCodeError = + + set DlgType = "MessageBox" + set STF_MB_TITLE = $(ShellCodeErrorTitle) + set STF_MB_TEXT = $(ShellCodeErrorText) + set STF_MB_TYPE = 1 + set STF_MB_ICON = 3 + set STF_MB_DEF = 1 + ui start "Error Message" + goto setfailed +setfailed = + + set CommonStatus = STATUS_FAILED + ifstr(i) $(OEM_ABANDON_ON) == TRUE + set OEM_ABANDON_ON = FALSE + goto removeadapter + endif + goto end +end = + + goto term +term = + + Return $(CommonStatus) + +[Install-Option] + set STF_VITAL = "" + ifstr(i) $(AddCopy) == "YES" + AddSectionFilesToCopyList Files-$(Option) $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers + AddSectionFilesToCopyList Files-App $(SrcDir) $(!STF_WINDOWSSYSPATH) + endif + ifstr(i) $(DoCopy) == "YES" + set !STF_NCPA_FLUSH_COPYLIST = TRUE + CopyFilesInCopyList + endif + ifstr(i) $(DoConfig) == "YES" + endif + Exit + +[Install-Update] + set STF_VITAL = "" + set STF_OVERWRITE = "VERIFYSOURCEOLDER" + AddSectionFilesToCopyList Files-$(Option) $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers + AddSectionFilesToCopyList Files-App $(SrcDir) $(!STF_WINDOWSSYSPATH) + AddSectionFilesToCopyList Files-Inf $(SrcDir) $(!STF_WINDOWSSYSPATH) + set !STF_NCPA_FLUSH_COPYLIST = TRUE + CopyFilesInCopyList + exit + +[Source Media Descriptions] +1 = "Windows NT Setup Disk #1" , TAGFILE = disk1 +2 = "Windows NT Setup CD-ROM Disk" , TAGFILE = disk2 + +[ProductType] +STF_PRODUCT = Winnt +STF_PLATFORM = I386 + +[Files-Inf] +2, oemsetup.inf, SIZE=1000, RENAME=$(!UG_Filename) + +[Files-B2Ether] +2,B2Ether.SYS , SIZE=999 + +[Files-App] + +[LanguagesSupported] +ENG + +[OptionsTextENG] +NDISPERF = "Basilisk II Ethernet Driver" + +[FileConstantsENG] +ProCaption = "Windows NT Setup" +ProCancel = "Cancel" +ProCancelMsg = "Windows NT Networking is not correctly installed. "+ + "Are you sure you want to cancel copying files?" +ProCancelCap = "Network Setup Message" +ProText1 = "Copying:" +ProText2 = "To:" +ProductSoftwareTitle = "Basilisk II Ethernet Driver" +ProductSoftwareDescription = "Adds ethernet capability to the Basilisk II Macintosh II emulator." +ProductSoftwareDisplayName = "Basilisk II Ethernet Driver" +FunctionTitle = $(ProductSoftwareTitle) +ShellCodeErrorTitle = "Error: "$(FunctionTitle) +ShellCodeErrorText = "Shell Code Error." + +[DialogConstantsENG] +Help = "&Help" +Exit = "Cancel" +OK = "OK" +HelpContext = "" +Continue = "Continue" +Cancel = "Cancel" diff --git a/BasiliskII/src/Windows/b2ether/driver/SOURCES b/BasiliskII/src/Windows/b2ether/driver/SOURCES new file mode 100755 index 00000000..e7aa2866 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/SOURCES @@ -0,0 +1,15 @@ +# MYMODE must be set + +TARGETNAME=b2ether +TARGETPATH=$(BASEDIR)\lib +TARGETTYPE=DRIVER + +TARGETLIBS=$(BASEDIR)\lib\*\$(DDKBUILDENV)\ndis.lib +INCLUDES=$(BASEDIR)\inc;$(BASEDIR)\src\network\inc;..\inc + +MSC_WARNING_LEVEL=/W3 /WX /FR /FAcs /D$(MYMODE) + +SOURCES=b2ether.c \ + b2ether_openclose.c \ + b2ether_read.c \ + b2ether_write.c diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.c b/BasiliskII/src/Windows/b2ether/driver/b2ether.c new file mode 100755 index 00000000..1119224d --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether.c @@ -0,0 +1,556 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#include "ntddpack.h" +#include "b2ether.h" + +#undef DBG +#define DBG 0 +#include "debug.h" + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ); + + +NTSTATUS +PacketReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath + ); + + +NTSTATUS +PacketCreateSymbolicLink( + IN PUNICODE_STRING DeviceName, + IN BOOLEAN Create + ); + +NTSTATUS +PacketQueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ); + + +#if DBG +ULONG PacketDebugFlag = PACKET_DEBUG_LOUD; +#endif + + +PDEVICE_EXTENSION GlobalDeviceExtension; + + +NTSTATUS DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath +) +{ + NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; + + UNICODE_STRING MacDriverName; + UNICODE_STRING UnicodeDeviceName; + + PDEVICE_OBJECT DeviceObject = NULL; + PDEVICE_EXTENSION DeviceExtension = NULL; + + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ErrorCode = STATUS_SUCCESS; + NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); + + ULONG DevicesCreated=0; + + PWSTR BindString; + PWSTR ExportString; + + PWSTR BindStringSave; + PWSTR ExportStringSave; + + NDIS_HANDLE NdisProtocolHandle; + + IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");) + + RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + + ProtocolChar.MajorNdisVersion = 3; + ProtocolChar.MinorNdisVersion = 0; + ProtocolChar.Reserved = 0; + ProtocolChar.OpenAdapterCompleteHandler = PacketOpenAdapterComplete; + ProtocolChar.CloseAdapterCompleteHandler = PacketCloseAdapterComplete; + ProtocolChar.SendCompleteHandler = PacketSendComplete; + ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete; + ProtocolChar.ResetCompleteHandler = PacketResetComplete; + ProtocolChar.RequestCompleteHandler = PacketRequestComplete; + ProtocolChar.ReceiveHandler = PacketReceiveIndicate; + ProtocolChar.ReceiveCompleteHandler = PacketReceiveComplete; + ProtocolChar.StatusHandler = PacketStatus; + ProtocolChar.StatusCompleteHandler = PacketStatusComplete; + ProtocolChar.Name = ProtoName; + + NdisRegisterProtocol( + &Status, + &NdisProtocolHandle, + &ProtocolChar, + sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); + + if (Status != NDIS_STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Packet: Failed to register protocol with NDIS\n");) + return Status; + } + + // + // Set up the device driver entry points. + // + + DriverObject->MajorFunction[IRP_MJ_CREATE] = PacketOpen; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = PacketClose; + DriverObject->MajorFunction[IRP_MJ_READ] = PacketRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = PacketWrite; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PacketCleanup; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PacketIoControl; + + DriverObject->DriverUnload = PacketUnload; + + + // + // Get the name of the Packet driver and the name of the MAC driver + // to bind to from the registry + // + + Status=PacketReadRegistry( + &BindString, + &ExportString, + RegistryPath + ); + + if (Status != STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Perf: Failed to read registry\n");) + goto RegistryError; + } + + BindStringSave = BindString; + ExportStringSave = ExportString; + + // create a device object for each entry + while (*BindString!= UNICODE_NULL && *ExportString!= UNICODE_NULL) { + + // Create a counted unicode string for both null terminated strings + RtlInitUnicodeString( + &MacDriverName, + BindString + ); + + RtlInitUnicodeString( + &UnicodeDeviceName, + ExportString + ); + + // Advance to the next string of the MULTI_SZ string + BindString += (MacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); + + ExportString += (UnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR); + + IF_LOUD(DbgPrint("Packet: DeviceName=%ws MacName=%ws\n",UnicodeDeviceName.Buffer,MacDriverName.Buffer);) + + // Create the device object + Status = IoCreateDevice( + DriverObject, + sizeof(DEVICE_EXTENSION), + &UnicodeDeviceName, + FILE_DEVICE_PROTOCOL, + 0, + FALSE, + &DeviceObject + ); + + if (Status != STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Perf: IoCreateDevice() failed:\n");) + break; + } + + DevicesCreated++; + + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; + DeviceExtension->DeviceObject = DeviceObject; + + // Save the the name of the MAC driver to open in the Device Extension + DeviceExtension->AdapterName=MacDriverName; + + if (DevicesCreated == 1) { + DeviceExtension->BindString = BindStringSave; + DeviceExtension->ExportString = ExportStringSave; + } + + DeviceExtension->NdisProtocolHandle=NdisProtocolHandle; + } + + if (DevicesCreated > 0) { + return STATUS_SUCCESS; + } + + ExFreePool(BindStringSave); + ExFreePool(ExportStringSave); + +RegistryError: + + NdisDeregisterProtocol( + &Status, + NdisProtocolHandle + ); + + Status=STATUS_UNSUCCESSFUL; + + return(Status); +} + + +VOID PacketUnload( IN PDRIVER_OBJECT DriverObject ) +{ + PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT OldDeviceObject; + PDEVICE_EXTENSION DeviceExtension; + + NDIS_HANDLE NdisProtocolHandle; + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("Packet: Unload\n");) + + DeviceObject = DriverObject->DeviceObject; + + while (DeviceObject != NULL) { + DeviceExtension = DeviceObject->DeviceExtension; + NdisProtocolHandle = DeviceExtension->NdisProtocolHandle; + if (DeviceExtension->BindString != NULL) { + ExFreePool(DeviceExtension->BindString); + } + if (DeviceExtension->ExportString != NULL) { + ExFreePool(DeviceExtension->ExportString); + } + OldDeviceObject=DeviceObject; + DeviceObject=DeviceObject->NextDevice; + IoDeleteDevice(OldDeviceObject); + } + + NdisDeregisterProtocol( &Status, NdisProtocolHandle ); +} + + +NTSTATUS PacketIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PLIST_ENTRY RequestListEntry; + PINTERNAL_REQUEST pRequest; + ULONG FunctionCode; + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("Packet: IoControl\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; + + Open=IrpSp->FileObject->FsContext; + + RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock); + if (RequestListEntry == NULL) { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement); + pRequest->Irp=Irp; + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_PENDING; + + IF_LOUD(DbgPrint("Packet: Function code is %08lx buff size=%08lx %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);) + + if (FunctionCode == IOCTL_PROTOCOL_RESET) { + IF_LOUD(DbgPrint("Packet: IoControl - Reset request\n");) + ExInterlockedInsertTailList( + &Open->ResetIrpList, + &Irp->Tail.Overlay.ListEntry, + &Open->RequestSpinLock); + NdisReset( &Status, Open->AdapterHandle ); + + if (Status != NDIS_STATUS_PENDING) { + IF_LOUD(DbgPrint("Packet: IoControl - ResetComplte being called\n");) + PacketResetComplete( Open, Status ); + } + + } else { + // See if it is an Ndis request + PPACKET_OID_DATA OidData=Irp->AssociatedIrp.SystemBuffer; + + if (((FunctionCode == IOCTL_PROTOCOL_SET_OID) || (FunctionCode == IOCTL_PROTOCOL_QUERY_OID)) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)) + && + (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) { + + IF_LOUD(DbgPrint("Packet: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);) + + if (FunctionCode == IOCTL_PROTOCOL_SET_OID) { + pRequest->Request.RequestType=NdisRequestSetInformation; + pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid; + pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length; + } else { + pRequest->Request.RequestType=NdisRequestQueryInformation; + pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data; + pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length; + } + NdisRequest( + &Status, + Open->AdapterHandle, + &pRequest->Request + ); + } else { // buffer too small + Status=NDIS_STATUS_FAILURE; + pRequest->Request.DATA.SET_INFORMATION.BytesRead=0; + pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0; + } + + if (Status != NDIS_STATUS_PENDING) { + IF_LOUD(DbgPrint("Packet: Calling RequestCompleteHandler\n");) + PacketRequestComplete( + Open, + &pRequest->Request, + Status + ); + } + } + return(STATUS_PENDING); +} + + +VOID PacketRequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST NdisRequest, + IN NDIS_STATUS Status +) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PIRP Irp; + PINTERNAL_REQUEST pRequest; + UINT FunctionCode; + + PPACKET_OID_DATA OidData; + + IF_LOUD(DbgPrint("Packet: RequestComplete\n");) + + Open= (POPEN_INSTANCE)ProtocolBindingContext; + + pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request); + Irp=pRequest->Irp; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode; + + OidData=Irp->AssociatedIrp.SystemBuffer; + + if (FunctionCode == IOCTL_PROTOCOL_SET_OID) { + OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead; + } else { + if (FunctionCode == IOCTL_PROTOCOL_QUERY_OID) { + OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten; + } + } + + Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength; + + ExInterlockedInsertTailList( + &Open->RequestList, + &pRequest->ListElement, + &Open->RequestSpinLock); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + + +VOID PacketStatus( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize +) +{ + IF_LOUD(DbgPrint("Packet: Status Indication\n");) +} + + +VOID PacketStatusComplete( IN NDIS_HANDLE ProtocolBindingContext ) +{ + IF_LOUD(DbgPrint("Packet: StatusIndicationComplete\n");) +} + + +#if 0 +NTSTATUS PacketCreateSymbolicLink( + IN PUNICODE_STRING DeviceName, + IN BOOLEAN Create +) +{ + UNICODE_STRING UnicodeDosDeviceName; + NTSTATUS Status; + + if (DeviceName->Length < sizeof(L"\\Device\\")) { + return STATUS_UNSUCCESSFUL; + } + + RtlInitUnicodeString(&UnicodeDosDeviceName,NULL); + UnicodeDosDeviceName.MaximumLength=DeviceName->Length+sizeof(L"\\DosDevices")+sizeof(UNICODE_NULL); + UnicodeDosDeviceName.Buffer=ExAllocatePool( + NonPagedPool, + UnicodeDosDeviceName.MaximumLength + ); + if (UnicodeDosDeviceName.Buffer != NULL) { + RtlZeroMemory( UnicodeDosDeviceName.Buffer, UnicodeDosDeviceName.MaximumLength ); + RtlAppendUnicodeToString( &UnicodeDosDeviceName, L"\\DosDevices\\" ); + RtlAppendUnicodeToString( &UnicodeDosDeviceName, (DeviceName->Buffer+(sizeof("\\Device"))) ); + IF_LOUD(DbgPrint("Packet: DosDeviceName is %ws\n",UnicodeDosDeviceName.Buffer);) + if (Create) { + Status=IoCreateSymbolicLink(&UnicodeDosDeviceName,DeviceName); + } else { + Status=IoDeleteSymbolicLink(&UnicodeDosDeviceName); + } + ExFreePool(UnicodeDosDeviceName.Buffer); + } + return Status; +} +#endif + + +NTSTATUS PacketReadRegistry( + IN PWSTR *MacDriverName, + IN PWSTR *PacketDriverName, + IN PUNICODE_STRING RegistryPath +) +{ + NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE ParamTable[5]; + PWSTR Bind = L"Bind"; // LAURI: \Device\W30NT1 + PWSTR Export = L"Export"; // \Device\appletalk\W30NT1\0\0 + PWSTR Parameters = L"Parameters"; + PWSTR Linkage = L"Linkage"; + PWCHAR Path; + + Path=ExAllocatePool( PagedPool, RegistryPath->Length+sizeof(WCHAR) ); + + if (!Path) return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory( Path, RegistryPath->Length+sizeof(WCHAR) ); + RtlCopyMemory( Path, RegistryPath->Buffer, RegistryPath->Length ); + + IF_LOUD(DbgPrint("Packet: Reg path is %ws\n",RegistryPath->Buffer);) + + RtlZeroMemory( ParamTable, sizeof(ParamTable) ); + + // change to the parmeters key + ParamTable[0].QueryRoutine = NULL; + ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; + ParamTable[0].Name = Parameters; + + // change to the linkage key + ParamTable[1].QueryRoutine = NULL; + ParamTable[1].Flags = RTL_QUERY_REGISTRY_SUBKEY; + ParamTable[1].Name = Linkage; + + // Get the name of the mac driver we should bind to + ParamTable[2].QueryRoutine = PacketQueryRegistryRoutine; + ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[2].Name = Bind; + ParamTable[2].EntryContext = (PVOID)MacDriverName; + ParamTable[2].DefaultType = REG_MULTI_SZ; + + // Get the name that we should use for the driver object + ParamTable[3].QueryRoutine = PacketQueryRegistryRoutine; + ParamTable[3].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; + + ParamTable[3].Name = Export; + ParamTable[3].EntryContext = (PVOID)PacketDriverName; + ParamTable[3].DefaultType = REG_MULTI_SZ; + + Status=RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + Path, + ParamTable, + NULL, + NULL + ); + + ExFreePool(Path); + + return Status; +} + + +NTSTATUS PacketQueryRegistryRoutine( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ) + +{ + PUCHAR Buffer; + + IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");) + + if (ValueType != REG_MULTI_SZ) { + return STATUS_OBJECT_NAME_NOT_FOUND; + } + + Buffer=ExAllocatePool(NonPagedPool,ValueLength); + if(!Buffer) return STATUS_INSUFFICIENT_RESOURCES; + + RtlCopyMemory( Buffer, ValueData, ValueLength ); + + *((PUCHAR *)EntryContext)=Buffer; + + return STATUS_SUCCESS; +} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.dsp b/BasiliskII/src/Windows/b2ether/driver/b2ether.dsp new file mode 100755 index 00000000..c724f24d --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether.dsp @@ -0,0 +1,109 @@ +# Microsoft Developer Studio Project File - Name="b2ether" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=b2ether - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "b2ether.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "b2ether.mak" CFG="b2ether - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "b2ether - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "b2ether - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "b2ether - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f b2ether.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "b2ether.sys" +# PROP BASE Bsc_Name "b2ether.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "ddkbuild free D:\BasiliskII\src\Windows\b2ether\driver" +# PROP Rebuild_Opt "-cf" +# PROP Target_File "b2ether.sys" +# PROP Bsc_Name "b2ether.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "b2ether - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f b2ether.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "b2ether.sys" +# PROP BASE Bsc_Name "b2ether.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "ddkbuild checked D:\BasiliskII\src\Windows\b2ether\driver" +# PROP Rebuild_Opt "-cf" +# PROP Target_File "b2ether.sys" +# PROP Bsc_Name "b2ether.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "b2ether - Win32 Release" +# Name "b2ether - Win32 Debug" + +!IF "$(CFG)" == "b2ether - Win32 Release" + +!ELSEIF "$(CFG)" == "b2ether - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\b2ether.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether.h +# End Source File +# Begin Source File + +SOURCE=.\b2ether_openclose.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether_read.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether_write.c +# End Source File +# Begin Source File + +SOURCE=..\OEMSETUP.INF +# End Source File +# Begin Source File + +SOURCE=.\SOURCES +# End Source File +# End Target +# End Project diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.dsw b/BasiliskII/src/Windows/b2ether/driver/b2ether.dsw new file mode 100755 index 00000000..474c03a0 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "b2ether"=.\b2ether.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.h b/BasiliskII/src/Windows/b2ether/driver/b2ether.h new file mode 100755 index 00000000..50080b74 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether.h @@ -0,0 +1,195 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MAX_REQUESTS 4 + +typedef struct _INTERNAL_REQUEST { + LIST_ENTRY ListElement; + PIRP Irp; + NDIS_REQUEST Request; +} INTERNAL_REQUEST, *PINTERNAL_REQUEST; + +// Port device extension. +typedef struct _DEVICE_EXTENSION { + PDEVICE_OBJECT DeviceObject; + NDIS_HANDLE NdisProtocolHandle; + NDIS_STRING AdapterName; + PWSTR BindString; + PWSTR ExportString; +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +typedef struct _OPEN_INSTANCE { + PDEVICE_EXTENSION DeviceExtension; + NDIS_HANDLE AdapterHandle; + NDIS_HANDLE PacketPool; + KSPIN_LOCK RcvQSpinLock; + LIST_ENTRY RcvList; + PIRP OpenCloseIrp; + KSPIN_LOCK RequestSpinLock; + LIST_ENTRY RequestList; + LIST_ENTRY ResetIrpList; + INTERNAL_REQUEST Requests[MAX_REQUESTS]; +} OPEN_INSTANCE, *POPEN_INSTANCE; + +typedef struct _PACKET_RESERVED { + LIST_ENTRY ListElement; + PIRP Irp; + PMDL pMdl; +} PACKET_RESERVED, *PPACKET_RESERVED; + + +#define ETHERNET_HEADER_LENGTH 14 +#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved)) +#define TRANSMIT_PACKETS 16 + + +VOID +PacketOpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus + ); + +VOID +PacketCloseAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + + +NDIS_STATUS +PacketReceiveIndicate( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ); + +VOID +PacketReceiveComplete( + IN NDIS_HANDLE ProtocolBindingContext + ); + + +VOID +PacketRequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST pRequest, + IN NDIS_STATUS Status + ); + +VOID +PacketSendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status + ); + + +VOID +PacketResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ); + + +VOID +PacketStatus( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN PVOID StatusBuffer, + IN UINT StatusBufferSize + ); + + +VOID +PacketStatusComplete( + IN NDIS_HANDLE ProtocolBindingContext + ); + +VOID +PacketTransferDataComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status, + IN UINT BytesTransferred + ); + + +VOID +PacketRemoveReference( + IN PDEVICE_EXTENSION DeviceExtension + ); + + +NTSTATUS +PacketCleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP FlushIrp + ); + + +NTSTATUS +PacketShutdown( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID +PacketUnload( + IN PDRIVER_OBJECT DriverObject + ); + + + +NTSTATUS +PacketOpen( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +NTSTATUS +PacketClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +NTSTATUS +PacketWrite( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +NTSTATUS +PacketRead( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +NTSTATUS +PacketIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether.vc5.unsupported.dsp b/BasiliskII/src/Windows/b2ether/driver/b2ether.vc5.unsupported.dsp new file mode 100755 index 00000000..d9c6b9c6 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether.vc5.unsupported.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="b2ether" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=b2ether - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "b2ether.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "b2ether.mak" CFG="b2ether - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "b2ether - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "b2ether - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "b2ether - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f b2ether.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "b2ether.sys" +# PROP BASE Bsc_Name "b2ether.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "ddkbuild free D:\BasiliskII\src\Windows\b2ether\driver" +# PROP Rebuild_Opt "-cf" +# PROP Target_File "b2ether.sys" +# PROP Bsc_Name "b2ether.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "b2ether - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f b2ether.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "b2ether.sys" +# PROP BASE Bsc_Name "b2ether.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "ddkbuild checked D:\BasiliskII\src\Windows\b2ether\driver" +# PROP Rebuild_Opt "-cf" +# PROP Target_File "b2ether.sys" +# PROP Bsc_Name "b2ether.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "b2ether - Win32 Release" +# Name "b2ether - Win32 Debug" + +!IF "$(CFG)" == "b2ether - Win32 Release" + +!ELSEIF "$(CFG)" == "b2ether - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\b2ether.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether.h +# End Source File +# Begin Source File + +SOURCE=.\b2ether_openclose.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether_read.c +# End Source File +# Begin Source File + +SOURCE=.\b2ether_write.c +# End Source File +# Begin Source File + +SOURCE=..\OEMSETUP.INF +# End Source File +# Begin Source File + +SOURCE=.\SOURCES +# End Source File +# End Target +# End Project diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c new file mode 100755 index 00000000..6541993d --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether_openclose.c @@ -0,0 +1,303 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#include "b2ether.h" + +#undef DBG +#define DBG 0 +#include "debug.h" + +static UINT Medium; +static NDIS_MEDIUM MediumArray=NdisMedium802_3; + +NTSTATUS PacketOpen( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) +/* + This is the dispatch routine for create/open and close requests. + These requests complete successfully. +*/ +{ + PDEVICE_EXTENSION DeviceExtension; + + POPEN_INSTANCE Open; + + PIO_STACK_LOCATION IrpSp; + + NDIS_STATUS Status; + NDIS_STATUS ErrorStatus; + + UINT i; + + IF_LOUD(DbgPrint("Packet: OpenAdapter\n");) + + DeviceExtension = DeviceObject->DeviceExtension; + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open = ExAllocatePool(NonPagedPool,sizeof(OPEN_INSTANCE)); + if (Open==NULL) { + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory( Open, sizeof(OPEN_INSTANCE) ); + + // Save or open here + IrpSp->FileObject->FsContext = Open; + Open->DeviceExtension = DeviceExtension; + Open->OpenCloseIrp = Irp; + + // Allocate a packet pool for our xmit and receive packets + NdisAllocatePacketPool( + &Status, + &Open->PacketPool, + TRANSMIT_PACKETS, + sizeof(PACKET_RESERVED)); + + if (Status != NDIS_STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Packet: Failed to allocate packet pool\n");) + ExFreePool(Open); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // list to hold irp's want to reset the adapter + InitializeListHead(&Open->ResetIrpList); + + // Initialize list for holding pending read requests + KeInitializeSpinLock(&Open->RcvQSpinLock); + InitializeListHead(&Open->RcvList); + + // Initialize the request list + KeInitializeSpinLock(&Open->RequestSpinLock); + InitializeListHead(&Open->RequestList); + + // link up the request stored in our open block + for ( i=0; iRequestList, + &Open->Requests[i].ListElement, + &Open->RequestSpinLock); + + } + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_PENDING; + + // Try to open the MAC + NdisOpenAdapter( + &Status, + &ErrorStatus, + &Open->AdapterHandle, + &Medium, + &MediumArray, + 1, + DeviceExtension->NdisProtocolHandle, + Open, + &DeviceExtension->AdapterName, + 0, + NULL); + + if (Status != NDIS_STATUS_PENDING) { + PacketOpenAdapterComplete( Open, Status, NDIS_STATUS_SUCCESS ); + } + return(STATUS_PENDING); +} + + +VOID PacketOpenAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status, + IN NDIS_STATUS OpenErrorStatus +) +{ + PIRP Irp; + POPEN_INSTANCE Open; + + IF_LOUD(DbgPrint("Packet: OpenAdapterComplete\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + Irp = Open->OpenCloseIrp; + + if (Status != NDIS_STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Packet: OpenAdapterComplete-FAILURE\n");) + NdisFreePacketPool(Open->PacketPool); + ExFreePool(Open); + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return; +} + + +NTSTATUS PacketClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) +{ + POPEN_INSTANCE Open; + NDIS_STATUS Status; + PIO_STACK_LOCATION IrpSp; + + IF_LOUD(DbgPrint("Packet: CloseAdapter\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Open = IrpSp->FileObject->FsContext; + Open->OpenCloseIrp =Irp; + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_PENDING; + + NdisCloseAdapter( &Status, Open->AdapterHandle ); + + if (Status != NDIS_STATUS_PENDING) { + PacketCloseAdapterComplete( Open, Status ); + } + + return(STATUS_PENDING); +} + +VOID PacketCloseAdapterComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status +) +{ + POPEN_INSTANCE Open; + PIRP Irp; + + IF_LOUD(DbgPrint("Packet: CloseAdapterComplete\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + Irp = Open->OpenCloseIrp; + + NdisFreePacketPool(Open->PacketPool); + ExFreePool(Open); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + + +NTSTATUS PacketCleanup( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP FlushIrp +) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PLIST_ENTRY PacketListEntry; + PNDIS_PACKET pPacket; + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("Packet: Cleanup\n");) + + IrpSp = IoGetCurrentIrpStackLocation(FlushIrp); + + Open=IrpSp->FileObject->FsContext; + + IoMarkIrpPending(FlushIrp); + FlushIrp->IoStatus.Status = STATUS_PENDING; + + // + // The open instance of the device is about to close + // We need to complete all pending Irp's + // First we complete any pending read requests + // + while ((PacketListEntry=ExInterlockedRemoveHeadList( + &Open->RcvList, + &Open->RcvQSpinLock + )) != NULL) { + + IF_LOUD(DbgPrint("Packet: CleanUp - Completeing read\n");) + + pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved); + + // complete normally + PacketTransferDataComplete( + Open, + pPacket, + NDIS_STATUS_SUCCESS, + 0 + ); + } + + // IoMarkIrpPending(FlushIrp); + // FlushIrp->IoStatus.Status = STATUS_PENDING; + + // We now place the Irp on the Reset list + ExInterlockedInsertTailList( + &Open->ResetIrpList, + &FlushIrp->Tail.Overlay.ListEntry, + &Open->RequestSpinLock); + + // Now reset the adapter, the mac driver will complete any + // pending requests we have made to it. + NdisReset( &Status, Open->AdapterHandle ); + + if (Status != NDIS_STATUS_PENDING) { + IF_LOUD(DbgPrint("Packet: Cleanup - ResetComplte being called\n");) + PacketResetComplete( Open, Status ); + } + + return(STATUS_PENDING); +} + + +VOID PacketResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status +) +{ + POPEN_INSTANCE Open; + PIRP Irp; + PLIST_ENTRY ResetListEntry; + + IF_LOUD(DbgPrint("Packet: PacketResetComplte\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + // remove the reset IRP from the list + ResetListEntry=ExInterlockedRemoveHeadList( + &Open->ResetIrpList, + &Open->RequestSpinLock + ); + +#if DBG + if (ResetListEntry == NULL) { + DbgBreakPoint(); + return; + } +#endif + + Irp = CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + IF_LOUD(DbgPrint("Packet: PacketResetComplte exit\n");) +} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c new file mode 100755 index 00000000..87ade9a9 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether_read.c @@ -0,0 +1,238 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#include "b2ether.h" + +#undef DBG +#define DBG 0 +#include "debug.h" + + +NTSTATUS PacketRead( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + PMDL pMdl; + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("Packet: Read\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open = IrpSp->FileObject->FsContext; + + if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + pMdl=IoAllocateMdl( + MmGetMdlVirtualAddress(Irp->MdlAddress), + MmGetMdlByteCount(Irp->MdlAddress), + FALSE, + FALSE, + NULL + ); + + if (!pMdl) { + IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");) + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + IoBuildPartialMdl( + Irp->MdlAddress, + pMdl, + ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH, + 0 + ); + pMdl->Next = NULL; + + // + // Try to get a packet from our list of free ones + // + NdisAllocatePacket( &Status, &pPacket, Open->PacketPool ); + + if (Status != NDIS_STATUS_SUCCESS) { + IF_LOUD(DbgPrint("Packet: Read- No free packets\n");) + IoFreeMdl(pMdl); + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + // + // Get a pointer to the packet itself + // + RESERVED(pPacket)->Irp = Irp; + RESERVED(pPacket)->pMdl = pMdl; + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_PENDING; + + // + // Attach our new MDL to the packet + // + NdisChainBufferAtFront(pPacket,pMdl); + + + // + // Put this packet in a list of pending reads. + // The receive indication handler will attemp to remove packets + // from this list for use in transfer data calls + // + ExInterlockedInsertTailList( + &Open->RcvList, + &RESERVED(pPacket)->ListElement, + &Open->RcvQSpinLock); + + return(STATUS_PENDING); +} + + +NDIS_STATUS +PacketReceiveIndicate ( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_HANDLE MacReceiveContext, + IN PVOID HeaderBuffer, + IN UINT HeaderBufferSize, + IN PVOID LookAheadBuffer, + IN UINT LookaheadBufferSize, + IN UINT PacketSize + ) + +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PIRP Irp; + PLIST_ENTRY PacketListEntry; + PNDIS_PACKET pPacket; + ULONG SizeToTransfer; + NDIS_STATUS Status; + UINT BytesTransfered; + ULONG BufferLength; + PPACKET_RESERVED Reserved; + + IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + + if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) { + return NDIS_STATUS_NOT_ACCEPTED; // NDIS_STATUS_SUCCESS; + } + + // See if there are any pending read that we can satisfy + PacketListEntry=ExInterlockedRemoveHeadList( + &Open->RcvList, + &Open->RcvQSpinLock + ); + + if (PacketListEntry == NULL) { + IF_LOUD(DbgPrint("Packet: ReceiveIndicate dropped a packet\n");) + return NDIS_STATUS_NOT_ACCEPTED; + } + + Reserved=CONTAINING_RECORD(PacketListEntry,PACKET_RESERVED,ListElement); + pPacket=CONTAINING_RECORD(Reserved,NDIS_PACKET,ProtocolReserved); + + Irp=RESERVED(pPacket)->Irp; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + // This is the length of our partial MDL + BufferLength = IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH; + + SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength; + + // copy the ethernet header into the actual readbuffer + NdisMoveMappedMemory( + MmGetSystemAddressForMdl(Irp->MdlAddress), + HeaderBuffer, + HeaderBufferSize + ); + + // Call the Mac to transfer the packet + NdisTransferData( + &Status, + Open->AdapterHandle, + MacReceiveContext, + 0, + SizeToTransfer, + pPacket, + &BytesTransfered); + + if (Status != NDIS_STATUS_PENDING) { + PacketTransferDataComplete( Open, pPacket, Status, BytesTransfered ); + } + + return NDIS_STATUS_SUCCESS; +} + +VOID PacketTransferDataComplete ( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status, + IN UINT BytesTransfered +) +{ + PIO_STACK_LOCATION IrpSp; + POPEN_INSTANCE Open; + PIRP Irp; + PMDL pMdl; + + IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");) + + Open = (POPEN_INSTANCE)ProtocolBindingContext; + Irp = RESERVED(pPacket)->Irp; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + pMdl = RESERVED(pPacket)->pMdl; + + // Free the MDL that we allocated + IoFreeMdl(pMdl); + + // recycle the packet + NdisReinitializePacket(pPacket); + + // Put the packet on the free queue + NdisFreePacket(pPacket); + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH; + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + + +VOID PacketReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) +{ +} diff --git a/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c b/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c new file mode 100755 index 00000000..4b6684ff --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/b2ether_write.c @@ -0,0 +1,103 @@ +/* + * b2ether driver -- derived from DDK packet driver sample + * + * Basilisk II (C) 1997-1999 Christian Bauer + * + * Windows platform specific code copyright (C) Lauri Pesonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "stdarg.h" +#include "ntddk.h" +#include "ntiologc.h" +#include "ndis.h" +#include "b2ether.h" + +#undef DBG +#define DBG 0 +#include "debug.h" + + +NTSTATUS PacketWrite( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +) +{ + POPEN_INSTANCE Open; + PIO_STACK_LOCATION IrpSp; + PNDIS_PACKET pPacket; + + NDIS_STATUS Status; + + IF_LOUD(DbgPrint("Packet: SendAdapter\n");) + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + Open = IrpSp->FileObject->FsContext; + + // Try to get a packet from our list of free ones + NdisAllocatePacket( &Status, &pPacket, Open->PacketPool ); + if (Status != NDIS_STATUS_SUCCESS) { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + RESERVED(pPacket)->Irp=Irp; + + // Attach the writes buffer to the packet + NdisChainBufferAtFront(pPacket,Irp->MdlAddress); + + IoMarkIrpPending(Irp); + Irp->IoStatus.Status = STATUS_PENDING; + + // Call the MAC + NdisSend( &Status, Open->AdapterHandle, pPacket ); + + if (Status != NDIS_STATUS_PENDING) { + PacketSendComplete( Open, pPacket, Status ); + } + + return(STATUS_PENDING); +} + + +VOID PacketSendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET pPacket, + IN NDIS_STATUS Status +) +{ + PIRP Irp; + + IF_LOUD(DbgPrint("Packet: SendComplete\n");) + + Irp = RESERVED(pPacket)->Irp; + + // recyle the packet + NdisReinitializePacket(pPacket); + + // Put the packet back on the free list + NdisFreePacket(pPacket); + + Irp->IoStatus.Status = Status; + + // a known bug, but I don't need this information + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} diff --git a/BasiliskII/src/Windows/b2ether/driver/sbrList.txt b/BasiliskII/src/Windows/b2ether/driver/sbrList.txt new file mode 100755 index 00000000..0b495f70 --- /dev/null +++ b/BasiliskII/src/Windows/b2ether/driver/sbrList.txt @@ -0,0 +1 @@ +/o b2ether.bsc *.sbr