diff --git a/NetKVM/Common/ParaNdis-Debug.c b/NetKVM/Common/ParaNdis-Debug.c index ad3d56c1..6f347309 100644 --- a/NetKVM/Common/ParaNdis-Debug.c +++ b/NetKVM/Common/ParaNdis-Debug.c @@ -38,6 +38,22 @@ typedef BOOLEAN (*KeDeregisterBugCheckReasonCallbackType) ( __inout PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord ); +typedef ULONG (*vDbgPrintExType)( + __in ULONG ComponentId, + __in ULONG Level, + __in PCCH Format, + __in va_list arglist + ); + +static ULONG DummyPrintProcedure( + __in ULONG ComponentId, + __in ULONG Level, + __in PCCH Format, + __in va_list arglist + ) +{ + return 0; +} static BOOLEAN KeRegisterBugCheckReasonCallbackDummyProc( __out PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, __in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, @@ -55,6 +71,7 @@ BOOLEAN KeDeregisterBugCheckReasonCallbackDummyProc( return FALSE; } +static vDbgPrintExType PrintProcedure = DummyPrintProcedure; static KeRegisterBugCheckReasonCallbackType BugCheckRegisterCallback = KeRegisterBugCheckReasonCallbackDummyProc; static KeDeregisterBugCheckReasonCallbackType BugCheckDeregisterCallback = KeDeregisterBugCheckReasonCallbackDummyProc; KBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord; @@ -68,7 +85,7 @@ static void DebugPrint(const char *fmt, ...) NTSTATUS status; va_list list; va_start(list, fmt); - vDbgPrintEx(DPFLTR_DEFAULT_ID, 9 | DPFLTR_MASK, fmt, list); + PrintProcedure(DPFLTR_DEFAULT_ID, 9 | DPFLTR_MASK, fmt, list); #if defined(VIRTIO_DBG_USE_IOPORT) { // use this way of output only for DISPATCH_LEVEL, @@ -149,7 +166,7 @@ static void AnotherDbgBreak() void ParaNdis_DebugInitialize(PVOID DriverObject,PVOID RegistryPath) { - NDIS_STRING usRegister, usDeregister; + NDIS_STRING usRegister, usDeregister, usPrint; PVOID pr, pd; BOOLEAN res; WPP_INIT_TRACING(DriverObject, RegistryPath); @@ -157,8 +174,11 @@ void ParaNdis_DebugInitialize(PVOID DriverObject,PVOID RegistryPath) NdisAllocateSpinLock(&CrashLock); KeInitializeCallbackRecord(&CallbackRecord); ParaNdis_PrepareBugCheckData(); + NdisInitUnicodeString(&usPrint, L"vDbgPrintEx"); NdisInitUnicodeString(&usRegister, L"KeRegisterBugCheckReasonCallback"); NdisInitUnicodeString(&usDeregister, L"KeDeregisterBugCheckReasonCallback"); + pd = MmGetSystemRoutineAddress(&usPrint); + if (pd) PrintProcedure = (vDbgPrintExType)pd; pr = MmGetSystemRoutineAddress(&usRegister); pd = MmGetSystemRoutineAddress(&usDeregister); if (pr && pd) diff --git a/NetKVM/Common/ndis56common.h b/NetKVM/Common/ndis56common.h index d8a25af3..7977c7aa 100644 --- a/NetKVM/Common/ndis56common.h +++ b/NetKVM/Common/ndis56common.h @@ -351,6 +351,7 @@ typedef struct _tagPARANDIS_ADAPTER PNET_BUFFER_LIST SendHead; PNET_BUFFER_LIST SendTail; PNET_BUFFER_LIST SendWaitingList; + LIST_ENTRY WaitingMapping; NDIS_HANDLE DmaHandle; NDIS_HANDLE ConnectTimer; NDIS_HANDLE InterruptRecoveryTimer; diff --git a/NetKVM/DebugTools/NetKVMDumpParser/NetKVMDumpParser.cpp b/NetKVM/DebugTools/NetKVMDumpParser/NetKVMDumpParser.cpp index b9ba5568..98fd2ddb 100644 --- a/NetKVM/DebugTools/NetKVMDumpParser/NetKVMDumpParser.cpp +++ b/NetKVM/DebugTools/NetKVMDumpParser/NetKVMDumpParser.cpp @@ -18,10 +18,18 @@ #define new DEBUG_NEW #endif -#define DEBUG_SYMBOLS_IF IDebugSymbols2 +#define PRINT_SEPARATOR "-------------------------------------" +#define DEBUG_SYMBOLS_IF IDebugSymbols3 -#define PRINT(fmt, ...) printf("[%s]: "##fmt##"\n", __FUNCTION__, __VA_ARGS__); -//#define PRINT(fmt, ...) { CString __s; __s.Format(TEXT("[%s]: ")##TEXT(fmt)##TEXT("\n"), TEXT(__FUNCTION__), __VA_ARGS__); OutputDebugString(__s.GetBuffer()); } +FILE *outf = stdout; + +//#define UNDER_DEBUGGING + +#ifndef UNDER_DEBUGGING +#define PRINT(fmt, ...) fprintf(outf, "[%s]: "##fmt##"\n", __FUNCTION__, __VA_ARGS__); +#else +#define PRINT(fmt, ...) { CString __s; __s.Format(TEXT("[%s]: ")##TEXT(fmt)##TEXT("\n"), TEXT(__FUNCTION__), __VA_ARGS__); OutputDebugString(__s.GetBuffer()); } +#endif CString ErrorToString(HRESULT hr) { @@ -169,6 +177,11 @@ VALUE(DEBUG_CSS_TYPE_OPTIONS), ENDTABLE }; +#if !defined(DEBUG_STATUS_RESTART_REQUESTED) +#error Path to debug SDK is not defined properly in Property Manager. +#endif + + const tNamedValue EngineExecutionStatus[] = { VALUE(DEBUG_STATUS_NO_CHANGE), @@ -254,14 +267,22 @@ VALUE(SYMOPT_DEBUG), ENDTABLE }; +typedef struct _tagModule +{ + LPCSTR name; + ULONG64 Base; + ULONG index; +}tModule; + class tDumpParser : public DebugBaseEventCallbacks, public IDebugOutputCallbacks { public: tDumpParser() : refCount(0), Client(NULL), Control(NULL), DataSpaces(NULL), DebugSymbols(NULL) { HRESULT hr; + bEnableOutput = FALSE; hr = DebugCreate(__uuidof(IDebugClient), (void **)&Client); - if (Client) hr = Client->QueryInterface(__uuidof(IDebugControl), (void **)&Control); + if (Client) hr = Client->QueryInterface(__uuidof(IDebugControl2), (void **)&Control); if (Client) hr = Client->QueryInterface(__uuidof(IDebugDataSpaces3), (void **)&DataSpaces); if (Client) hr = Client->QueryInterface(__uuidof(DEBUG_SYMBOLS_IF), (void **)&DebugSymbols); } @@ -284,8 +305,6 @@ public: DebugSymbols->AddSymbolOptions(SYMOPT_DEBUG); //DebugSymbols->RemoveSymbolOptions(SYMOPT_DEFERRED_LOADS); DebugSymbols->AppendSymbolPath("."); - //DebugSymbols->AppendSymbolPath("D:\\SVN\\Qumranet\\drivers\\Logs\\2009-4\\Install\\Vista\\x86"); - } else { @@ -303,10 +322,15 @@ public: return hr == S_OK; } void ProcessDumpFile(); - void FindOurTaggedCrashData(); - void CheckLoadedSymbols(); - void ParseCrashData(tBugCheckStaticDataHeader *ph, ULONG64 databuffer, ULONG bytesRead); - typedef enum _tageSystemProperty {espSymbolPath, espSystemVersion } eSystemProperty; + void FindOurTaggedCrashData(BOOL bWithSymbols); + BOOL CheckLoadedSymbols(tModule *pModule); + void ProcessSymbols(tModule *pModule); + void ParseCrashData(tBugCheckStaticDataHeader *ph, ULONG64 databuffer, ULONG bytesRead, BOOL bWithSymbols); + typedef enum _tageSystemProperty { + espSymbolPath, + espSystemVersion, + espSystemTime, + } eSystemProperty; CString GetProperty(eSystemProperty Prop); protected: CString Parse(ULONG64 val, const tNamedValue *pt) @@ -497,15 +521,18 @@ DEBUG_EVENT_CHANGE_SYMBOL_STATE ; __in PCSTR Text ) { - //printf("%s", Text); - //OutputDebugString(Text); + if (bEnableOutput) + { + PRINT("%s", Text); + } return S_OK; } ULONG refCount; IDebugClient *Client; - IDebugControl *Control; + IDebugControl2 *Control; IDebugDataSpaces3 *DataSpaces; DEBUG_SYMBOLS_IF *DebugSymbols; + BOOL bEnableOutput; }; #define CHECK_INTERFACE(xf) { \ @@ -533,7 +560,7 @@ static void ParseHistoryEntry(LONGLONG basetime, tBugCheckHistoryDataEntry *phis } } -void tDumpParser::ParseCrashData(tBugCheckStaticDataHeader *ph, ULONG64 databuffer, ULONG bytesRead) +void tDumpParser::ParseCrashData(tBugCheckStaticDataHeader *ph, ULONG64 databuffer, ULONG bytesRead, BOOL bWithSymbols) { UINT i; for (i = 0; i < ph->ulMaxContexts; ++i) @@ -544,31 +571,42 @@ void tDumpParser::ParseCrashData(tBugCheckStaticDataHeader *ph, ULONG64 databuff { LONGLONG diffInt = (ph->qCrashTime.QuadPart - pndc->LastInterruptTimeStamp.QuadPart) / 10; LONGLONG diffTx = (ph->qCrashTime.QuadPart - pndc->LastTxCompletionTimeStamp.QuadPart) / 10; + PRINT(PRINT_SEPARATOR); PRINT("Context %I64X:", pndc->Context); PRINT("\tLastInterrupt %I64d us before crash", diffInt); PRINT("\tLast Tx complete %I64d us before crash", diffTx); PRINT("\tWaiting %d packets, %d free buffers", pndc->nofPacketsToComplete, pndc->nofReadyTxBuffers); + PRINT(PRINT_SEPARATOR); } } tBugCheckStaticDataContent_V0 *pd = (tBugCheckStaticDataContent_V0 *)(ph->DataArea - databuffer + (PUCHAR)ph); tBugCheckHistoryDataEntry *phist = (tBugCheckHistoryDataEntry *)(pd->HistoryData - databuffer + (PUCHAR)ph); - PRINT("History: version %d, %d entries of %d, current at %d", pd->HistoryDataVersion, pd->SizeOfHistory, pd->SizeOfHistoryEntry, pd->CurrentHistoryIndex); - LONG Index = pd->CurrentHistoryIndex % pd->SizeOfHistory; - LONG EndIndex = Index; - ParseHistoryEntry(NULL, NULL, 0); - for (; Index < (LONG)pd->SizeOfHistory; Index++) + PRINT(PRINT_SEPARATOR); + if (pd->SizeOfHistory > 2) { - ParseHistoryEntry(ph->qCrashTime.QuadPart, phist, Index); + PRINT("History: version %d, %d entries of %d, current at %d", pd->HistoryDataVersion, pd->SizeOfHistory, pd->SizeOfHistoryEntry, pd->CurrentHistoryIndex); + LONG Index = pd->CurrentHistoryIndex % pd->SizeOfHistory; + LONG EndIndex = Index; + ParseHistoryEntry(NULL, NULL, 0); + for (; Index < (LONG)pd->SizeOfHistory; Index++) + { + ParseHistoryEntry(ph->qCrashTime.QuadPart, phist, Index); + } + for (Index = 0; Index < EndIndex; Index++) + { + ParseHistoryEntry(ph->qCrashTime.QuadPart, phist, Index); + } } - for (Index = 0; Index < EndIndex; Index++) + else { - ParseHistoryEntry(ph->qCrashTime.QuadPart, phist, Index); + PRINT("History records are not available"); } + PRINT(PRINT_SEPARATOR); } -void tDumpParser::FindOurTaggedCrashData() +void tDumpParser::FindOurTaggedCrashData(BOOL bWithSymbols) { ULONG64 h; if (S_OK == DataSpaces->StartEnumTagged(&h)) @@ -604,7 +642,7 @@ void tDumpParser::FindOurTaggedCrashData() PRINT("Versions: status data %d, pre-NIC data %d, ptr size %d, %d contexts, crash time %I64X", ph->StaticDataVersion, ph->PerNicDataVersion, ph->SizeOfPointer, ph->ulMaxContexts, ph->qCrashTime); PRINT("Per-NIC data at %I64X, Static data at %I64X(%d bytes)", ph->PerNicData, ph->DataArea, ph->DataAreaSize); - ParseCrashData(ph, bcdl->Address, bytesRead); + ParseCrashData(ph, bcdl->Address, bytesRead, bWithSymbols); } } free(databuffer); @@ -637,7 +675,7 @@ static BOOL GetModuleName(ULONG Which, ULONG64 Base, DEBUG_SYMBOLS_IF *DebugSymb return S_OK == hr; } -static BOOL TryMatchingSymbols(DEBUG_SYMBOLS_IF *DebugSymbols, PCSTR name) +static BOOL TryMatchingSymbols(DEBUG_SYMBOLS_IF *DebugSymbols, PCSTR name, BOOL bPrintAll = FALSE) { UINT n = 0; CString s; @@ -652,7 +690,8 @@ static BOOL TryMatchingSymbols(DEBUG_SYMBOLS_IF *DebugSymbols, PCSTR name) matchHandle, buf, size, NULL, NULL)) { n++; - break; + if (!bPrintAll) break; + PRINT("%s", buf); } DebugSymbols->EndSymbolMatch(matchHandle); free(buf); @@ -660,67 +699,29 @@ static BOOL TryMatchingSymbols(DEBUG_SYMBOLS_IF *DebugSymbols, PCSTR name) return n != 0; } -void tDumpParser::CheckLoadedSymbols() +BOOL tDumpParser::CheckLoadedSymbols(tModule *pModule) { - ULONG index; + BOOL bLoaded = FALSE; ULONG bufferSize = 2048, bufferUsage; UNREFERENCED_PARAMETER(bufferUsage); - ULONG64 Base; char *buffer = (char *)malloc(bufferSize); DEBUG_MODULE_PARAMETERS ModuleParams; - PCSTR name = "netkvm"; - HRESULT hr = DebugSymbols->GetModuleByModuleName(name, 0, &index, &Base); + HRESULT hr = DebugSymbols->GetModuleByModuleName(pModule->name, 0, &pModule->index, &pModule->Base); if (S_OK == hr) { CString s; - PRINT("Found %s at %I64X", name, Base); - if (GetModuleName(DEBUG_MODNAME_MODULE, Base, DebugSymbols, s)) + PRINT("Found %s at %I64X", pModule->name, pModule->Base); + if (GetModuleName(DEBUG_MODNAME_MODULE, pModule->Base, DebugSymbols, s)) PRINT("\tModule Name:%s", s.GetBuffer()); - if (GetModuleName(DEBUG_MODNAME_IMAGE, Base, DebugSymbols, s)) + if (GetModuleName(DEBUG_MODNAME_IMAGE, pModule->Base, DebugSymbols, s)) PRINT("\tImage Name:%s", s.GetBuffer()); - if (GetModuleName(DEBUG_MODNAME_SYMBOL_FILE, Base, DebugSymbols, s)) + if (GetModuleName(DEBUG_MODNAME_SYMBOL_FILE, pModule->Base, DebugSymbols, s)) PRINT("\tSymbol file:%s", s.GetBuffer()); + bLoaded = 0 != TryMatchingSymbols(DebugSymbols, pModule->name); + PRINT("Symbols for %s %sLOADED", pModule->name, bLoaded ? "" : "NOT "); - -#if 0 - { - // this does not retrive information, produces error D0000147 - hr = DebugSymbols->GetModuleVersionInformation( - index, Base, "\\", buffer, bufferSize, &bufferUsage); - if (S_OK == hr) - { - VS_FIXEDFILEINFO *ffi = (VS_FIXEDFILEINFO *)buffer; - PRINT("File version:%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS)); - } - else - { - CString sError = ErrorToString(hr & 0xffff); - PRINT("Error %08X loading symbols: %s", hr, sError.GetBuffer()); - } - // this does not improve clearness of loading - // gives the wrong OK status when the PDB is not loaded - CString sLoadFor = s; - PRINT("Trying to load symbols for %s...", sLoadFor); - hr = DebugSymbols->Reload(sLoadFor); - if (S_OK == hr) - { - PRINT("Symbols for %s loaded successfully", name); - if (GetModuleName(DEBUG_MODNAME_SYMBOL_FILE, Base, DebugSymbols, s)) - PRINT("\tSymbol file:%s", s.GetBuffer()); - } - else - { - CString sError = ErrorToString(hr); - PRINT("Error %08X loading symbols: %s", hr, sError.GetBuffer()); - } - } -#endif - BOOL bLoaded = 0 != TryMatchingSymbols(DebugSymbols, name); - PRINT("Symbols for %s %sLOADED", name, bLoaded ? "" : "NOT "); - - - if (S_OK == DebugSymbols->GetModuleParameters(1, &Base, 0, &ModuleParams)) + if (S_OK == DebugSymbols->GetModuleParameters(1, &pModule->Base, 0, &ModuleParams)) { CString sSymbolType = Parse(ModuleParams.SymbolType, SymbolTypeValues); CString sFlags = Parse(ModuleParams.Flags, ModuleFlags); @@ -734,35 +735,16 @@ void tDumpParser::CheckLoadedSymbols() } } free(buffer); -} - -void ExtractKernelLog(IDebugDataSpaces3 *DataSpaces) -{ - // does not work - ULONG SizeUsed; - ULONG64 KdBufferAddr = 0, KdSizeAddr = 0; - HRESULT hr = DataSpaces->ReadDebuggerData( - DEBUG_DATA_KdPrintCircularBufferPtrAddr, - &KdBufferAddr, - sizeof(KdBufferAddr), - &SizeUsed); - if (S_OK == hr) hr = DataSpaces->ReadDebuggerData( - DEBUG_DATA_KdPrintBufferSizeAddr, - &KdSizeAddr, - sizeof(KdSizeAddr), - &SizeUsed); - if (S_OK == hr) hr = DataSpaces->ReadDebuggerData( - DEBUG_DATA_KdPrintBufferSizeAddr, - &KdSizeAddr, - sizeof(KdSizeAddr), - &SizeUsed); - + return bLoaded; } void tDumpParser::ProcessDumpFile() { ULONG SymbolOptions; + BOOL bSymbols; CString s; + tModule module; + module.name = "netkvm"; if (S_OK == DebugSymbols->GetSymbolOptions(&SymbolOptions)) { s = Parse(SymbolOptions, SymbolOptionsFlags); @@ -773,10 +755,10 @@ void tDumpParser::ProcessDumpFile() PRINT("Symbol path:%s", s.GetBuffer()); s = GetProperty(espSystemVersion); PRINT("System version:%s", s.GetBuffer()); - - FindOurTaggedCrashData(); - CheckLoadedSymbols(); - //ExtractKernelLog(); + s = GetProperty(espSystemTime); + PRINT("Crash time:%s", s.GetBuffer()); + bSymbols = CheckLoadedSymbols(&module); + FindOurTaggedCrashData(bSymbols); } CString tDumpParser::GetProperty(eSystemProperty Prop) @@ -811,22 +793,50 @@ CString tDumpParser::GetProperty(eSystemProperty Prop) free(buf); } break; + case espSystemTime: + if (Control) + { + ULONG ulSecondSince1970 = 0, ulUpTime = 0; + Control->GetCurrentTimeDate(&ulSecondSince1970); + Control->GetCurrentSystemUpTime(&ulUpTime); + s = "Unknown"; + if (ulSecondSince1970) + { + char buffer[256] = {0}; + ULONG days, hours, min, sec, rem; + days = ulUpTime / (60*60*24); + rem = ulUpTime - days * 60*60*24; + hours = rem / (60*60); + rem = rem - hours * 60 * 60; + min = rem / 60; + rem = rem - min * 60; + sec = rem; + __time32_t timestamp = ulSecondSince1970; + tm *timer = _localtime32(×tamp); + strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S %Y(Local)", timer); + s.Format("%s (Up time %d:%d:%d:%d)", buffer, days, hours, min, sec); + } + } default: break; } return s; } - int ParseDumpFile(int argc, TCHAR* argv[]) { - if (1) + if (argc == 2) { + CString s = argv[1]; + s += ".txt"; + FILE *f = fopen(s.GetBuffer(), "w+t"); + if (f) outf = f; tDumpParser Parser; - if (argc == 2) - { - if (!Parser.LoadFile(argv[1])) PRINT("Failed to load dump file %s", argv[1]); - } +#ifdef UNDER_DEBUGGING + fputs("UNDER_DEBUGGING, the output is redirected to debugger", f); +#endif + if (!Parser.LoadFile(argv[1])) PRINT("Failed to load dump file %s", argv[1]); + if (f) fclose(f); } else { diff --git a/NetKVM/buildAll.bat b/NetKVM/buildAll.bat index e58969ff..a01fafdf 100644 --- a/NetKVM/buildAll.bat +++ b/NetKVM/buildAll.bat @@ -25,8 +25,7 @@ set OLD_PATH=%PATH% if not "%1"=="" goto parameters_here echo no parameters specified, rebuild all call clean.bat -:call "%0" Vista Vista64 XP XP64 Win2K -call "%0" Win7 Win7_64 Vista Vista64 XP XP64 +call "%0" Vista Vista64 XP XP64 Win2K call :PackInstall goto :eof :parameters_here @@ -160,4 +159,5 @@ goto continue :echo Packing to ISO image :call tools\makecdimage.cmd %_DRIVER_ISO_NAME% Install goto :eof +echo "setting old path back" set PATH=%OLD_PATH% \ No newline at end of file diff --git a/NetKVM/clean.bat b/NetKVM/clean.bat index 8987cb78..1d293a89 100644 --- a/NetKVM/clean.bat +++ b/NetKVM/clean.bat @@ -1,8 +1,5 @@ rmdir /S /Q wlh\objfre_wlh_x86 rmdir /S /Q wlh\objfre_wlh_amd64 -rmdir /S /Q wlh\objfre_win7_amd64 -rmdir /S /Q wlh\objfre_win7_x86 - del wlh\BuildLog.htm rmdir /S /Q wxp\objfre_wnet_amd64 @@ -15,16 +12,12 @@ rmdir /S /Q virtio\objfre_wnet_amd64 rmdir /S /Q virtio\objfre_w2k_x86 rmdir /S /Q virtio\objfre_wxp_x86 rmdir /S /Q virtio\objfre_wlh_amd64 -rmdir /S /Q virtio\objfre_win7_amd64 -rmdir /S /Q virtio\objfre_win7_x86 rmdir /S /Q common\objfre_wlh_x86 rmdir /S /Q common\objfre_wnet_amd64 rmdir /S /Q common\objfre_w2k_x86 rmdir /S /Q common\objfre_wxp_x86 rmdir /S /Q common\objfre_wlh_amd64 -rmdir /S /Q common\objfre_win7_amd64 -rmdir /S /Q common\objfre_win7_x86 rmdir /S /Q Install diff --git a/NetKVM/wlh/ParaNdis6-Impl.c b/NetKVM/wlh/ParaNdis6-Impl.c index 59d7ff9a..b295202a 100644 --- a/NetKVM/wlh/ParaNdis6-Impl.c +++ b/NetKVM/wlh/ParaNdis6-Impl.c @@ -450,6 +450,8 @@ NDIS_STATUS ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext) NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS mic; DEBUG_ENTRY(0); + InitializeListHead(&pContext->WaitingMapping); + NdisZeroMemory(&mic, sizeof(mic)); mic.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_INTERRUPT; mic.Header.Revision = NDIS_MINIPORT_INTERRUPT_REVISION_1; @@ -1286,13 +1288,13 @@ static BOOLEAN PrepareSingleNBL( bOK = FALSE; pFailReason = "Failure to allocate BLE"; } - + if (bOK && !pB) { bOK = FALSE; pFailReason = "Empty NBL"; } - + while (pB && bOK) { ULONG dataLength = NET_BUFFER_DATA_LENGTH(pB); @@ -1403,6 +1405,8 @@ static void StartTransferSingleNBL(PARANDIS_ADAPTER *pContext, PNET_BUFFER_LIST tNetBufferEntry *pnbe = (tNetBufferEntry *)RemoveHeadList(&list); DPrintf(4, ("[%s] mapping entry %p", __FUNCTION__, pnbe)); //ParaNdis_DebugHistory(pContext, hopSendPacketRequest, pNBL, 0, 0, status); + NdisInterlockedInsertTailList(&pContext->WaitingMapping, &pnbe->list, &pContext->SendLock); + if (bPassive) irql = KeRaiseIrqlToDpcLevel(); if (pContext->bUseScatterGather) { @@ -1533,7 +1537,14 @@ VOID ProcessSGListHandler( PNET_BUFFER_LIST pNBL = pnbe->nbl; LONG DoneCounter; tNetBufferListEntry *pble = (tNetBufferListEntry *)pNBL->Scratch; + + NdisAcquireSpinLock(&pContext->SendLock); + // remove the netbuffer entry from WaitingMapping list + RemoveEntryList(&pnbe->list); + // insert it into list of buffers under netbufferlist entry InsertTailList(&pble->bufferEntries, &pnbe->list); + NdisReleaseSpinLock(&pContext->SendLock); + pnbe->pSGList = pSGL; DoneCounter = InterlockedIncrement(&pble->nBuffersMapped); DPrintf(3, ("[%s] mapped %d of %d(%d)", __FUNCTION__,