diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-01-06 07:09:26 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-01-06 07:09:26 +0000 |
commit | 7452e76589c3544aeda69ca97dfcbd139dc08c09 (patch) | |
tree | e827295c0be7c812a4b4976153cb5f1f632e3216 /sys/compat/ndis/subr_pe.c | |
parent | 7a30cbbe36c3da10547bc71289118de8e9bf0798 (diff) | |
download | FreeBSD-src-7452e76589c3544aeda69ca97dfcbd139dc08c09.zip FreeBSD-src-7452e76589c3544aeda69ca97dfcbd139dc08c09.tar.gz |
- Add pe_get_message() and pe_get_messagetable() for processing
the RT_MESSAGETABLE resources that some driver binaries have.
This allows us to print error messages in ndis_syslog().
- Correct the implementation of InterlockedIncrement() and
InterlockedDecrement() -- they return uint32_t, not void.
- Correct the declarations of the 64-bit arithmetic shift
routines in subr_ntoskrnl.c (_allshr, allshl, etc...). These
do not follow the _stdcall convention: instead, they appear
to be __attribute__((regparm(3)).
- Change the implementation of KeInitializeSpinLock(). There is
no complementary KeFreeSpinLock() function, so creating a new
mutex on each call to KeInitializeSpinLock() leaks resources
when a driver is unloaded. For now, KeInitializeSpinLock()
returns a handle to the ntoskrnl interlock mutex.
- Use a driver's MiniportDisableInterrupt() and MiniportEnableInterrupt()
routines if they exist. I'm not sure if I'm doing this right
yet, but at the very least this shouldn't break any currently
working drivers, and it makes the Intel PRO/1000 driver work.
- In ndis_register_intr(), save some state that might be needed
later, and save a pointer to the driver's interrupt structure
in the ndis_miniport_block.
- Save a pointer to the driver image for use by ndis_syslog()
when it calls pe_get_message().
Diffstat (limited to 'sys/compat/ndis/subr_pe.c')
-rw-r--r-- | sys/compat/ndis/subr_pe.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/sys/compat/ndis/subr_pe.c b/sys/compat/ndis/subr_pe.c index 340d669..3151598 100644 --- a/sys/compat/ndis/subr_pe.c +++ b/sys/compat/ndis/subr_pe.c @@ -61,6 +61,15 @@ __FBSDID("$FreeBSD$"); #endif #include <compat/ndis/pe_var.h> +#ifdef _KERNEL +#include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> +#include <compat/ndis/resource_var.h> +#include <compat/ndis/ntoskrnl_var.h> +#include <compat/ndis/ndis_var.h> +#endif static u_int32_t pe_functbl_match(image_patch_table *, char *); @@ -456,6 +465,98 @@ pe_get_import_descriptor(imgbase, desc, module) return (ENOENT); } +#ifdef _KERNEL +int +pe_get_messagetable(imgbase, md) + vm_offset_t imgbase; + message_resource_data **md; +{ + image_resource_directory *rdir, *rtype; + image_resource_directory_entry *dent, *dent2; + image_resource_data_entry *rent; + vm_offset_t offset; + int i; + + if (imgbase == 0) + return(EINVAL); + + offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_RESOURCE); + if (offset == 0) + return (ENOENT); + + rdir = (image_resource_directory *)offset; + + dent = (image_resource_directory_entry *)(offset + + sizeof(image_resource_directory)); + + for (i = 0; i < rdir->ird_id_entries; i++){ + if (dent->irde_name != RT_MESSAGETABLE) { + dent++; + continue; + } + dent2 = dent; + while (dent2->irde_dataoff & RESOURCE_DIR_FLAG) { + rtype = (image_resource_directory *)(offset + + (dent2->irde_dataoff & ~RESOURCE_DIR_FLAG)); + dent2 = (image_resource_directory_entry *) + ((uintptr_t)rtype + + sizeof(image_resource_directory)); + } + rent = (image_resource_data_entry *)(offset + + dent2->irde_dataoff); + *md = (message_resource_data *)pe_translate_addr(imgbase, + rent->irde_offset); + return(0); + } + + return(ENOENT); +} + +int +pe_get_message(imgbase, id, str, len) + vm_offset_t imgbase; + uint32_t id; + char **str; + int *len; +{ + message_resource_data *md = NULL; + message_resource_block *mb; + message_resource_entry *me; + int i; + char m[1024], *msg; + + pe_get_messagetable(imgbase, &md); + + if (md == NULL) + return(ENOENT); + + mb = (message_resource_block *)((uintptr_t)md + + sizeof(message_resource_data)); + + for (i = 0; i < md->mrd_numblocks; i++) { + if (id >= mb->mrb_lowid && id <= mb->mrb_highid) { + me = (message_resource_entry *)((uintptr_t)md + + mb->mrb_entryoff); + for (i = id - mb->mrb_lowid; i > 0; i--) + me = (message_resource_entry *)((uintptr_t)me + + me->mre_len); + if (me->mre_flags == MESSAGE_RESOURCE_UNICODE) { + msg = m; + ndis_unicode_to_ascii((uint16_t *)me->mre_text, + me->mre_len, &msg); + *str = m; + } else + *str = me->mre_text; + *len = me->mre_len; + return(0); + } + mb++; + } + + return(ENOENT); +} +#endif + /* * Find the function that matches a particular name. This doesn't * need to be particularly speedy since it's only run when loading |