static NTSTATUS CancelPacketRead(PIRP Irp, PIO_STACK_LOCATION IrpSp) { PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_PACKET_ENTRY PacketEntry; NTSTATUS Status; /* Indicate a 0-byte packet on the queue so one read returns 0 */ PacketEntry = ExAllocatePool(PagedPool, sizeof(NDISUIO_PACKET_ENTRY)); if (PacketEntry) { PacketEntry->PacketLength = 0; ExInterlockedInsertHeadList(&AdapterContext->PacketList, &PacketEntry->ListEntry, &AdapterContext->Spinlock); KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE); Status = STATUS_SUCCESS; } else { Status = STATUS_NO_MEMORY; } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
static VOID NTAPI ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext; PNDISUIO_PACKET_ENTRY PacketEntry; /* Release the cancel spin lock */ IoReleaseCancelSpinLock(Irp->CancelIrql); /* Indicate a 0-byte packet on the queue to cancel the read */ PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY)); if (PacketEntry) { PacketEntry->PacketLength = 0; ExInterlockedInsertHeadList(&AdapterContext->PacketList, &PacketEntry->ListEntry, &AdapterContext->Spinlock); KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE); } }
VOID LsuInsertAce( IN PLSU_BLOCK_ACL BlockAcl, IN PLSU_BLOCK_ACE BlockAce ){ InterlockedIncrement(&BlockAcl->BlockACECnt); ExInterlockedInsertHeadList( &BlockAcl->BlockAclHead, &BlockAce->BlockAclList, &BlockAcl->BlcokAclSpinlock); }
VOID NTAPI LwipThreadMain(PVOID Context) { thread_t Container = (thread_t)Context; KIRQL OldIrql; ExInterlockedInsertHeadList(&ThreadListHead, &Container->ListEntry, &ThreadListLock); Container->ThreadFunction(Container->ThreadContext); KeAcquireSpinLock(&ThreadListLock, &OldIrql); RemoveEntryList(&Container->ListEntry); KeReleaseSpinLock(&ThreadListLock, OldIrql); ExFreePool(Container); PsTerminateSystemThread(STATUS_SUCCESS); }
VOID LfsTable_InsertNetDiskPartitionInfoUser( IN PLFS_TABLE LfsTable, IN PNETDISK_PARTITION_INFO NetDiskPartitionInfo, IN PLPX_ADDRESS BindAddress, BOOLEAN Primary ) { NTSTATUS ntStatus ; PLFSTAB_ENTRY Entry ; LfsTable ; NetDiskPartitionInfo ; BindAddress ; Primary ; ntStatus = LfsTable_CreateEntry( NetDiskPartitionInfo, BindAddress, Primary, &Entry ) ; if(!NT_SUCCESS(ntStatus)) { SPY_LOG_PRINT( LFS_DEBUG_TABLE_INFO, ("LfsTable_InsertNetDiskPartitionInfoUser: LfsTable_CreateEntry() failed.\n")); return ; } Entry->LfsTable = LfsTable ; ExInterlockedInsertHeadList( &LfsTable->LfsTabPartitionList, &Entry->LfsTabPartitionEntry, &LfsTable->SpinLock ) ; InterlockedIncrement(&LfsTable->EntryCount) ; LfsTable_Reference(LfsTable) ; SPY_LOG_PRINT( LFS_DEBUG_TABLE_INFO, ("LfsTable_InsertNetDiskPartitionInfoUser: inserted a Partition entry.\n")); }
POPEN_FILE PrimarySession_AllocateOpenFile ( IN PPRIMARY_SESSION PrimarySession, IN HANDLE FileHandle, IN PFILE_OBJECT FileObject ) { POPEN_FILE openFile; openFile = ExAllocatePoolWithTag( NonPagedPool, sizeof(OPEN_FILE), OPEN_FILE_TAG ); if (openFile == NULL) { ASSERT( NDASFAT_INSUFFICIENT_RESOURCES ); return NULL; } RtlZeroMemory( openFile, sizeof(OPEN_FILE) ); openFile->FileHandle = FileHandle; openFile->FileObject = FileObject; openFile->PrimarySession = PrimarySession; InitializeListHead( &openFile->ListEntry ); ExInterlockedInsertHeadList( &PrimarySession->Thread.OpenedFileQueue, &openFile->ListEntry, &PrimarySession->Thread.OpenedFileQSpinLock ); DebugTrace2( 0,Dbg, ("PrimarySession_AllocateOpenFile OpenFile = %p\n", openFile) ); return openFile; }
VOID NdasPortAddToLpxLocalAddressList( PNDASPORT_DRIVER_EXTENSION DriverExtension, PTDI_ADDRESS_LPX TdiLpxAddress) { PTDI_ADDRESS_LPX_LIST_ENTRY lpxAddressEntry; lpxAddressEntry = (PTDI_ADDRESS_LPX_LIST_ENTRY) ExAllocatePoolWithTag( NonPagedPool, sizeof(TDI_ADDRESS_LPX_LIST_ENTRY), NDASPORT_TAG_TDI); if (NULL == lpxAddressEntry) { DebugPrint((0, "NdasPortAddToLpxLocalAddressList: Allocation Failure: " "%02X:%02X:%02X-%02X:%02X:%02X\n", TdiLpxAddress->Node[0], TdiLpxAddress->Node[1], TdiLpxAddress->Node[2], TdiLpxAddress->Node[3], TdiLpxAddress->Node[4], TdiLpxAddress->Node[5])); ASSERT(FALSE); return; } RtlCopyMemory( &lpxAddressEntry->TdiAddress, TdiLpxAddress, sizeof(TDI_ADDRESS_LPX)); ExInterlockedInsertHeadList( &DriverExtension->LpxLocalAddressList, &lpxAddressEntry->ListEntry, &DriverExtension->LpxLocalAddressListSpinLock); DebugPrint((0, "\tLocal LPX Address Added: %02X:%02X:%02X:%02X:%02X:%02X\n", TdiLpxAddress->Node[0], TdiLpxAddress->Node[1], TdiLpxAddress->Node[2], TdiLpxAddress->Node[3], TdiLpxAddress->Node[4], TdiLpxAddress->Node[5])); }
NTSTATUS Primary_FsControlMountVolumeComplete ( IN PPRIMARY Primary, IN PLFS_DEVICE_EXTENSION LfsDeviceExt ) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_FsControlMountVolumeComplete: LfsDeviceExt = %p, Primary = %p, LfsDeviceExt->LocalNetDiskPartitionInfo.NetDiskPartitionInfo.StartingOffset = %I64x\n", LfsDeviceExt, Primary, LfsDeviceExt->NetdiskPartitionInformation.PartitionInformation.StartingOffset)); LfsDeviceExt_Reference ( LfsDeviceExt ); ExInterlockedInsertHeadList( // must be attached to head &Primary->LfsDeviceExtQueue, &LfsDeviceExt->PrimaryQListEntry, &Primary->LfsDeviceExtQSpinLock ); return STATUS_SUCCESS; }
NTSTATUS DeviceControlCompleteRoutine(PDEVICE_OBJECT pDeviceObject, PIRP pIrp) { UNREFERENCED_PARAMETER(pDeviceObject); NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpsp = IoGetCurrentIrpStackLocation(pIrp); ULONG uLength = 0; PVOID pBuffer = pIrp->AssociatedIrp.SystemBuffer; ULONG ulInputlength = pIrpsp->Parameters.DeviceIoControl.InputBufferLength; ULONG ulOutputlength = pIrpsp->Parameters.DeviceIoControl.OutputBufferLength; do { switch (pIrpsp->Parameters.DeviceIoControl.IoControlCode) { case CWK_DVC_SEND_STR: { ASSERT(pBuffer != NULL); ASSERT(ulInputlength > 0); ASSERT(ulOutputlength == 0); } break; case CWK_DVC_RECV_STR: { ASSERT(ulInputlength == 0); while (TRUE) { PEVENT_DATA_NODE pNode = (PEVENT_DATA_NODE)ExInterlockedRemoveHeadList(&g_ListHead, &g_Lock); if (NULL != pNode) { PREGISTRY_EVENT pOutputBuffer = (PREGISTRY_EVENT)pBuffer; SIZE_T ulNumberOfBytes = sizeof(REGISTRY_EVENT) + // 结构体大小 pNode->pstRegistryEvent->ulProcessPathLength + // 进程路径长度 pNode->pstRegistryEvent->ulRegistryPathLength + // 路径长度 pNode->pstRegistryEvent->ulDataLength; // 数据长度 if (NULL != pNode->pstRegistryEvent) { if (ulOutputlength >= ulNumberOfBytes) { RtlCopyBytes(pOutputBuffer, pNode->pstRegistryEvent, ulNumberOfBytes); ExFreePoolWithTag(pNode->pstRegistryEvent, MEM_TAG); ExFreePoolWithTag(pNode, MEM_TAG); } else { ExInterlockedInsertHeadList(&g_ListHead, (PLIST_ENTRY)pNode, &g_Lock); } } uLength = (ULONG)ulNumberOfBytes; break; } else { KeWaitForSingleObject(&g_Event, Executive, KernelMode, 0, 0); } } } break; default: { status = STATUS_INVALID_PARAMETER; } break; } } while (FALSE); pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = uLength; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; }
VOID ReadonlyThreadProc ( IN PREADONLY Readonly ) { BOOLEAN readonlyThreadTerminate = FALSE; PLIST_ENTRY readonlyRequestEntry; SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyThreadProc: Start Readonly = %p\n", Readonly) ); Readonly_Reference( Readonly ); Readonly->Thread.Flags = READONLY_THREAD_FLAG_INITIALIZING; ExAcquireFastMutex( &Readonly->FastMutex ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_START ); ClearFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_INITIALIZING ); ExReleaseFastMutex( &Readonly->FastMutex ); KeSetEvent( &Readonly->ReadyEvent, IO_DISK_INCREMENT, FALSE ); readonlyThreadTerminate = FALSE; while (readonlyThreadTerminate == FALSE) { PKEVENT events[2]; LONG eventCount; NTSTATUS eventStatus; LARGE_INTEGER timeOut; ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); eventCount = 0; events[eventCount++] = &Readonly->RequestEvent; timeOut.QuadPart = -LFS_READONLY_THREAD_FLAG_TIME_OUT; eventStatus = KeWaitForMultipleObjects( eventCount, events, WaitAny, Executive, KernelMode, TRUE, &timeOut, NULL ); if (eventStatus == STATUS_TIMEOUT) { ReadonlyTryCloseCcb( Readonly ); ReadonlyDismountVolumeStart( Readonly ); continue; } ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); ASSERT( eventCount < THREAD_WAIT_OBJECTS ); if (!NT_SUCCESS( eventStatus ) || eventStatus >= eventCount) { ASSERT( LFS_UNEXPECTED ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_ERROR ); readonlyThreadTerminate = TRUE; continue; } KeClearEvent( events[eventStatus] ); if (eventStatus == 0) { while (!FlagOn(Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED) && (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue, &Readonly->RequestQSpinLock))) { PREADONLY_REQUEST readonlyRequest; InitializeListHead( readonlyRequestEntry ); readonlyRequest = CONTAINING_RECORD( readonlyRequestEntry, READONLY_REQUEST, ListEntry ); if (!(readonlyRequest->RequestType == READONLY_REQ_DISCONNECT || readonlyRequest->RequestType == READONLY_REQ_DOWN || readonlyRequest->RequestType == READONLY_REQ_SEND_MESSAGE)) { ASSERT( FALSE ); ExAcquireFastMutex( &Readonly->FastMutex ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED | READONLY_THREAD_FLAG_ERROR ); ExReleaseFastMutex( &Readonly->FastMutex ); ExInterlockedInsertHeadList( &Readonly->RequestQueue, &readonlyRequest->ListEntry, &Readonly->RequestQSpinLock ); readonlyThreadTerminate = TRUE; break; } if (readonlyRequest->RequestType == READONLY_REQ_DISCONNECT) { if (readonlyRequest->Synchronous == TRUE) KeSetEvent(&readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE); else DereferenceReadonlyRequest( readonlyRequest ); continue; } if (readonlyRequest->RequestType == READONLY_REQ_DOWN) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyThread READONLY_REQ_DOWN Readonly = %p\n", Readonly) ); ExAcquireFastMutex( &Readonly->FastMutex ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED ); ExReleaseFastMutex( &Readonly->FastMutex ); ASSERT( IsListEmpty(&Readonly->RequestQueue) ); if (readonlyRequest->Synchronous == TRUE) KeSetEvent( &readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferenceReadonlyRequest( readonlyRequest ); readonlyThreadTerminate = TRUE; break; } ASSERT( readonlyRequest->RequestType == READONLY_REQ_SEND_MESSAGE ); ASSERT( readonlyRequest->Synchronous == TRUE ); } // while } else { NDAS_ASSERT( FALSE ); } } ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); ExAcquireFastMutex( &Readonly->FastMutex ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_STOPED ); while (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue, &Readonly->RequestQSpinLock)) { PREADONLY_REQUEST readonlyRequest; InitializeListHead( readonlyRequestEntry ); readonlyRequest = CONTAINING_RECORD( readonlyRequestEntry, READONLY_REQUEST, ListEntry ); readonlyRequest->ExecuteStatus = STATUS_IO_DEVICE_ERROR; if (readonlyRequest->Synchronous == TRUE) KeSetEvent( &readonlyRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferenceReadonlyRequest( readonlyRequest ); } ExReleaseFastMutex( &Readonly->FastMutex ); SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyThreadProc: PsTerminateSystemThread Readonly = %p, IsListEmpty(&Readonly->RequestQueue) = %d\n", Readonly, IsListEmpty(&Readonly->RequestQueue)) ); ExAcquireFastMutex( &Readonly->FastMutex ); SetFlag( Readonly->Thread.Flags, READONLY_THREAD_FLAG_TERMINATED ); ExReleaseFastMutex( &Readonly->FastMutex ); Readonly_Dereference( Readonly ); ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); PsTerminateSystemThread( STATUS_SUCCESS ); }
VOID NTAPI IopLogWorker(IN PVOID Parameter) { #define IO_ERROR_OBJECT_NAMES_LENGTH 100 NTSTATUS Status; PELF_API_MSG Message; PIO_ERROR_LOG_MESSAGE ErrorMessage; PLIST_ENTRY ListEntry; PERROR_LOG_ENTRY LogEntry; PIO_ERROR_LOG_PACKET Packet; PCHAR StringBuffer; ULONG RemainingLength; PDRIVER_OBJECT DriverObject; PWCHAR NameString; ULONG DriverNameLength, DeviceNameLength; UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + IO_ERROR_OBJECT_NAMES_LENGTH]; POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer; POBJECT_NAME_INFORMATION PoolObjectNameInfo; ULONG ReturnedLength, MessageLength; ULONG ExtraStringLength; PWCHAR p; PAGED_CODE(); UNREFERENCED_PARAMETER(Parameter); /* Connect to the port */ if (!IopConnectLogPort()) return; /* Allocate the message */ Message = ExAllocatePoolWithTag(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH, TAG_IO); if (!Message) { /* Couldn't allocate, try again */ IopRestartLogWorker(); return; } /* Zero out the message and get the actual I/O structure */ RtlZeroMemory(Message, sizeof(*Message)); ErrorMessage = &Message->IoErrorMessage; /* Start loop */ while (TRUE) { /* Get an entry */ ListEntry = IopGetErrorLogEntry(); if (!ListEntry) break; LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry); /* Get pointer to the log packet */ Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY)); /* Calculate the total length of the message only */ MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) - sizeof(ERROR_LOG_ENTRY) - sizeof(IO_ERROR_LOG_PACKET) + LogEntry->Size; /* Copy the packet */ RtlCopyMemory(&ErrorMessage->EntryData, Packet, LogEntry->Size - sizeof(ERROR_LOG_ENTRY)); /* Set the timestamp and time */ ErrorMessage->TimeStamp = LogEntry->TimeStamp; ErrorMessage->Type = IO_TYPE_ERROR_MESSAGE; /* Check if this message has any strings */ if (Packet->NumberOfStrings) { /* String buffer is after the current strings */ StringBuffer = (PCHAR)&ErrorMessage->EntryData + Packet->StringOffset; } else { /* Otherwise, string buffer is at the end */ StringBuffer = (PCHAR)ErrorMessage + MessageLength; } /* Align the buffer */ StringBuffer = ALIGN_UP_POINTER(StringBuffer, WCHAR); /* Set the offset for the driver's name to the current buffer */ ErrorMessage->DriverNameOffset = (ULONG)(StringBuffer - (PCHAR)ErrorMessage); /* Check how much space we have left for the device string */ RemainingLength = (ULONG)((ULONG_PTR)Message + IO_ERROR_LOG_MESSAGE_LENGTH - (ULONG_PTR)StringBuffer); NameString = NULL; DriverNameLength = 0; DeviceNameLength = 0; PoolObjectNameInfo = NULL; ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer; /* Now check if there is a driver object */ DriverObject = LogEntry->DriverObject; if (DriverObject) { /* Check if the driver has a name, and use it if so */ if (DriverObject->DriverName.Buffer) { NameString = DriverObject->DriverName.Buffer; DriverNameLength = DriverObject->DriverName.Length; } else { NameString = NULL; DriverNameLength = 0; } /* Check if there isn't a valid name */ if (!DriverNameLength) { /* Query the name directly */ Status = ObQueryNameString(DriverObject, ObjectNameInfo, sizeof(Buffer), &ReturnedLength); if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0)) { /* We don't have a name */ DriverNameLength = 0; } else { NameString = ObjectNameInfo->Name.Buffer; DriverNameLength = ObjectNameInfo->Name.Length; } } } else { /* Use default name */ NameString = L"Application Popup"; DriverNameLength = (ULONG)wcslen(NameString) * sizeof(WCHAR); } /* Check if we have a driver name */ if (DriverNameLength) { /* Skip to the end of the driver's name */ p = &NameString[DriverNameLength / sizeof(WCHAR)]; /* Now we'll walk backwards and assume the minimum size */ DriverNameLength = sizeof(WCHAR); p--; while ((*p != L'\\') && (p != NameString)) { /* No backslash found, keep going */ p--; DriverNameLength += sizeof(WCHAR); } /* Now we probably hit the backslash itself, skip past it */ if (*p == L'\\') { p++; DriverNameLength -= sizeof(WCHAR); } /* * Now make sure that the driver name fits in the buffer, minus * 3 NULL chars (driver name, device name, and remaining strings), * and copy the driver name in the string buffer. */ DriverNameLength = min(DriverNameLength, RemainingLength - 3 * sizeof(UNICODE_NULL)); RtlCopyMemory(StringBuffer, p, DriverNameLength); } /* Null-terminate the driver name */ *((PWSTR)(StringBuffer + DriverNameLength)) = UNICODE_NULL; DriverNameLength += sizeof(WCHAR); /* Go to the next string buffer position */ StringBuffer += DriverNameLength; RemainingLength -= DriverNameLength; /* Update the string offset */ ErrorMessage->EntryData.StringOffset = (USHORT)((ULONG_PTR)StringBuffer - (ULONG_PTR)ErrorMessage); /* Check if we have a device object */ if (LogEntry->DeviceObject) { /* We do, query its name */ Status = ObQueryNameString(LogEntry->DeviceObject, ObjectNameInfo, sizeof(Buffer) - DriverNameLength, &ReturnedLength); if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0)) { /* Setup an empty name */ RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, L"", 0); /* Check if we failed because our buffer wasn't large enough */ if (Status == STATUS_INFO_LENGTH_MISMATCH) { /* Then we'll allocate one... we really want this name! */ PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool, ReturnedLength, TAG_IO); if (PoolObjectNameInfo) { /* Query it again */ ObjectNameInfo = PoolObjectNameInfo; Status = ObQueryNameString(LogEntry->DeviceObject, ObjectNameInfo, ReturnedLength, &ReturnedLength); if (NT_SUCCESS(Status)) { /* Success, update the information */ ObjectNameInfo->Name.Length = IO_ERROR_OBJECT_NAMES_LENGTH - (USHORT)DriverNameLength; } } } } NameString = ObjectNameInfo->Name.Buffer; DeviceNameLength = ObjectNameInfo->Name.Length; } else { /* No device object, setup an empty name */ NameString = L""; DeviceNameLength = 0; } /* * Now make sure that the device name fits in the buffer, minus * 2 NULL chars (device name, and remaining strings), and copy * the device name in the string buffer. */ DeviceNameLength = min(DeviceNameLength, RemainingLength - 2 * sizeof(UNICODE_NULL)); RtlCopyMemory(StringBuffer, NameString, DeviceNameLength); /* Null-terminate the device name */ *((PWSTR)(StringBuffer + DeviceNameLength)) = UNICODE_NULL; DeviceNameLength += sizeof(WCHAR); /* Free the buffer if we had one */ if (PoolObjectNameInfo) { ExFreePoolWithTag(PoolObjectNameInfo, TAG_IO); PoolObjectNameInfo = NULL; } /* Go to the next string buffer position */ ErrorMessage->EntryData.NumberOfStrings++; StringBuffer += DeviceNameLength; RemainingLength -= DeviceNameLength; /* Check if we have any extra strings */ if (Packet->NumberOfStrings) { /* Find out the size of the extra strings */ ExtraStringLength = LogEntry->Size - sizeof(ERROR_LOG_ENTRY) - Packet->StringOffset; /* Round up the length */ ExtraStringLength = ROUND_UP(ExtraStringLength, sizeof(WCHAR)); /* Make sure that the extra strings fit in our buffer */ if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL))) { /* They wouldn't, so set normalize the length */ MessageLength -= ExtraStringLength - RemainingLength; ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL); } /* Now copy the extra strings */ RtlCopyMemory(StringBuffer, (PCHAR)Packet + Packet->StringOffset, ExtraStringLength); /* Null-terminate them */ *((PWSTR)(StringBuffer + ExtraStringLength)) = UNICODE_NULL; } /* Set the driver name length */ ErrorMessage->DriverNameLength = (USHORT)DriverNameLength; /* Update the message length to include the driver and device names */ MessageLength += DriverNameLength + DeviceNameLength; ErrorMessage->Size = (USHORT)MessageLength; /* Now update it again for the size of the actual LPC */ MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) - FIELD_OFFSET(ELF_API_MSG, Unknown[0])); /* Set the total and data lengths */ Message->Header.u1.s1.TotalLength = (USHORT)(sizeof(PORT_MESSAGE) + MessageLength); Message->Header.u1.s1.DataLength = (USHORT)MessageLength; /* Send the message */ Status = ZwRequestPort(IopLogPort, &Message->Header); if (!NT_SUCCESS(Status)) { /* * An error happened while sending the message on the port. * Close the port, requeue the log message on top of the list * and restart the worker. */ ZwClose(IopLogPort); IopLogPortConnected = FALSE; ExInterlockedInsertHeadList(&IopErrorLogListHead, &LogEntry->ListEntry, &IopLogListLock); IopRestartLogWorker(); break; } /* NOTE: The following is basically 'IoFreeErrorLogEntry(Packet)' */ /* Dereference both objects */ if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject); if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject); /* Decrease the total allocation size and free the entry */ InterlockedExchangeAdd(&IopTotalLogSize, -(LONG)LogEntry->Size); ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG); } /* Free the LPC Message */ ExFreePoolWithTag(Message, TAG_IO); }
NTSTATUS CleanupRtAddress( IN PDEVICE pDevice, IN PIRP pIrp) /*++ Routine Description; This Routine handles closing the Rt Object that is used by by RT to send and receive name service datagrams on port 137. Arguments; pIrp - a ptr to an IRP Return Value; NTSTATUS - status of the request --*/ { NTSTATUS status; PRT_INFO pRt; CTELockHandle OldIrq; PLIST_ENTRY pHead; ULONG Index; PLIST_ENTRY pLE; PIRP pTmpIrp; IpxPrint0("CleanupRtAddress - entered\n"); // // if the endpoint structure is allocated, then deallocate it // // pRt = REQUEST_OPEN_CONTEXT(pIrp); pRt = pRtInfo; Index = RT_ADDRESS_INDEX(pIrp); IpxPrint1("CleanupRtAdd: Index = (%d)\n", Index); IpxVerifyRt(pRt); CTEAssert(pRt && (pRt == pRtInfo)); CTEAssert(Index < IPX_RT_MAX_ADDRESSES); do { PLIST_ENTRY pRcvEntry; PRTRCV_BUFFER pRcv; PRT_IRP pRtAddFl = &pRt->AddFl[Index]; CTEAssert(pRtAddFl->State == RT_OPEN); IpxPrint1("CleanupRtAddress: Got AF handle = (%lx)\n", pRtAddFl); IpxReferenceRt(pRt, RT_CLEANUP); status = STATUS_SUCCESS; CTEGetLock (&pRt->Lock, &OldIrq); // // prevent any more dgram getting queued up // pRtAddFl->State = RT_CLOSING; CTEFreeLock (&pRt->Lock, OldIrq); // // free any rcv buffers that may be queued up // pHead = &pRtAddFl->RcvList; while (pRcvEntry = ExInterlockedRemoveHeadList(pHead, &pRt->Lock)) { pRcv = CONTAINING_RECORD(pRcvEntry,RTRCV_BUFFER,Linkage); CTEAssert(pRcv); IpxPrint1("CleanupRtAddress:Freeing buffer = (%lx)\n", pRcv); RtFreeMem(pRcv,pRcv->TotalAllocSize); } // // Complete all irps that are queued // while (pLE = ExInterlockedRemoveHeadList(&pRtAddFl->RcvIrpList, &pRt->Lock)) { // // The recv irp is here so copy the data to its buffer and // pass it up to RT // pTmpIrp = CONTAINING_RECORD(pLE, IRP, Tail.Overlay.ListEntry); IpxPrint1("CleanupRtAddress: Completing Rt rcv Irp from AdFl queue pIrp=%X\n" ,pTmpIrp); pTmpIrp->IoStatus.Information = 0; pTmpIrp->IoStatus.Status = STATUS_CANCELLED; NTIoComplete(pTmpIrp, (NTSTATUS)-1, (ULONG)-1); } //end of while // // dequeue and complete any irps on the complete queue. // while (pLE = ExInterlockedRemoveHeadList(&pRt->CompletedIrps, &pRt->Lock)) { pTmpIrp = CONTAINING_RECORD(pLE, IRP, Tail.Overlay.ListEntry); if (RT_ADDRESS_INDEX(pTmpIrp) == Index) { IpxPrint1("CleanupRtAddress:Completing Rt rcv Irp from CompleteIrps queue pIrp=%X\n" ,pTmpIrp); pTmpIrp->IoStatus.Information = 0; pTmpIrp->IoStatus.Status = STATUS_CANCELLED; NTIoComplete(pTmpIrp, (NTSTATUS)-1, (ULONG)-1); } else { ExInterlockedInsertHeadList(&pRt->HolderIrpsList, pLE, &pRt->Lock); } } CTEGetLock(&pRt->Lock, &OldIrq); while(!IsListEmpty(&pRt->HolderIrpsList)) { pLE = RemoveHeadList(&pRt->HolderIrpsList); InsertHeadList(&pRt->CompletedIrps, pLE); } CTEFreeLock(&pRt->Lock, OldIrq); // // Store AF pointer in Irp since we will now be freeing the address file // (in driver.c). // // // We always have addressfile in the Irp // // REQUEST_OPEN_CONTEXT(pIrp) = (PVOID)(pRtAddFl->AddressFile); IpxDereferenceRt(pRt, RT_CLEANUP); } while (FALSE); IpxPrint0("CleanupRtAddress: Return\n"); return(status); }
/* kd> dt ndis!_NDIS_PROTOCOL_BLOCK +0x000 Header : _NDIS_OBJECT_HEADER +0x004 ProtocolDriverContext : Ptr32 Void +0x008 NextProtocol : Ptr32 _NDIS_PROTOCOL_BLOCK +0x00c OpenQueue : Ptr32 _NDIS_OPEN_BLOCK win7 */ BOOLEAN EnumNetCards() { PNDIS_MINIPORT_BLOCK pMiniBlock=NULL; PNDIS_COMMON_OPEN_BLOCK_2k3_early pOpenBlock=NULL; ULONG MiniDriverBlockHeader ; ULONG NetCardType = 0; LIST_ENTRY *pListEntry=NULL; NETCARDS_INFO *pNI=NULL; NTSTATUS status = STATUS_SUCCESS; ULONG uTmp=0; ADAPTER_INFOEX *pAdapterInfoEx = NULL; ADAPTER_INFO AI; WCHAR *p1,*p2; ULONG index=0; UNICODE_STRING uniTmp; DWORD dwVersion=0; PKK_NDIS_PROTOCOL_BLOCK pProtocol = (PKK_NDIS_PROTOCOL_BLOCK)GetProtocolHeader(); dwVersion = GetWindowsVersion(); p1=p2=NULL; //清空列表 if (!IsListEmpty(&g_NetCardsInfoHeader.Next)) { ExInterlockedRemoveHeadList(&g_NetCardsInfoHeader.Next, &g_NetCardsInfoLock); // LockResource(&g_NetCardsInfoLock, TRUE); // pListEntry = RemoveHeadList(&g_NetCardsInfoHeader.Next); // UnlockResource(&g_NetCardsInfoLock); pNI = CONTAINING_RECORD(pListEntry, NETCARDS_INFO, Next); if (NULL==pNI) { DbgBreakPoint(); } RtlFreeAnsiString(&pNI->Name); kfree(pNI); } status = GetAdapterInfo(NULL, &uTmp); if (status==STATUS_BUFFER_TOO_SMALL) { pAdapterInfoEx = kmalloc(uTmp); RtlZeroMemory(pAdapterInfoEx, uTmp); if (NULL== pAdapterInfoEx) { return FALSE; } } status = GetAdapterInfo(pAdapterInfoEx, &uTmp); if (pAdapterInfoEx->uNumber==0) { kprintf("GetAdapterInfo() return pAdapterInfoEx->uNumber==0"); kfree(pAdapterInfoEx); return FALSE; } while (pProtocol) { //search for the nic driver block if (dwVersion==Windows_7||dwVersion==Windows_Vista) { if (((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->OpenQueue==0) { goto NextBlock; } } else { if (pProtocol->OpenQueue==NULL) { goto NextBlock; } } uTmp=0; //现在使用了protocol链表,所以要防止一个miniport多次使用的情况 if (dwVersion==Windows_Vista||dwVersion==Windows_7) { PNDIS_OPEN_BLOCKWIN7 pOP7 = (PNDIS_OPEN_BLOCKWIN7)((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->OpenQueue; pMiniBlock = pOP7->MiniportHandle; } else { pMiniBlock = pProtocol->OpenQueue->MiniportHandle; } pListEntry = g_NetCardsInfoHeader.Next.Flink; while(pListEntry&& (pListEntry!=&g_NetCardsInfoHeader.Next)) { pNI = CONTAINING_RECORD(pListEntry, NETCARDS_INFO, Next); if (pNI==NULL) { kprintf("Crash......when checking pMiniBlock is in g_NetCardsInfoHeader already\n"); return FALSE; // DbgBreakPoint(); } if (pNI->pMiniBlock==pMiniBlock) { uTmp = 1; break; } pListEntry = pListEntry->Flink; } if (uTmp==1) { //这个miniport已经使用过了 goto NextBlock; } NetCardType = IsPhysicalMiniport(pMiniBlock); //只取物理网卡 if (NetCardType==0) { goto NextBlock; } pNI = kmalloc(sizeof(NETCARDS_INFO)); RtlZeroMemory(pNI, sizeof(NETCARDS_INFO)); if (NetCardType==1) { SetFlag(pNI->flag, REGULARNETCARD); } if (NetCardType==2) { SetFlag(pNI->flag, WIRELESSNETCARD); } /* p_mini_block->SymbolicLinkName 亦可直接Createfile (p_mini_block->SymbolicLinkName....)发OID_802_3_CURRENT_ADDRESS来查询 */ pNI->pMiniBlock = pMiniBlock; uTmp =0; for (index=0; index<pAdapterInfoEx->uNumber; index++) { p1 = kmalloc(pMiniBlock->SymbolicLinkName.Length+2); RtlZeroMemory(p1, pMiniBlock->SymbolicLinkName.Length+2); RtlCopyMemory(p1, pMiniBlock->SymbolicLinkName.Buffer, pMiniBlock->SymbolicLinkName.Length); AI = pAdapterInfoEx->pAI[index]; p2 = kmalloc(AI.GUID.Length+2); RtlZeroMemory(p2, AI.GUID.Length+2); RtlCopyMemory(p2, AI.GUID.Buffer, AI.GUID.Length); _wcsupr(p1);_wcsupr(p2); if (wcsstr(p1,p2)) { kfree(p1);kfree(p2); uTmp = 1; break; //找到了,已经获取网卡MAC地址 } kfree(p1);kfree(p2); }//end for (index=0; index<pAdapterInfoEx->uNumber; index++) if (uTmp==1) { RtlCopyMemory(pNI->MacAddr, AI.macAddress, sizeof(pNI->MacAddr)); pNI->IPAddr = AI.IPAddr; pNI->GatewayIpAddr = AI.GatewayIpAddr; if (pAdapterInfoEx->pAI[index].bDhcp) { SetFlag(pNI->flag, DHCPENABLE); } ExInterlockedInsertHeadList(&g_NetCardsInfoHeader.Next, &pNI->Next, &g_NetCardsInfoLock); // LockResource(&g_NetCardsInfoLock, TRUE); // InsertHeadList(&g_NetCardsInfoHeader.Next, &pNI->Next); // UnlockResource(&g_NetCardsInfoLock); } else { kfree(pNI); pNI = NULL; goto NextBlock; } // if ((p_mini_block->Flags&ISCONNECTED)) // { // SetFlag(pNI->flag, ISCONNECTED); // } if (AI.status==NdisMediaStateConnected) { SetFlag(pNI->flag, ISCONNECTED); } //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318} GetNicNameByGUID(&AI.GUID, &uniTmp); RtlUnicodeStringToAnsiString(&pNI->Name, &uniTmp, TRUE); kprintf("\r\n 检举网卡信息如下:\r\nMAC : %02X:%02X:%02X:%02X:%02X:%02X \nIP :0x%x \nflag:0X%X \n网关IP:0x%x \nName: %Z \n\n", pNI->MacAddr[0], pNI->MacAddr[1], pNI->MacAddr[2], pNI->MacAddr[3], pNI->MacAddr[4], pNI->MacAddr[5], (pNI->IPAddr), pNI->flag, (pNI->GatewayIpAddr),&pNI->Name); NextBlock: if (dwVersion==Windows_Vista||dwVersion==Windows_7) { pProtocol = (PKK_NDIS_PROTOCOL_BLOCK )((PNDIS_PROTOCOL_BLOCKWin7)pProtocol)->NextProtocol; } else pProtocol = pProtocol->NextProtocol; } //end while (p_driver_block->NextDriver) //释放上面申请的内容 for (index=0; index<pAdapterInfoEx->uNumber; index++) { kfree(pAdapterInfoEx->pAI[index].GUID.Buffer); } kfree(pAdapterInfoEx); return 1; }
NTSTATUS FWDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; PVOID ioBuf; ULONG inBufLength, outBufLength; ULONG ioControlCode; ULONG_PTR num=0; irpStack = IoGetCurrentIrpStackLocation(Irp); deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; Irp->IoStatus.Information = 0; // // Get the pointer to the input/output buffer and it's length // ioBuf = Irp->AssociatedIrp.SystemBuffer; inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; // Irp->UserBuffer; // If METHOD_NEITHER, This is Output Buffer switch (ioControlCode) { case IOCTL_SETUPFW: { // if (g_AlreadyHookTCPIP) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); } else { Status= FWHookTcpipRecvHandler(); if (NT_SUCCESS(Status)) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); g_AlreadyHookTCPIP = 1; } } break; } case IOCTL_UNSETFW: { // InterlockedExchange(&g_InterceptTCPIPRcv, 0); //UNHOOK的行为就放到驱动卸载时候了 break; } case IOCTL_PENDDINGCHECKPORT: { //pendding进去 IoMarkIrpPending(Irp); ExInterlockedInsertHeadList(&g_AskUserConnectListHeader, &Irp->Tail.Overlay.ListEntry, &g_AskUserConnectListLock); Status= STATUS_PENDING; Irp->IoStatus.Status = Status; return Status; break; } case IOCTL_SETONEPORTSTATUS: { Status = SetupPortStatus(ioBuf, 1); break; } case IOCTL_RESPONSEPORTASK: { Status = ResponsePortAsk((PFIREWALL_ASKUSER)ioBuf); break; } case IOCTL_ReleasePENDDINGCHECKPORT: { Status = ReleasePenddingCheckPortIrp(); break; } case IOCTL_GETPORTSTATUS: { Status = GetPortRules(ioBuf, &outBufLength); if (Status==STATUS_INFO_LENGTH_MISMATCH) { Status = STATUS_SUCCESS; } Irp->IoStatus.Information = outBufLength; break; } default: { //Status = STATUS_INVALID_PARAMETER; kprintf("[SuperCI] Unknown IOCTL: 0x%X (%04X,%04X)\n", ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), IoGetFunctionCodeFromCtlCode(ioControlCode)); break; } } Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }