Exemple #1
0
// Initialize the control device
void NeoInitControlDevice()
{
	char name_kernel[MAX_SIZE];
	char name_win32[MAX_SIZE];
	UNICODE *unicode_kernel, *unicode_win32;
	DEVICE_OBJECT *control_device_object;
	NDIS_HANDLE ndis_control_handle;
	NDIS_DEVICE_OBJECT_ATTRIBUTES t;

	if (ctx == NULL)
	{
		return;
	}

	// Initialize the dispatch table
	NeoZero(ctx->DispatchTable, sizeof(PDRIVER_DISPATCH) * IRP_MJ_MAXIMUM_FUNCTION);

	// Register the handler
	ctx->DispatchTable[IRP_MJ_CREATE] =
		ctx->DispatchTable[IRP_MJ_CLOSE] =
		ctx->DispatchTable[IRP_MJ_READ] =
		ctx->DispatchTable[IRP_MJ_WRITE] =
		ctx->DispatchTable[IRP_MJ_DEVICE_CONTROL] = NeoNdisDispatch;
	ctx->Opened = FALSE;

	// Generate the device name
	sprintf(name_kernel, NDIS_NEO_DEVICE_NAME, ctx->HardwareID);
	unicode_kernel = NewUnicode(name_kernel);
	sprintf(name_win32, NDIS_NEO_DEVICE_NAME_WIN32, ctx->HardwareID);
	unicode_win32 = NewUnicode(name_win32);

	// Register the device
	NeoZero(&t, sizeof(t));
	t.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
	t.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
	t.Header.Size = NDIS_SIZEOF_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
	t.DeviceName = GetUnicode(unicode_kernel);
	t.SymbolicName = GetUnicode(unicode_win32);
	t.MajorFunctions = ctx->DispatchTable;

	NdisRegisterDeviceEx(ndis_miniport_driver_handle, &t,
		&control_device_object,
		&ndis_control_handle);

	ctx->NdisControlDevice = control_device_object;
	ctx->NdisControl = ndis_control_handle;

	// Initialize the display name
	if (strlen(ctx->HardwareID) > 11)
	{
		sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw + 11);
	}
	else
	{
		sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw);
	}
}
Exemple #2
0
// Check the cable connection state
void NeoCheckConnectState()
{
	NDIS_STATUS_INDICATION t;
	NDIS_LINK_STATE state;
	if (ctx == NULL || ctx->NdisMiniport == NULL)
	{
		return;
	}

	NeoZero(&t, sizeof(t));
	t.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
	t.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
	t.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;

	t.SourceHandle = ctx->NdisMiniport;

	NeoZero(&state, sizeof(state));
	state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	state.Header.Revision = NDIS_LINK_STATE_REVISION_1;
	state.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1;

	state.MediaDuplexState = NdisPauseFunctionsSendAndReceive;
	state.XmitLinkSpeed = state.RcvLinkSpeed = max_speed;
	state.PauseFunctions = NdisPauseFunctionsUnsupported;

	t.StatusCode = NDIS_STATUS_LINK_STATE;
	t.StatusBuffer = &state;
	t.StatusBufferSize = sizeof(NDIS_LINK_STATE);

	if (keep_link == false)
	{
		if (ctx->ConnectedOld != ctx->Connected || ctx->ConnectedForce)
		{
			ctx->ConnectedForce = FALSE;
			ctx->ConnectedOld = ctx->Connected;
			if (ctx->Halting == FALSE)
			{
				state.MediaConnectState = ctx->Connected ? MediaConnectStateConnected : MediaConnectStateDisconnected;
				NdisMIndicateStatusEx(ctx->NdisMiniport, &t);
			}
		}
	}
	else
	{
		if (ctx->ConnectedForce)
		{
			ctx->ConnectedForce = false;

			if (ctx->Halting == FALSE)
			{
				state.MediaConnectState = MediaConnectStateConnected;
				NdisMIndicateStatusEx(ctx->NdisMiniport, &t);
			}
		}
	}
}
Exemple #3
0
// Win32 driver entry point
NDIS_STATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
{
	NDIS_MINIPORT_CHARACTERISTICS miniport;
	ULONG os_major_ver = 0, os_minor_ver = 0;

	// Initialize the Neo library
	if (NeoInit() == FALSE)
	{
		// Initialization Failed
		return STATUS_UNSUCCESSFUL;
	}

	g_is_win8 = false;

#ifndef	NDIS30_MINIPORT
	// Get the OS version
	PsGetVersion(&os_major_ver, &os_minor_ver, NULL, NULL);

	if (os_major_ver >= 7 || (os_major_ver == 6 && os_minor_ver >= 2))
	{
		// Windows 8
		g_is_win8 = true;
	}
#endif	// NDIS30_MINIPORT

	// Initialize the NDIS wrapper
	NdisMInitializeWrapper(&ctx->NdisWrapper, DriverObject, RegistryPath, NULL);
	ndis_wrapper_handle = ctx->NdisWrapper;

	// Register a NDIS miniport driver
	NeoZero(&miniport, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
	miniport.MajorNdisVersion = NEO_NDIS_MAJOR_VERSION;
	miniport.MinorNdisVersion = NEO_NDIS_MINOR_VERSION;

	// Register the handler
	miniport.InitializeHandler = NeoNdisInit;
	miniport.HaltHandler = NeoNdisHalt;
	miniport.QueryInformationHandler = NeoNdisQuery;
	miniport.ResetHandler = NeoNdisReset;
	miniport.SetInformationHandler = NeoNdisSet;

#ifndef	NDIS30_MINIPORT
	miniport.SendPacketsHandler = NeoNdisSendPackets;
#else	// NDIS30_MINIPORT
	miniport.SendHandler = NULL;
#endif	// NDIS30_MINIPORT

	if (NG(NdisMRegisterMiniport(ctx->NdisWrapper, &miniport, sizeof(NDIS_MINIPORT_CHARACTERISTICS))))
	{
		// Registration failure
		return STATUS_UNSUCCESSFUL;
	}

	// Initialization success
	return STATUS_SUCCESS;
}
Exemple #4
0
// Initialization
BOOL NeoInit()
{
	// Initialize the context
	NeoZero(ctx, sizeof(NEO_CTX));

	// Initialize the status information
	NeoNewStatus(&ctx->Status);

	return TRUE;
}
Exemple #5
0
// Release the status information
void NeoFreeStatus(NEO_STATUS *s)
{
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	// Memory initialization
	NeoZero(s, sizeof(NEO_STATUS));
}
Exemple #6
0
// Clear to zero by memory allocation
void *NeoZeroMalloc(UINT size)
{
	void *p = NeoMalloc(size);
	if (p == NULL)
	{
		// Memory allocation failure
		return NULL;
	}
	// Clear to zero
	NeoZero(p, size);
	return p;
}
Exemple #7
0
// Shutdown
void NeoShutdown()
{
	if (ctx == NULL)
	{
		// Uninitialized
		return;
	}

	// Relaese the status information
	NeoFreeStatus(&ctx->Status);

	NeoZero(ctx, sizeof(NEO_CTX));
}
Exemple #8
0
// Initialize the control device
void NeoInitControlDevice()
{
	char name_kernel[MAX_SIZE];
	char name_win32[MAX_SIZE];
	UNICODE *unicode_kernel, *unicode_win32;
	DEVICE_OBJECT *control_device_object;
	NDIS_HANDLE ndis_control_handle;

	if (ctx == NULL)
	{
		return;
	}

	// Initialize the dispatch table
	NeoZero(ctx->DispatchTable, sizeof(PDRIVER_DISPATCH) * IRP_MJ_MAXIMUM_FUNCTION);

	// Register the handler
	ctx->DispatchTable[IRP_MJ_CREATE] =
		ctx->DispatchTable[IRP_MJ_CLOSE] =
		ctx->DispatchTable[IRP_MJ_READ] =
		ctx->DispatchTable[IRP_MJ_WRITE] =
		ctx->DispatchTable[IRP_MJ_DEVICE_CONTROL] = NeoNdisDispatch;
	ctx->Opened = FALSE;

	// Generate the device name
	sprintf(name_kernel, NDIS_NEO_DEVICE_NAME, ctx->HardwareID);
	unicode_kernel = NewUnicode(name_kernel);
	sprintf(name_win32, NDIS_NEO_DEVICE_NAME_WIN32, ctx->HardwareID);
	unicode_win32 = NewUnicode(name_win32);

	// Register the Device
	NdisMRegisterDevice(ctx->NdisWrapper, GetUnicode(unicode_kernel),
		GetUnicode(unicode_win32), ctx->DispatchTable,
		&control_device_object,
		&ndis_control_handle);

	ctx->NdisControlDevice = control_device_object;
	ctx->NdisControl = ndis_control_handle;

	// Initialize the display name
	if (strlen(ctx->HardwareID) > 11)
	{
		sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw + 11);
	}
	else
	{
		sprintf(ctx->HardwarePrintableID, NDIS_NEO_HARDWARE_ID, ctx->HardwareID_Raw);
	}
}
Exemple #9
0
// Create a packet buffer
PACKET_BUFFER *NeoNewPacketBuffer()
{
	PACKET_BUFFER *p;
	NET_BUFFER_LIST_POOL_PARAMETERS p1;

	// Memory allocation
	p = NeoZeroMalloc(sizeof(PACKET_BUFFER));

	// Create a NET_BUFFER_LIST pool
	NeoZero(&p1, sizeof(p1));
	p1.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	p1.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
	p1.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
	p1.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
	p1.fAllocateNetBuffer = TRUE;
	p1.DataSize = NEO_MAX_PACKET_SIZE;
	p->NetBufferListPool = NdisAllocateNetBufferListPool(NULL, &p1);

	// Create a NET_BUFFER_LIST
	p->NetBufferList = NdisAllocateNetBufferList(p->NetBufferListPool, 0, 0);

	return p;
}
Exemple #10
0
// Initialization handler of adapter
NDIS_STATUS NeoNdisInitEx(NDIS_HANDLE MiniportAdapterHandle,
						  NDIS_HANDLE MiniportDriverContext,
						  PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters)
{
	NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES attr;
	NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES gen;
	NDIS_PM_CAPABILITIES pnpcap;

	if (ctx == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

	if (ctx->NdisMiniportDriverHandle == NULL)
	{
		ctx->NdisMiniportDriverHandle = ndis_miniport_driver_handle;
	}

	// Prevention of multiple start
	if (ctx->Initing != FALSE)
	{
		// Multiple started
		return NDIS_STATUS_FAILURE;
	}
	ctx->Initing = TRUE;

	// Examine whether it has already been initialized
	if (ctx->Inited != FALSE)
	{
		// Driver is started on another instance already.
		// VPN driver can start only one instance per one service.
		// User can start multiple drivers with different instance ID
		return NDIS_STATUS_FAILURE;
	}

	// Current value of the packet filter
	ctx->CurrentPacketFilter = NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL;

	// Initialize the adapter information
	ctx->NdisMiniport = MiniportAdapterHandle;
	ctx->NdisContext = ctx;
	ctx->HardwareStatus = NdisHardwareStatusReady;
	ctx->Halting = FALSE;
	ctx->Connected = ctx->ConnectedOld = FALSE;

	//if (keep_link == false)
	{
		ctx->ConnectedForce = TRUE;
	}

	// Read the information from the registry
	if (NeoLoadRegistory() == FALSE)
	{
		// Failure
		ctx->Initing = FALSE;
		return NDIS_STATUS_FAILURE;
	}

	// Register the device attributes
	NeoZero(&attr, sizeof(attr));
	attr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
	attr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
	attr.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
	attr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
	attr.InterfaceType = NdisInterfaceInternal;
	attr.MiniportAdapterContext = ctx->NdisContext;

	NdisMSetMiniportAttributes(ctx->NdisMiniport, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&attr);

	NeoZero(&pnpcap, sizeof(pnpcap));

	NeoZero(&gen, sizeof(gen));
	gen.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
	gen.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
	gen.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
	gen.MediaType = NdisMedium802_3;
	gen.PhysicalMediumType = NdisPhysicalMedium802_3;
	gen.MtuSize = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
	gen.MaxXmitLinkSpeed = gen.MaxRcvLinkSpeed = max_speed;
	gen.RcvLinkSpeed = gen.XmitLinkSpeed = max_speed;
	gen.MediaConnectState = MediaConnectStateDisconnected;
	gen.LookaheadSize = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
	gen.MacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_NO_LOOPBACK;
	gen.SupportedPacketFilters = NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL;
	gen.MaxMulticastListSize = NEO_MAX_MULTICASE;
	gen.MacAddressLength = NEO_MAC_ADDRESS_SIZE;
	NeoCopy(gen.PermanentMacAddress, ctx->MacAddress, NEO_MAC_ADDRESS_SIZE);
	NeoCopy(gen.CurrentMacAddress, ctx->MacAddress, NEO_MAC_ADDRESS_SIZE);
	gen.AccessType = NET_IF_ACCESS_BROADCAST;
	gen.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
	gen.ConnectionType = NET_IF_CONNECTION_DEDICATED;
	gen.IfType = IF_TYPE_ETHERNET_CSMACD;
	gen.IfConnectorPresent = TRUE;
	gen.SupportedStatistics =
		NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |
		NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |
		NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |
		NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |
		NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |
		NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |
		NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
	gen.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
	gen.AutoNegotiationFlags = NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED |
		NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED |
		NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED |
		NDIS_LINK_STATE_PAUSE_FUNCTIONS_AUTO_NEGOTIATED;
	gen.SupportedOidList = SupportedOids;
	gen.SupportedOidListLength = sizeof(SupportedOids);

	NeoZero(&pnpcap, sizeof(pnpcap));
	pnpcap.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	pnpcap.Header.Revision = NDIS_PM_CAPABILITIES_REVISION_1;
	pnpcap.Header.Size = NDIS_SIZEOF_NDIS_PM_CAPABILITIES_REVISION_1;
	pnpcap.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
	pnpcap.MinPatternWakeUp  = NdisDeviceStateUnspecified;
	pnpcap.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
	gen.PowerManagementCapabilitiesEx = &pnpcap;

	NdisMSetMiniportAttributes(ctx->NdisMiniport, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&gen);

	// Initialize the received packet array
	NeoInitPacketArray();

	// Initialize the control device
	NeoInitControlDevice();

	// Start the adapter
	NeoStartAdapter();

	// Flag setting
	ctx->Initing = FALSE;
	ctx->Inited = TRUE;

	// Notify the connection state
	NeoSetConnectState(FALSE);

	return NDIS_STATUS_SUCCESS;
}
Exemple #11
0
// Win32 driver entry point
NDIS_STATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath)
{
	NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniport;
	ULONG os_major_ver = 0, os_minor_ver = 0;
	NDIS_STATUS ret;

	// Initialize the Neo library
	if (NeoInit() == FALSE)
	{
		// Initialization Failed
		return STATUS_UNSUCCESSFUL;
	}

	g_is_win8 = false;

	// Get the OS version
	PsGetVersion(&os_major_ver, &os_minor_ver, NULL, NULL);

	if (os_major_ver >= 7 || (os_major_ver == 6 && os_minor_ver >= 2))
	{
		// Windows 8
		g_is_win8 = true;
	}

	// Register a NDIS miniport driver
	NeoZero(&miniport, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS));

	miniport.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
	miniport.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
	miniport.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;

	miniport.MajorNdisVersion = NEO_NDIS_MAJOR_VERSION;
	miniport.MinorNdisVersion = NEO_NDIS_MINOR_VERSION;

	// Register the handler
	miniport.InitializeHandlerEx = NeoNdisInitEx;
	miniport.HaltHandlerEx = NeoNdisHaltEx;
	miniport.OidRequestHandler = NeoNdisOidRequest;
	miniport.ResetHandlerEx = NeoNdisResetEx;
	miniport.CheckForHangHandlerEx = NeoNdisCheckForHangEx;
	miniport.UnloadHandler = NeoNdisDriverUnload;
	miniport.SendNetBufferListsHandler = NeoNdisSendNetBufferLists;

	miniport.SetOptionsHandler = NeoNdisSetOptions;
	miniport.PauseHandler = NeoNdisPause;
	miniport.RestartHandler = NeoNdisRestart;
	miniport.ReturnNetBufferListsHandler = NeoNdisReturnNetBufferLists;
	miniport.CancelSendHandler = NeoNdisCancelSend;
	miniport.DevicePnPEventNotifyHandler = NeoNdisDevicePnPEventNotify;
	miniport.ShutdownHandlerEx = NeoNdisShutdownEx;
	miniport.CancelOidRequestHandler = NeoNdisCancelOidRequest;

	ret = NdisMRegisterMiniportDriver(DriverObject, RegistryPath,
		NULL, &miniport, &ndis_miniport_driver_handle);

	if (NG(ret))
	{
		// Registration failure
		return STATUS_UNSUCCESSFUL;
	}

	// Initialization success
	return STATUS_SUCCESS;
}
Exemple #12
0
// Read the information from the registry
BOOL NeoLoadRegistory()
{
	void *buf;
	NDIS_STATUS ret;
	UINT size;
	NDIS_HANDLE config;
	NDIS_CONFIGURATION_PARAMETER *param;
	UNICODE *name;
	ANSI_STRING ansi;
	UNICODE_STRING *unicode;
	UINT speed;
	BOOL keep;

	// Get the config handle
	NdisOpenConfiguration(&ret, &config, ctx->NdisConfig);
	if (NG(ret))
	{
		// Failure
		return FALSE;
	}

	// Read the MAC address
	NdisReadNetworkAddress(&ret, &buf, &size, config);
	if (NG(ret))
	{
		// Failure
		NdisCloseConfiguration(config);
		return FALSE;
	}

	// Copy the MAC address
	if (size != NEO_MAC_ADDRESS_SIZE)
	{
		// Invalid size
		NdisCloseConfiguration(config);
		return FALSE;
	}
	NeoCopy(ctx->MacAddress, buf, NEO_MAC_ADDRESS_SIZE);

	if (ctx->MacAddress[0] == 0x00 &&
		ctx->MacAddress[1] == 0x00 &&
		ctx->MacAddress[2] == 0x01 &&
		ctx->MacAddress[3] == 0x00 &&
		ctx->MacAddress[4] == 0x00 &&
		ctx->MacAddress[5] == 0x01)
	{
		// Special MAC address
		UINT ptr32 = (UINT)((UINT64)ctx);

		ctx->MacAddress[0] = 0x00;
		ctx->MacAddress[1] = 0xAD;
		ctx->MacAddress[2] = ((UCHAR *)(&ptr32))[0];
		ctx->MacAddress[3] = ((UCHAR *)(&ptr32))[1];
		ctx->MacAddress[4] = ((UCHAR *)(&ptr32))[2];
		ctx->MacAddress[5] = ((UCHAR *)(&ptr32))[3];
	}

	// Initialize the key name of the device name
	name = NewUnicode("MatchingDeviceId");

	// Read the hardware ID
	NdisReadConfiguration(&ret, &param, config, GetUnicode(name), NdisParameterString);
	FreeUnicode(name);
	if (NG(ret))
	{
		// Failure
		NdisCloseConfiguration(config);
		return FALSE;
	}
	// Type checking
	if (param->ParameterType != NdisParameterString)
	{
		// Failure
		NdisCloseConfiguration(config);
		return FALSE;
	}
	unicode = &param->ParameterData.StringData;

	// Prepare a buffer for ANSI string
	NeoZero(&ansi, sizeof(ANSI_STRING));
	ansi.MaximumLength = MAX_SIZE - 1;
	ansi.Buffer = NeoZeroMalloc(MAX_SIZE);

	// Convert to ANSI string
	NdisUnicodeStringToAnsiString(&ansi, unicode);
	// Copy
	strcpy(ctx->HardwareID, ansi.Buffer);
	strcpy(ctx->HardwareID_Raw, ctx->HardwareID);
	// Convert to upper case
	_strupr(ctx->HardwareID);
	// Release the memory
	NeoFree(ansi.Buffer);

	// Read the bit rate
	name = NewUnicode("MaxSpeed");
	NdisReadConfiguration(&ret, &param, config, GetUnicode(name), NdisParameterInteger);
	FreeUnicode(name);

	if (NG(ret) || param->ParameterType != NdisParameterInteger)
	{
		speed = NEO_MAX_SPEED_DEFAULT;
	}
	else
	{
		speed = param->ParameterData.IntegerData * 10000;
	}

	max_speed = speed;

	// Read the link keeping flag
	name = NewUnicode("KeepLink");
	NdisReadConfiguration(&ret, &param, config, GetUnicode(name), NdisParameterInteger);
	FreeUnicode(name);

	if (NG(ret) || param->ParameterType != NdisParameterInteger)
	{
		keep = false;
	}
	else
	{
		keep = (param->ParameterData.IntegerData == 0 ? false : true);
	}

	keep_link = keep;

	// Close the Config handle
	NdisCloseConfiguration(config);

	return TRUE;
}
Exemple #13
0
// Information acquisition handler of adapter
NDIS_STATUS NeoNdisQuery(NDIS_HANDLE MiniportAdapterContext,
					NDIS_OID Oid,
					void *InformationBuffer,
					ULONG InformationBufferLength,
					ULONG *BytesWritten,
					ULONG *BytesNeeded)
{
	NDIS_MEDIUM media;
	void *buf;
	UINT value32;
	USHORT value16;
	UINT size;
	NDIS_STATISTICS_INFO stat;
	NDIS_INTERRUPT_MODERATION_PARAMETERS intp;

	if (ctx == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

	// Initialization
	size = sizeof(UINT);
	value32 = value16 = 0;
	buf = &value32;

	// Branch processing
	switch (Oid)
	{
	case OID_GEN_SUPPORTED_LIST:
		// Return a list of supported OID
		buf = SupportedOids;
		size = sizeof(SupportedOids);
		break;

	case OID_GEN_MAC_OPTIONS:
		// Ethernet option
		value32 = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
			NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | NDIS_MAC_OPTION_NO_LOOPBACK;
		break;

	case OID_GEN_HARDWARE_STATUS:
		// Hardware state
		buf = &ctx->HardwareStatus;
		size = sizeof(NDIS_HARDWARE_STATUS);
		break;

	case OID_GEN_MEDIA_SUPPORTED:
	case OID_GEN_MEDIA_IN_USE:
		// Type of media
		media = NdisMedium802_3;
		buf = &media;
		size = sizeof(NDIS_MEDIUM);
		break;

	case OID_GEN_CURRENT_LOOKAHEAD:
	case OID_GEN_MAXIMUM_LOOKAHEAD:
		// Read-ahead available size
		value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
		break;

	case OID_GEN_MAXIMUM_FRAME_SIZE:
		// Maximum frame size
		value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE - NEO_MIN_PACKET_SIZE;
		break;

	case OID_GEN_MAXIMUM_TOTAL_SIZE:
	case OID_GEN_TRANSMIT_BLOCK_SIZE:
	case OID_GEN_RECEIVE_BLOCK_SIZE:
		// Maximum packet size
		value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE;
		break;

	case OID_GEN_TRANSMIT_BUFFER_SPACE:
	case OID_GEN_RECEIVE_BUFFER_SPACE:
		// Buffer size
		value32 = NEO_MAX_PACKET_SIZE_ANNOUNCE * NEO_MAX_PACKET_EXCHANGE;
		break;

	case OID_GEN_LINK_SPEED:
		// Communication speed
		value32 = (UINT)(max_speed / 100);
		break;

	case OID_GEN_VENDOR_ID:
		// Vendor ID
		NeoCopy(&value32, ctx->MacAddress, 3);
		value32 &= 0xFFFFFF00;
		value32 |= 0x01;
		break;

	case OID_GEN_VENDOR_DESCRIPTION:
		// Hardware ID
		buf = ctx->HardwarePrintableID;
		size = (UINT)strlen(ctx->HardwarePrintableID) + 1;
		break;

	case OID_GEN_DRIVER_VERSION:
		// Driver version
		value16 = ((USHORT)NEO_NDIS_MAJOR_VERSION << 8) | NEO_NDIS_MINOR_VERSION;
		buf = &value16;
		size = sizeof(USHORT);
		break;

	case OID_GEN_VENDOR_DRIVER_VERSION:
		// Vendor driver version
		value16 = ((USHORT)NEO_NDIS_MAJOR_VERSION << 8) | NEO_NDIS_MINOR_VERSION;
		buf = &value16;
		size = sizeof(USHORT);
		break;

	case OID_802_3_PERMANENT_ADDRESS:
	case OID_802_3_CURRENT_ADDRESS:
		// MAC address
		buf = ctx->MacAddress;
		size = NEO_MAC_ADDRESS_SIZE;
		break;

	case OID_802_3_MAXIMUM_LIST_SIZE:
		// Number of multicast
		value32 = NEO_MAX_MULTICASE;
		break;

	case OID_GEN_MAXIMUM_SEND_PACKETS:
		// Number of packets that can be sent at a time
		value32 = NEO_MAX_PACKET_EXCHANGE;
		break;

	case OID_GEN_XMIT_OK:
		// Number of packets sent
		value32 = ctx->Status.NumPacketSend;
		break;

	case OID_GEN_RCV_OK:
		// Number of received packets
		value32 = ctx->Status.NumPacketRecv;
		break;

	case OID_GEN_XMIT_ERROR:
		// Number of transmission error packets
		value32 = ctx->Status.NumPacketSendError;
		break;

	case OID_GEN_RCV_ERROR:
		// Number of error packets received
		value32 = ctx->Status.NumPacketRecvError;
		break;

	case OID_GEN_RCV_NO_BUFFER:
		// Number of reception buffer shortage occurrences
		value32 = ctx->Status.NumPacketRecvNoBuffer;
		break;

	case OID_802_3_RCV_ERROR_ALIGNMENT:
		// Number of errors
		value32 = 0;
		break;

	case OID_GEN_MEDIA_CONNECT_STATUS:
		// Cable connection state
		NeoCheckConnectState();
		if (keep_link == false)
		{
			value32 = ctx->Connected ? NdisMediaStateConnected : NdisMediaStateDisconnected;
		}
		else
		{
			value32 = NdisMediaStateConnected;
		}
		break;

	case OID_802_3_XMIT_ONE_COLLISION:
	case OID_802_3_XMIT_MORE_COLLISIONS:
		// Number of collisions
		value32 = 0;
		break;

	case OID_GEN_CURRENT_PACKET_FILTER:
		// Current settings of the packet filter
		value32 = ctx->CurrentPacketFilter;
		break;

/*	case OID_GEN_PROTOCOL_OPTIONS:
		// Current value of the protocol option
		value32 = ctx->CurrentProtocolOptions;
		break;*/

	case OID_GEN_STATISTICS:
		// Statistics (NDIS 6.0)
		NeoZero(&stat, sizeof(stat));
		buf = &stat;
		size = sizeof(stat);

		stat.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
		stat.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
		stat.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
		stat.SupportedStatistics =
			NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |
			NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |
			NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |
			NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |
			NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |
			NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |
			NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;

		stat.ifInErrors = ctx->Status.Int64NumRecvError;
		stat.ifHCInOctets = ctx->Status.Int64BytesRecvTotal;
		stat.ifHCInUcastPkts = ctx->Status.Int64NumRecvUnicast;
		stat.ifHCInBroadcastPkts = ctx->Status.Int64NumRecvBroadcast;
		stat.ifHCOutOctets = ctx->Status.Int64BytesSendTotal;
		stat.ifHCOutUcastPkts = ctx->Status.Int64NumSendUnicast;
		stat.ifHCOutBroadcastPkts = ctx->Status.Int64NumSendBroadcast;
		stat.ifOutErrors = ctx->Status.Int64NumSendError;
		stat.ifHCInUcastOctets = ctx->Status.Int64BytesRecvUnicast;
		stat.ifHCInBroadcastOctets = ctx->Status.Int64BytesRecvBroadcast;
		stat.ifHCOutUcastOctets = ctx->Status.Int64BytesSendUnicast;
		stat.ifHCOutBroadcastOctets = ctx->Status.Int64BytesSendBroadcast;
		break;

	case OID_GEN_INTERRUPT_MODERATION:
		// Interrupt Moderation (NDIS 6.0)
		NeoZero(&intp, sizeof(intp));
		buf = &intp;
		size = sizeof(intp);

		intp.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
		intp.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
		intp.Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
		intp.InterruptModeration = NdisInterruptModerationNotSupported;
		break;

	default:
		// Unknown OID
		*BytesWritten = 0;
		return NDIS_STATUS_INVALID_OID;
	}

	if (size > InformationBufferLength)
	{
		// Undersize
		*BytesNeeded = size;
		*BytesWritten = 0;
		return NDIS_STATUS_INVALID_LENGTH;
	}

	// Data copy
	NeoCopy(InformationBuffer, buf, size);
	*BytesWritten = size;

	return NDIS_STATUS_SUCCESS;
}