In if_ndis.c:ndis_intr(), be a bit more intelligent about squelching
unexpected interrupts. If an interrupt is triggered and we're not finished initializing yet, bail. If we have finished initializing, but IFF_UP isn't set yet, drain the interrupt with ndis_intr() or ndis_disable_intr() as appropriate, then return _without_ scheduling ndis_intrtask(). In kern_ndis.c:ndis_load_driver() only relocate/dynalink a given driver image once. Trying to relocate an image that's already been relocated will trash the image. We poison a part of the image header that we don't otherwise need with a magic value to indicate it's already been fixed up. This fixes the case where there are multiple units of the same kind of device.
This commit is contained in:
parent
361c31ad14
commit
958e09f637
@ -477,12 +477,14 @@ ndis_convert_res(arg)
|
||||
if (brl != NULL) {
|
||||
SLIST_FOREACH(brle, brl, link) {
|
||||
switch (brle->type) {
|
||||
#ifdef notdef
|
||||
case SYS_RES_IOPORT:
|
||||
prd->cprd_type = CmResourceTypePort;
|
||||
prd->u.cprd_port.cprd_start.np_quad =
|
||||
brle->start;
|
||||
prd->u.cprd_port.cprd_len = brle->count;
|
||||
break;
|
||||
#endif
|
||||
case SYS_RES_MEMORY:
|
||||
prd->cprd_type = CmResourceTypeMemory;
|
||||
prd->u.cprd_port.cprd_start.np_quad =
|
||||
@ -1084,6 +1086,8 @@ ndis_unload_driver(arg)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define NDIS_LOADED 0x42534F44
|
||||
|
||||
int
|
||||
ndis_load_driver(img, arg)
|
||||
vm_offset_t img;
|
||||
@ -1102,22 +1106,34 @@ ndis_load_driver(img, arg)
|
||||
|
||||
sc = arg;
|
||||
|
||||
/* Perform text relocation */
|
||||
if (pe_relocate(img))
|
||||
return(ENOEXEC);
|
||||
/*
|
||||
* Only perform the relocation/linking phase once
|
||||
* since the binary image may be shared among multiple
|
||||
* device instances.
|
||||
*/
|
||||
|
||||
/* Dynamically link the NDIS.SYS routines -- required. */
|
||||
if (pe_patch_imports(img, "NDIS", ndis_functbl))
|
||||
return(ENOEXEC);
|
||||
|
||||
/* Dynamically link the HAL.dll routines -- also required. */
|
||||
if (pe_patch_imports(img, "HAL", hal_functbl))
|
||||
return(ENOEXEC);
|
||||
|
||||
/* Dynamically link ntoskrnl.exe -- optional. */
|
||||
if (pe_get_import_descriptor(img, &imp_desc, "ntoskrnl") == 0) {
|
||||
if (pe_patch_imports(img, "ntoskrnl", ntoskrnl_functbl))
|
||||
ptr = (uint32_t *)(img + 8);
|
||||
if (*ptr != NDIS_LOADED) {
|
||||
/* Perform text relocation */
|
||||
if (pe_relocate(img))
|
||||
return(ENOEXEC);
|
||||
|
||||
/* Dynamically link the NDIS.SYS routines -- required. */
|
||||
if (pe_patch_imports(img, "NDIS", ndis_functbl))
|
||||
return(ENOEXEC);
|
||||
|
||||
/* Dynamically link the HAL.dll routines -- also required. */
|
||||
if (pe_patch_imports(img, "HAL", hal_functbl))
|
||||
return(ENOEXEC);
|
||||
|
||||
/* Dynamically link ntoskrnl.exe -- optional. */
|
||||
if (pe_get_import_descriptor(img,
|
||||
&imp_desc, "ntoskrnl") == 0) {
|
||||
if (pe_patch_imports(img,
|
||||
"ntoskrnl", ntoskrnl_functbl))
|
||||
return(ENOEXEC);
|
||||
}
|
||||
*ptr = NDIS_LOADED;
|
||||
}
|
||||
|
||||
/* Locate the driver entry point */
|
||||
|
@ -119,8 +119,12 @@ __stdcall static uint32_t
|
||||
__stdcall static void ntoskrnl_freemdl(ndis_buffer *);
|
||||
__stdcall static void *ntoskrnl_mmaplockedpages(ndis_buffer *, uint8_t);
|
||||
__stdcall static void ntoskrnl_init_lock(kspin_lock *);
|
||||
__stdcall static void dummy(void);
|
||||
__stdcall static size_t ntoskrnl_memcmp(const void *, const void *, size_t);
|
||||
__stdcall static void ntoskrnl_init_ansi_string(ndis_ansi_string *, char *);
|
||||
__stdcall static void ntoskrnl_init_unicode_string(ndis_unicode_string *,
|
||||
uint16_t *);
|
||||
__stdcall static void ntoskrnl_free_unicode_string(ndis_unicode_string *);
|
||||
__stdcall static void dummy(void);
|
||||
|
||||
static struct mtx *ntoskrnl_interlock;
|
||||
extern struct mtx_pool *ndis_mtxpool;
|
||||
@ -185,8 +189,12 @@ ntoskrnl_unicode_to_ansi(dest, src, allocate)
|
||||
{
|
||||
char *astr = NULL;
|
||||
|
||||
if (dest == NULL || src == NULL)
|
||||
return(NDIS_STATUS_FAILURE);
|
||||
|
||||
if (allocate) {
|
||||
ndis_unicode_to_ascii(src->nus_buf, src->nus_len, &astr);
|
||||
if (ndis_unicode_to_ascii(src->nus_buf, src->nus_len, &astr))
|
||||
return(NDIS_STATUS_FAILURE);
|
||||
dest->nas_buf = astr;
|
||||
dest->nas_len = dest->nas_maxlen = strlen(astr);
|
||||
} else {
|
||||
@ -646,6 +654,60 @@ ntoskrnl_memcmp(s1, s2, len)
|
||||
return(total);
|
||||
}
|
||||
|
||||
__stdcall static void
|
||||
ntoskrnl_init_ansi_string(dst, src)
|
||||
ndis_ansi_string *dst;
|
||||
char *src;
|
||||
{
|
||||
ndis_ansi_string *a;
|
||||
|
||||
a = dst;
|
||||
if (a == NULL)
|
||||
return;
|
||||
if (src == NULL) {
|
||||
a->nas_len = a->nas_maxlen = 0;
|
||||
a->nas_buf = NULL;
|
||||
} else {
|
||||
a->nas_buf = src;
|
||||
a->nas_len = a->nas_maxlen = strlen(src);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__stdcall static void
|
||||
ntoskrnl_init_unicode_string(dst, src)
|
||||
ndis_unicode_string *dst;
|
||||
uint16_t *src;
|
||||
{
|
||||
ndis_unicode_string *u;
|
||||
int i;
|
||||
|
||||
u = dst;
|
||||
if (u == NULL)
|
||||
return;
|
||||
if (src == NULL) {
|
||||
u->nus_len = u->nus_maxlen = 0;
|
||||
u->nus_buf = NULL;
|
||||
} else {
|
||||
i = 0;
|
||||
while(src[i] != 0)
|
||||
i++;
|
||||
u->nus_buf = src;
|
||||
u->nus_len = u->nus_maxlen = i * 2;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__stdcall static void
|
||||
ntoskrnl_free_unicode_string(ustr)
|
||||
ndis_unicode_string *ustr;
|
||||
{
|
||||
free(ustr->nus_buf, M_DEVBUF);
|
||||
return;
|
||||
}
|
||||
|
||||
__stdcall static void
|
||||
dummy()
|
||||
{
|
||||
@ -659,6 +721,10 @@ image_patch_table ntoskrnl_functbl[] = {
|
||||
{ "RtlEqualUnicodeString", (FUNC)ntoskrnl_unicode_equal },
|
||||
{ "RtlCopyUnicodeString", (FUNC)ntoskrnl_unicode_copy },
|
||||
{ "RtlUnicodeStringToAnsiString", (FUNC)ntoskrnl_unicode_to_ansi },
|
||||
{ "RtlAnsiStringToUnicodeString", (FUNC)ntoskrnl_ansi_to_unicode },
|
||||
{ "RtlInitAnsiString", (FUNC)ntoskrnl_init_ansi_string },
|
||||
{ "RtlInitUnicodeString", (FUNC)ntoskrnl_init_unicode_string },
|
||||
{ "RtlFreeUnicodeString", (FUNC)ndoskrnl_free_unicode_string },
|
||||
{ "sprintf", (FUNC)sprintf },
|
||||
{ "DbgPrint", (FUNC)printf },
|
||||
{ "strncmp", (FUNC)strncmp },
|
||||
|
Loading…
x
Reference in New Issue
Block a user