NTSTATUS FWHookTcpipRecvHandler() { PKK_NDIS_PROTOCOL_BLOCK pTcpipProtocolBlcok=NULL; PKK_NDIS_PROTOCOL_BLOCK pProtocolBlockHeader=NULL; ULONG ut1,ut2; PNDIS_COMMON_OPEN_BLOCK_2k3_early pOpenBlock=NULL; NTSTATUS status = STATUS_SUCCESS; PNDIS_HOOK_INFO pHI ; PULONG ptmp; PLOCK_STATE pLockState1=NULL; #ifdef VMPROTECT VMProtectBeginVirtualization("FWHookTcpipRecvHandler"); #endif pLockState1 = kmalloc(sizeof(LOCK_STATE)); ut1 = ut2 = 0; do { pTcpipProtocolBlcok = (PKK_NDIS_PROTOCOL_BLOCK)GetTcpipProtocolBlock(); if (pTcpipProtocolBlcok==0) { status = STATUS_UNSUCCESSFUL; break; } pOpenBlock = pTcpipProtocolBlcok->OpenQueue; NdisAcquireReadWriteLock(&g_HookTcpipFireWallLock, KKRWLOCK_FOR_WRITE, pLockState1); while(pOpenBlock) { // if (!IsPhysicalMiniport(pOpenBlock->MiniportHandle)) // { // goto __nextpOpenBlock; // } pHI = kmalloc(sizeof(NDIS_HOOK_INFO)); ptmp=NULL; RtlZeroMemory(pHI, sizeof(NDIS_HOOK_INFO)); pHI->OldHandler = (PVOID)pOpenBlock->ReceiveHandler; pHI->Address2Restore = &(pOpenBlock->ReceiveHandler); pHI->pMiniBlock = (ULONG)pOpenBlock->MiniportHandle; pHI->pSignContext = (PVOID)pOpenBlock->ProtocolBindingContext; pHI->pProtocolBindingContext = (ULONG)pOpenBlock->ProtocolBindingContext; pHI->pOpenblock = (ULONG_PTR)pOpenBlock; pHI->szFuncname = "KKNewTcpipArpRcv"; pHI->NewHandler = (PVOID)KKNewTcpipArpRcv; *(PULONG)&(pOpenBlock->ReceivePacketHandler)=0; //把这个清0了 InsertHeadList(&g_HookTcpipFireWallList.Next, &pHI->Next); ptmp = (ULONG*)pHI->Address2Restore; *ptmp = (ULONG)KKNewTcpipArpRcv; //__nextpOpenBlock: pOpenBlock = (PNDIS_COMMON_OPEN_BLOCK_2k3_early)pOpenBlock->ProtocolNextOpen; } NdisReleaseReadWriteLock(&g_HookTcpipFireWallLock, pLockState1); } while (0); if (pLockState1) { kfree(pLockState1); } #ifdef VMPROTECT VMProtectEnd(); #endif return status; }
VOID LurnResetFaultInfo(PLURELATION_NODE Lurn) { RtlZeroMemory(&Lurn->FaultInfo, sizeof(LURN_FAULT_INFO)); }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvRegEnumerateValueKeys // Enumerates and print names of sub value keys using a given registry key handle. // // Arguments: // IN RegKeyHandle // Handle to root key // // Return Value: // none // VOID testdrvRegEnumerateValueKeys( IN HANDLE RegKeyHandle ) { NTSTATUS status; ULONG index; PKEY_VALUE_BASIC_INFORMATION regBuffer; PWCHAR nameBuffer; ULONG length; status = STATUS_SUCCESS; index = 0; regBuffer = NULL; nameBuffer = NULL; while (status != STATUS_NO_MORE_ENTRIES) { // Get the buffer size necessary status = ZwEnumerateValueKey( RegKeyHandle, index, KeyValueBasicInformation, NULL, 0, &length ); if ((status != STATUS_BUFFER_TOO_SMALL) && (status != STATUS_BUFFER_OVERFLOW)) { if (status != STATUS_NO_MORE_ENTRIES) { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status); } else { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": Enumerated %d value keys", index); } break; } regBuffer = (PKEY_VALUE_BASIC_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, TESTDRV_POOL_TAG); if (regBuffer == NULL) { continue; } // Now actually attempt to get subkey info status = ZwEnumerateValueKey( RegKeyHandle, index, KeyValueBasicInformation, regBuffer, length, &length ); if (!NT_SUCCESS(status)) { testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey failed %x", status); // Free our temporary storage ExFreePool(regBuffer); continue; } // Allocate a buffer for the display name nameBuffer = (PWCHAR)ExAllocatePoolWithTag( PagedPool, regBuffer->NameLength + sizeof(WCHAR), TESTDRV_POOL_TAG ); if (nameBuffer == NULL) { // Free our temporary storage ExFreePool(regBuffer); continue; } // NULL terminate the string RtlZeroMemory(nameBuffer, regBuffer->NameLength + sizeof(WCHAR)); // Copy the name over RtlCopyMemory(nameBuffer, regBuffer->Name, regBuffer->NameLength); testdrvDebugPrint(DBG_PNP, DBG_INFO, __FUNCTION__ ": ZwEnumerateValueKey returned %S", nameBuffer); // Free both buffers ExFreePool(regBuffer); ExFreePool(nameBuffer); // Increment our index ++index; } return; }
DWORD MonitorAppAddFilters( _In_ HANDLE engineHandle, _In_ FWP_BYTE_BLOB* applicationPath) /*++ Routine Description: Adds the required sublayer, filters and callouts to the Windows Filtering Platform (WFP). Arguments: [in] HANDLE engineHandle - Handle to the base Filtering engine [in] FWP_BYTE_BLOB* applicationPath - full path to the application including the NULL terminator and size also including the NULL the terminator [in] CALLOUTS* callouts - The callouts that need to be added. Return Value: NO_ERROR or a specific result --*/ { DWORD result = NO_ERROR; FWPM_SUBLAYER monitorSubLayer; FWPM_FILTER filter; FWPM_FILTER_CONDITION filterConditions[2]; // We only need two for this call. RtlZeroMemory(&monitorSubLayer, sizeof(FWPM_SUBLAYER)); monitorSubLayer.subLayerKey = MONITOR_SAMPLE_SUBLAYER; monitorSubLayer.displayData.name = L"Monitor Sample Sub layer"; monitorSubLayer.displayData.description = L"Monitor Sample Sub layer"; monitorSubLayer.flags = 0; // We don't really mind what the order of invocation is. monitorSubLayer.weight = 0; printf("Starting Transaction\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully Started Transaction\n"); printf("Adding Sublayer\n"); result = FwpmSubLayerAdd(engineHandle, &monitorSubLayer, NULL); if (NO_ERROR != result) { goto abort; } printf("Sucessfully added Sublayer\n"); RtlZeroMemory(&filter, sizeof(FWPM_FILTER)); filter.layerKey = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4; filter.displayData.name = L"Flow established filter."; filter.displayData.description = L"Sets up flow for traffic that we are interested in."; filter.action.type = FWP_ACTION_CALLOUT_INSPECTION; // We're only doing inspection. filter.action.calloutKey = MONITOR_SAMPLE_FLOW_ESTABLISHED_CALLOUT_V4; filter.filterCondition = filterConditions; filter.subLayerKey = monitorSubLayer.subLayerKey; filter.weight.type = FWP_EMPTY; // auto-weight. filter.numFilterConditions = 2; RtlZeroMemory(filterConditions, sizeof(filterConditions)); // // Add the application path to the filter conditions. // filterConditions[0].fieldKey = FWPM_CONDITION_ALE_APP_ID; filterConditions[0].matchType = FWP_MATCH_EQUAL; filterConditions[0].conditionValue.type = FWP_BYTE_BLOB_TYPE; filterConditions[0].conditionValue.byteBlob = applicationPath; // // For the purposes of this sample, we will monitor TCP traffic only. // filterConditions[1].fieldKey = FWPM_CONDITION_IP_PROTOCOL; filterConditions[1].matchType = FWP_MATCH_EQUAL; filterConditions[1].conditionValue.type = FWP_UINT8; filterConditions[1].conditionValue.uint8 = IPPROTO_TCP; printf("Adding Flow Established Filter\n"); result = FwpmFilterAdd(engineHandle, &filter, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully added Flow Established filter\n"); RtlZeroMemory(&filter, sizeof(FWPM_FILTER)); filter.layerKey = FWPM_LAYER_STREAM_V4; filter.action.type = FWP_ACTION_CALLOUT_INSPECTION; // We're only doing inspection. filter.action.calloutKey = MONITOR_SAMPLE_STREAM_CALLOUT_V4; filter.subLayerKey = monitorSubLayer.subLayerKey; filter.weight.type = FWP_EMPTY; // auto-weight. filter.numFilterConditions = 0; RtlZeroMemory(filterConditions, sizeof(filterConditions)); filter.filterCondition = filterConditions; filter.displayData.name = L"Stream Layer Filter"; filter.displayData.description = L"Monitors TCP traffic."; printf("Adding Stream Filter\n"); result = FwpmFilterAdd(engineHandle, &filter, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully added Stream filter\n"); printf("Committing Transaction\n"); result = FwpmTransactionCommit(engineHandle); if (NO_ERROR == result) { printf("Successfully Committed Transaction\n"); } goto cleanup; abort: printf("Aborting Transaction\n"); result = FwpmTransactionAbort(engineHandle); if (NO_ERROR == result) { printf("Successfully Aborted Transaction\n"); } cleanup: return result; }
static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { REGS RegsIn; REGS RegsOut; ULONG RetryCount; PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER); TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer); ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF); // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ RegsIn.b.ah = 0x42; // Subfunction 42h RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk) RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet RegsIn.w.si = BIOSCALLBUFOFFSET; // Setup disk address packet RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET)); Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET); Packet->Reserved = 0; Packet->LBABlockCount = (USHORT)SectorCount; ASSERT(Packet->LBABlockCount == SectorCount); Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F; Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4); Packet->LBAStartBlock = SectorNumber; // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ // Return: // CF clear if successful // AH = 00h // CF set on error // AH = error code // disk address packet's block count field set to the // number of blocks successfully transferred // Retry 3 times for (RetryCount=0; RetryCount<3; RetryCount++) { Int386(0x13, &RegsIn, &RegsOut); // If it worked return TRUE if (INT386_SUCCESS(RegsOut)) { return TRUE; } // If it was a corrected ECC error then the data is still good else if (RegsOut.b.ah == 0x11) { return TRUE; } // If it failed the do the next retry else { PcDiskResetController(DriveNumber); continue; } } // If we get here then the read failed ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount); return FALSE; }
/* * @implemented */ VOID EXPORT NdisRegisterProtocol( OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE NdisProtocolHandle, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics, IN UINT CharacteristicsLength) /* * FUNCTION: Registers an NDIS driver's ProtocolXxx entry points * ARGUMENTS: * Status = Address of buffer for status information * NdisProtocolHandle = Address of buffer for handle used to identify the driver * ProtocolCharacteristics = Pointer to NDIS_PROTOCOL_CHARACTERISTICS structure * CharacteristicsLength = Size of structure which ProtocolCharacteristics targets * NOTES: * - you *must* set NdisProtocolHandle before doing anything that could wind up * getting BindAdapterHandler, as it will probably call OpenAdapter with this handle * - the above implies that the initialization of the protocol block must be complete * by then * TODO: * - break this function up - probably do a 'ndisRefreshProtocolBindings' function * - make this thing able to handle >1 protocol */ { PPROTOCOL_BINDING Protocol; NTSTATUS NtStatus; UINT MinSize; PNET_PNP_EVENT PnPEvent; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); *NdisProtocolHandle = NULL; /* first validate the PROTOCOL_CHARACTERISTICS */ switch (ProtocolCharacteristics->MajorNdisVersion) { case 0x03: /* we don't really want to support ndis3 drivers - so we complain for now */ NDIS_DbgPrint(MID_TRACE, ("NDIS 3 protocol attempting to register\n")); MinSize = sizeof(NDIS30_PROTOCOL_CHARACTERISTICS); break; case 0x04: MinSize = sizeof(NDIS40_PROTOCOL_CHARACTERISTICS); break; case 0x05: MinSize = sizeof(NDIS50_PROTOCOL_CHARACTERISTICS); break; default: *Status = NDIS_STATUS_BAD_VERSION; NDIS_DbgPrint(MIN_TRACE, ("Incorrect characteristics size\n")); return; } if (CharacteristicsLength < MinSize) { NDIS_DbgPrint(MIN_TRACE, ("Bad protocol characteristics.\n")); *Status = NDIS_STATUS_BAD_CHARACTERISTICS; return; } /* set up the protocol block */ Protocol = ExAllocatePool(NonPagedPool, sizeof(PROTOCOL_BINDING)); if (!Protocol) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); *Status = NDIS_STATUS_RESOURCES; return; } RtlZeroMemory(Protocol, sizeof(PROTOCOL_BINDING)); RtlCopyMemory(&Protocol->Chars, ProtocolCharacteristics, MinSize); NtStatus = RtlUpcaseUnicodeString(&Protocol->Chars.Name, &ProtocolCharacteristics->Name, TRUE); if (!NT_SUCCESS(NtStatus)) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); ExFreePool(Protocol); *Status = NDIS_STATUS_RESOURCES; return; } KeInitializeSpinLock(&Protocol->Lock); InitializeListHead(&Protocol->AdapterListHead); /* We must set this before the call to ndisBindMiniportsToProtocol because the protocol's * BindAdapter handler might need it */ *NdisProtocolHandle = Protocol; ndisBindMiniportsToProtocol(Status, Protocol); /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */ PnPEvent = ProSetupPnPEvent(NetEventBindsComplete, NULL, 0); if (PnPEvent) { if (Protocol->Chars.PnPEventHandler) { /* We call this with a NULL binding context because it affects all bindings */ NtStatus = (*Protocol->Chars.PnPEventHandler)(NULL, PnPEvent); /* FIXME: We don't support this yet */ ASSERT(NtStatus != NDIS_STATUS_PENDING); } ExFreePool(PnPEvent); } if (*Status == NDIS_STATUS_SUCCESS) { ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); } else { NDIS_DbgPrint(MIN_TRACE, ("Binding failed (%x)\n", *Status)); ExFreePool(Protocol); *NdisProtocolHandle = NULL; } }
DWORD MonitorAppAddCallouts() /*++ Routine Description: Adds the callouts during installation Arguments: [in] PCWSTR AppPath - The path to the application to monitor. Return Value: NO_ERROR or a specific FWP result. --*/ { FWPM_CALLOUT callout; DWORD result; FWPM_DISPLAY_DATA displayData; HANDLE engineHandle = NULL; FWPM_SESSION session; RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Sample Non-Dynamic Session"; session.displayData.description = L"For Adding callouts"; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Starting Transaction for adding callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); RtlZeroMemory(&callout, sizeof(FWPM_CALLOUT)); displayData.description = MONITOR_FLOW_ESTABLISHED_CALLOUT_DESCRIPTION; displayData.name = MONITOR_FLOW_ESTABLISHED_CALLOUT_NAME; callout.calloutKey = MONITOR_SAMPLE_FLOW_ESTABLISHED_CALLOUT_V4; callout.displayData = displayData; callout.applicableLayer = FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4; callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; // Make this a persistent callout. printf("Adding Persistent Flow Established callout through the Filtering Engine\n"); result = FwpmCalloutAdd(engineHandle, &callout, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully Added Persistent Flow Established callout.\n"); RtlZeroMemory(&callout, sizeof(FWPM_CALLOUT)); displayData.description = MONITOR_STREAM_CALLOUT_DESCRIPTION; displayData.name = MONITOR_STREAM_CALLOUT_DESCRIPTION; callout.calloutKey = MONITOR_SAMPLE_STREAM_CALLOUT_V4; callout.displayData = displayData; callout.applicableLayer = FWPM_LAYER_STREAM_V4; callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT; // Make this a persistent callout. printf("Adding Persistent Stream callout through the Filtering Engine\n"); result = FwpmCalloutAdd(engineHandle, &callout, NULL, NULL); if (NO_ERROR != result) { goto abort; } printf("Successfully Added Persistent Stream callout.\n"); printf("Committing Transaction\n"); result = FwpmTransactionCommit(engineHandle); if (NO_ERROR == result) { printf("Successfully Committed Transaction.\n"); } goto cleanup; abort: printf("Aborting Transaction\n"); result = FwpmTransactionAbort(engineHandle); if (NO_ERROR == result) { printf("Successfully Aborted Transaction.\n"); } cleanup: if (engineHandle) { FwpmEngineClose(engineHandle); } return result; }
NTSTATUS XixfsGetNdasBacl( IN PDEVICE_OBJECT DeviceObject, OUT PNDAS_BLOCK_ACL NdasBacl, IN BOOLEAN SystemOrUser ) { NTSTATUS RC = STATUS_SUCCESS; BOOLEAN result; PSRB_IO_CONTROL pSrbIoCtl; PNDASSCSI_QUERY_INFO_DATA QueryInfo; int OutbuffSize = 0; PUCHAR outBuff = NULL; PDEVICE_OBJECT scsiAdpaterDeviceObject; PAGED_CODE(); ASSERT(DeviceObject); // need somemore ASSERT( NdasBacl->Length >= sizeof(NDASSCSI_QUERY_INFO_DATA) ); result = XixFsGetScsiportAdapter(DeviceObject, &scsiAdpaterDeviceObject); if(result != TRUE){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixfsGetNdasBacl!!! \n")); return STATUS_UNSUCCESSFUL; } if(NdasBacl->Length < sizeof(NDASSCSI_QUERY_INFO_DATA)){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixfsGetNdasBacl : TOO SAMLL BUFFER !!! \n")); return STATUS_UNSUCCESSFUL; } OutbuffSize = sizeof(SRB_IO_CONTROL) + NdasBacl->Length; OutbuffSize = SECTORALIGNSIZE_512(OutbuffSize); pSrbIoCtl = (PSRB_IO_CONTROL)ExAllocatePool(NonPagedPool , OutbuffSize); if(!pSrbIoCtl){ ObDereferenceObject(scsiAdpaterDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } try{ RtlZeroMemory(pSrbIoCtl, OutbuffSize); pSrbIoCtl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(pSrbIoCtl->Signature, NDASSCSI_IOCTL_SIGNATURE, 8); pSrbIoCtl->Timeout = 10; pSrbIoCtl->ControlCode = NDASSCSI_IOCTL_QUERYINFO_EX; pSrbIoCtl->Length = OutbuffSize; QueryInfo = (PNDASSCSI_QUERY_INFO_DATA)((PUCHAR)pSrbIoCtl + sizeof(SRB_IO_CONTROL)); outBuff = (PUCHAR)QueryInfo; QueryInfo->Length = sizeof(NDASSCSI_QUERY_INFO_DATA); QueryInfo->InfoClass = SystemOrUser?NdscSystemBacl:NdscUserBacl; QueryInfo->QueryDataLength = 0; //Fist step Send Disk RC = XixFsRawDevIoCtrl ( DeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(NT_SUCCESS(RC)){ RtlCopyMemory(NdasBacl, outBuff, NdasBacl->Length); }else{ // Send port RC = XixFsRawDevIoCtrl ( scsiAdpaterDeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(NT_SUCCESS(RC)){ RtlCopyMemory(NdasBacl, outBuff, NdasBacl->Length); } } }finally{ ObDereferenceObject(scsiAdpaterDeviceObject); ExFreePool(pSrbIoCtl); } return RC; }
NTSTATUS XixFsCheckXifsd( PDEVICE_OBJECT DeviceObject, PPARTITION_INFORMATION partitionInfo, PBLOCKACE_ID BlockAceId, PBOOLEAN IsWriteProtected ) { NTSTATUS RC = STATUS_SUCCESS; NDSCIOCTL_PRIMUNITDISKINFO DiskInfo; NDAS_BLOCK_ACE Partition_BACL; ASSERT(DeviceObject); *IsWriteProtected = FALSE; DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Enter XixFsSetXifsd \n")); try{ RC = XixFsGetNdadDiskInfo(DeviceObject, &DiskInfo); if(NT_SUCCESS(RC)) { // is device support ndas lock if((DiskInfo.Lur.SupportedFeatures & (NDASFEATURE_GP_LOCK|NDASFEATURE_ADV_GP_LOCK)) == 0 ){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Enter XixFsSetXifsd : don't support lock \n")); RC = STATUS_UNSUCCESSFUL; try_return(RC); } if(DiskInfo.Lur.DeviceMode != DEVMODE_SHARED_READWRITE){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Failed XixFsSetXifsd : don't support read write \n")); // Changed by ILGU HONG for readonly 09052006 *IsWriteProtected = TRUE; RC = STATUS_SUCCESS; // Changed by ILGU HONG for readonly end try_return(RC); } if(DiskInfo.Lur.EnabledFeatures & NDASFEATURE_RO_FAKE_WRITE){ RtlZeroMemory(&Partition_BACL, sizeof(PNDAS_BLOCK_ACE)); Partition_BACL.AccessMode = NBACE_ACCESS_WRITE; Partition_BACL.BlockEndAddr = (partitionInfo->StartingOffset.QuadPart + partitionInfo->PartitionLength.QuadPart)/512 -1; Partition_BACL.BlockStartAddr = partitionInfo->StartingOffset.QuadPart/512; RC = XixFsAddUserBacl(DeviceObject, &Partition_BACL,BlockAceId); if(!NT_SUCCESS(RC)){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Faile XixFsSetXifsd : XixFsAddUserBacl \n")); } } } }finally{ } return RC; }
// Added by ILGU HONG for 08312006 NTSTATUS XixFsGetNdadDiskInfo( IN PDEVICE_OBJECT DeviceObject, OUT PNDSCIOCTL_PRIMUNITDISKINFO PrimUnitDisk ) { NTSTATUS RC = STATUS_SUCCESS; PDEVICE_OBJECT scsiAdpaterDeviceObject = NULL; BOOLEAN result = FALSE; PSRB_IO_CONTROL pSrbIoCtl = NULL; uint32 OutbuffSize = 0; PNDASSCSI_QUERY_INFO_DATA QueryInfo; PNDSCIOCTL_PRIMUNITDISKINFO pPrimUnitDisk; PAGED_CODE(); ASSERT(DeviceObject); DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Enter XixFsGetNdadDeviceInfo \n")); result = XixFsGetScsiportAdapter(DeviceObject, &scsiAdpaterDeviceObject); if(result != TRUE){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail GetScsiportAdpater!!! \n")); return STATUS_UNSUCCESSFUL; } OutbuffSize = sizeof(SRB_IO_CONTROL) + sizeof(NDASSCSI_QUERY_INFO_DATA) + sizeof(NDSCIOCTL_PRIMUNITDISKINFO); OutbuffSize = SECTORALIGNSIZE_512(OutbuffSize); pSrbIoCtl = (PSRB_IO_CONTROL)ExAllocatePoolWithTag(NonPagedPool, OutbuffSize, TAG_BUFFER); if(!pSrbIoCtl){ ObDereferenceObject(scsiAdpaterDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } try{ RtlZeroMemory(pSrbIoCtl, OutbuffSize); pSrbIoCtl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(pSrbIoCtl->Signature, NDASSCSI_IOCTL_SIGNATURE, 8); pSrbIoCtl->Timeout = 10; pSrbIoCtl->ControlCode = NDASSCSI_IOCTL_QUERYINFO_EX; pSrbIoCtl->Length = sizeof(NDASSCSI_QUERY_INFO_DATA) + sizeof(NDSCIOCTL_PRIMUNITDISKINFO); QueryInfo = (PNDASSCSI_QUERY_INFO_DATA)((PUCHAR)pSrbIoCtl + sizeof(SRB_IO_CONTROL)); pPrimUnitDisk = (PNDSCIOCTL_PRIMUNITDISKINFO)((PUCHAR)pSrbIoCtl + sizeof(SRB_IO_CONTROL)); QueryInfo->Length = sizeof(NDASSCSI_QUERY_INFO_DATA); QueryInfo->InfoClass = NdscPrimaryUnitDiskInformation; QueryInfo->QueryDataLength = 0; //Fist step Send Disk RC = XixFsRawDevIoCtrl ( DeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(NT_SUCCESS(RC)){ if(pPrimUnitDisk->Length == sizeof(NDSCIOCTL_PRIMUNITDISKINFO)) { RtlCopyMemory(PrimUnitDisk, pPrimUnitDisk, sizeof(NDSCIOCTL_PRIMUNITDISKINFO)); } DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Success XixFsGetNdadDeviceInfo Status (0x%x)\n", RC)); }else{ // Send port RC = XixFsRawDevIoCtrl ( scsiAdpaterDeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(!NT_SUCCESS(RC)){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixFsGetNdadDeviceInfo Status (0x%x)\n", RC)); }else{ if(pPrimUnitDisk->Length == sizeof(NDSCIOCTL_PRIMUNITDISKINFO)) { RtlCopyMemory(PrimUnitDisk, pPrimUnitDisk, sizeof(NDSCIOCTL_PRIMUNITDISKINFO)); } DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Success XixFsGetNdadDeviceInfo Status (0x%x)\n", RC)); } } }finally{ ObDereferenceObject(scsiAdpaterDeviceObject); ExFreePool(pSrbIoCtl); } DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Exit XixFsGetNdadDeviceInfo Status (0x%x)\n", RC)); return RC; }
NTSTATUS XixFsRemoveUserBacl( IN PDEVICE_OBJECT DeviceObject, IN BLOCKACE_ID BlockAceId ){ NTSTATUS RC = STATUS_SUCCESS; BOOLEAN result; PSRB_IO_CONTROL pSrbIoCtl; int OutbuffSize; PNDSCIOCTL_REMOVE_USERBACL removeNdasBace; PDEVICE_OBJECT scsiAdpaterDeviceObject; PAGED_CODE(); result = XixFsGetScsiportAdapter(DeviceObject, &scsiAdpaterDeviceObject); if(result != TRUE){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixFsRemoveUserBacl!!! \n")); return STATUS_UNSUCCESSFUL; } OutbuffSize = sizeof(SRB_IO_CONTROL) + sizeof(NDASSCSI_QUERY_INFO_DATA) + sizeof(NDSCIOCTL_REMOVE_USERBACL); OutbuffSize = SECTORALIGNSIZE_512(OutbuffSize); pSrbIoCtl = (PSRB_IO_CONTROL)ExAllocatePool(NonPagedPool , OutbuffSize); if(!pSrbIoCtl){ ObDereferenceObject(scsiAdpaterDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } try{ RtlZeroMemory(pSrbIoCtl, OutbuffSize); pSrbIoCtl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(pSrbIoCtl->Signature, NDASSCSI_IOCTL_SIGNATURE, 8); pSrbIoCtl->Timeout = 10; pSrbIoCtl->ControlCode = NDASSCSI_IOCTL_REMOVE_USERBACL; pSrbIoCtl->Length = sizeof(NDSCIOCTL_REMOVE_USERBACL); removeNdasBace = (PNDSCIOCTL_REMOVE_USERBACL)((PUCHAR)pSrbIoCtl + sizeof(SRB_IO_CONTROL)); removeNdasBace->NdasBlockAceId = BlockAceId; //Fist step Send Disk RC = XixFsRawDevIoCtrl ( DeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(!NT_SUCCESS(RC)) { // Send port RC = XixFsRawDevIoCtrl ( scsiAdpaterDeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(!NT_SUCCESS(RC)) { DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixFsRemoveUserBacl Not NetDisk. status = %x\n", RC)); } } }finally{ ObDereferenceObject(scsiAdpaterDeviceObject); ExFreePool(pSrbIoCtl); } return RC; }
// Allocates structures for virtualization, initializes VMCS and virtualizes // the current processor _Use_decl_annotations_ static void VmpInitializeVm( ULONG_PTR guest_stack_pointer, ULONG_PTR guest_instruction_pointer, void *context) { PAGED_CODE(); const auto shared_data = reinterpret_cast<SharedProcessorData *>(context); if (!shared_data) { return; } // Allocate related structures const auto processor_data = reinterpret_cast<ProcessorData *>(ExAllocatePoolWithTag( NonPagedPool, sizeof(ProcessorData), kHyperPlatformCommonPoolTag)); if (!processor_data) { return; } RtlZeroMemory(processor_data, sizeof(ProcessorData)); processor_data->shared_data = shared_data; InterlockedIncrement(&processor_data->shared_data->reference_count); // Set up EPT processor_data->ept_data = EptInitialization(); if (!processor_data->ept_data) { goto ReturnFalse; } // Check if XSAVE/XRSTOR are available and save an instruction mask for all // supported user state components processor_data->xsave_inst_mask = RtlGetEnabledExtendedFeatures(static_cast<ULONG64>(-1)); HYPERPLATFORM_LOG_DEBUG("xsave_inst_mask = %p", processor_data->xsave_inst_mask); if (processor_data->xsave_inst_mask) { // Allocate a large enough XSAVE area to store all supported user state // components. A size is round-up to multiple of the page size so that the // address fulfills a requirement of 64K alignment. // // See: ENUMERATION OF CPU SUPPORT FOR XSAVE INSTRUCTIONS AND XSAVESUPPORTED // FEATURES int cpu_info[4] = {}; __cpuidex(cpu_info, 0xd, 0); const auto xsave_area_size = ROUND_TO_PAGES(cpu_info[2]); // ecx processor_data->xsave_area = ExAllocatePoolWithTag( NonPagedPool, xsave_area_size, kHyperPlatformCommonPoolTag); if (!processor_data->xsave_area) { goto ReturnFalse; } RtlZeroMemory(processor_data->xsave_area, xsave_area_size); } else { // Use FXSAVE/FXRSTOR instead. int cpu_info[4] = {}; __cpuid(cpu_info, 1); const CpuFeaturesEcx cpu_features_ecx = {static_cast<ULONG32>(cpu_info[2])}; const CpuFeaturesEdx cpu_features_edx = {static_cast<ULONG32>(cpu_info[3])}; if (cpu_features_ecx.fields.avx) { HYPERPLATFORM_LOG_ERROR("A processor supports AVX but not XSAVE/XRSTOR."); goto ReturnFalse; } if (!cpu_features_edx.fields.fxsr) { HYPERPLATFORM_LOG_ERROR("A processor does not support FXSAVE/FXRSTOR."); goto ReturnFalse; } } // Allocate other processor data fields processor_data->vmm_stack_limit = UtilAllocateContiguousMemory(KERNEL_STACK_SIZE); if (!processor_data->vmm_stack_limit) { goto ReturnFalse; } RtlZeroMemory(processor_data->vmm_stack_limit, KERNEL_STACK_SIZE); processor_data->vmcs_region = reinterpret_cast<VmControlStructure *>(ExAllocatePoolWithTag( NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag)); if (!processor_data->vmcs_region) { goto ReturnFalse; } RtlZeroMemory(processor_data->vmcs_region, kVmxMaxVmcsSize); processor_data->vmxon_region = reinterpret_cast<VmControlStructure *>(ExAllocatePoolWithTag( NonPagedPool, kVmxMaxVmcsSize, kHyperPlatformCommonPoolTag)); if (!processor_data->vmxon_region) { goto ReturnFalse; } RtlZeroMemory(processor_data->vmxon_region, kVmxMaxVmcsSize); // Initialize stack memory for VMM like this: // // (High) // +------------------+ <- vmm_stack_region_base (eg, AED37000) // | processor_data | // +------------------+ <- vmm_stack_data (eg, AED36FFC) // | MAXULONG_PTR | // +------------------+ <- vmm_stack_base (initial SP)(eg, AED36FF8) // | | v // | (VMM Stack) | v (grow) // | | v // +------------------+ <- vmm_stack_limit (eg, AED34000) // (Low) const auto vmm_stack_region_base = reinterpret_cast<ULONG_PTR>(processor_data->vmm_stack_limit) + KERNEL_STACK_SIZE; const auto vmm_stack_data = vmm_stack_region_base - sizeof(void *); const auto vmm_stack_base = vmm_stack_data - sizeof(void *); HYPERPLATFORM_LOG_DEBUG("vmm_stack_limit = %p", processor_data->vmm_stack_limit); HYPERPLATFORM_LOG_DEBUG("vmm_stack_region_base = %p", vmm_stack_region_base); HYPERPLATFORM_LOG_DEBUG("vmm_stack_data = %p", vmm_stack_data); HYPERPLATFORM_LOG_DEBUG("vmm_stack_base = %p", vmm_stack_base); HYPERPLATFORM_LOG_DEBUG("processor_data = %p stored at %p", processor_data, vmm_stack_data); HYPERPLATFORM_LOG_DEBUG("guest_stack_pointer = %p", guest_stack_pointer); HYPERPLATFORM_LOG_DEBUG("guest_inst_pointer = %p", guest_instruction_pointer); *reinterpret_cast<ULONG_PTR *>(vmm_stack_base) = MAXULONG_PTR; *reinterpret_cast<ProcessorData **>(vmm_stack_data) = processor_data; // Set up VMCS if (!VmpEnterVmxMode(processor_data)) { goto ReturnFalse; } if (!VmpInitializeVmcs(processor_data)) { goto ReturnFalseWithVmxOff; } if (!VmpSetupVmcs(processor_data, guest_stack_pointer, guest_instruction_pointer, vmm_stack_base)) { goto ReturnFalseWithVmxOff; } // Do virtualize the processor VmpLaunchVm(); // Here is not be executed with successful vmlaunch. Instead, the context // jumps to an address specified by guest_instruction_pointer. ReturnFalseWithVmxOff:; __vmx_off(); ReturnFalse:; VmpFreeProcessorData(processor_data); }
/* 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; }
////////////////////////////////////////////////////////////////////////// //如果提供的缓存区不够大,返回STATUS_BUFFER_TOO_SMALL NTSTATUS GetAdapterInfo(ADAPTER_INFOEX *pAIEX, PULONG Size2Take) { NTSTATUS status; HANDLE hAdapter = NULL; PKEY_FULL_INFORMATION pKeyFullInfo = NULL; ULONG uTmp; ULONG uCounter=0; do { // UNICODE_STRING ustrAdapter = UNICODE_STRING_CONST(L";\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";); UNICODE_STRING ustrAdapter = UNICODE_STRING_CONST(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters"); OBJECT_ATTRIBUTES ObjAttrib; ULONG nSize; ULONG nIndex; InitializeObjectAttributes(&ObjAttrib, &ustrAdapter, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenKey(&hAdapter, KEY_READ, &ObjAttrib); if (!NT_SUCCESS(status)) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,"ZwOpenKey Error: %x\n", status); break; } ZwQueryKey(hAdapter, KeyFullInformation, NULL, 0, &nSize); pKeyFullInfo = (PKEY_FULL_INFORMATION)kmalloc( nSize); if (!pKeyFullInfo) { status = STATUS_INSUFFICIENT_RESOURCES; break; } status = ZwQueryKey(hAdapter, KeyFullInformation, pKeyFullInfo, nSize, &nSize); if (!NT_SUCCESS(status)) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwQueryKey Error: %x\n", status); break; } if (pAIEX==NULL) { status = STATUS_BUFFER_TOO_SMALL; *Size2Take = pKeyFullInfo->SubKeys*sizeof(ADAPTER_INFO)+sizeof(ULONG); break; } for (nIndex = 0; nIndex< pKeyFullInfo->SubKeys; nIndex ++) { PKEY_BASIC_INFORMATION pKeyBasicInfo = NULL; HANDLE hDev = NULL; pKeyBasicInfo = NULL; do { UNICODE_STRING strKeyName; UNICODE_STRING ustrDev ;// UNICODE_STRING_CONST(DEV_DOS_ROOT L"{F6ACFAC2-D39E-4A43-A320-0CDB9E22B15B}"); IO_STATUS_BLOCK IoStatusBlock; ULONG nOid; ZwEnumerateKey(hAdapter, nIndex, KeyBasicInformation, NULL, 0, &nSize); pKeyBasicInfo = (PKEY_BASIC_INFORMATION) kmalloc(nSize); if (NULL == pKeyBasicInfo) { status = STATUS_INSUFFICIENT_RESOURCES; break; } status = ZwEnumerateKey(hAdapter, nIndex, KeyBasicInformation, pKeyBasicInfo, nSize, &nSize); if (!NT_SUCCESS(status)) { kprintf("ZwEnumerateKey fail \n"); break; } strKeyName.Buffer = pKeyBasicInfo->Name; strKeyName.MaximumLength = (USHORT)pKeyBasicInfo->NameLength; strKeyName.Length = (USHORT)pKeyBasicInfo->NameLength; ustrDev.Buffer = kmalloc(strKeyName.MaximumLength+sizeof(DEV_DOS_ROOT)); ustrDev.MaximumLength = strKeyName.MaximumLength+sizeof(DEV_DOS_ROOT); ustrDev.Length = 0; if (NULL == ustrDev.Buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlAppendUnicodeToString(&ustrDev, DEV_DOS_ROOT); status = RtlAppendUnicodeStringToString(&ustrDev, &strKeyName); if (STATUS_SUCCESS != status) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";RtlAppendUnicodeStringToString Error: %x\n", status); kfree(ustrDev.Buffer); break; } InitializeObjectAttributes(&ObjAttrib, &ustrDev, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenFile(&hDev, GENERIC_READ, &ObjAttrib, &IoStatusBlock, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE); if (STATUS_SUCCESS != status) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwOpenFile %wZ,Error: %x\n", &ustrDev, status); kfree(ustrDev.Buffer); break; } // nOid = OID_GEN_MEDIA_IN_USE; // nOid = OID_GEN_PHYSICAL_MEDIUM; //网卡类型 // uTmp = sizeof(uTmp); // status = ZwDeviceIoControlFile(hDev, // NULL, // NULL, // NULL, // &IoStatusBlock, // IOCTL_NDIS_QUERY_GLOBAL_STATS, // &nOid, // sizeof(nOid), // &uTmp, // uTmp); // if (STATUS_SUCCESS != status) // { // DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_GEN_PHYSICAL_MEDIUM Error: 0X%x\n", status); // uTmp = -1; // if (status==STATUS_INVALID_PARAMETER) // { // // NdisPhysicalMediumUnspecified // } // // break; // } //其实这里应该先发OID_GEN_MEDIA_IN_USE获取下media类型 nOid = OID_GEN_MEDIA_CONNECT_STATUS; //网卡类型 uTmp = sizeof(uTmp); status = ZwDeviceIoControlFile(hDev, NULL, NULL, NULL, &IoStatusBlock, IOCTL_NDIS_QUERY_GLOBAL_STATS, &nOid, sizeof(nOid), &uTmp, uTmp); if (STATUS_SUCCESS != status) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_GEN_MEDIA_CONNECT_STATUS Error: 0X%x\n", status); uTmp = NdisMediaStateDisconnected; // break; } pAIEX->pAI[uCounter].status = uTmp; kprintf(" %wZ, OID_GEN_MEDIA_CONNECT_STATUS %s \n", &ustrDev, uTmp == NdisMediaStateConnected ? "Connected" : "Disconnected"); kfree(ustrDev.Buffer); uTmp = sizeof(pAIEX->pAI[uCounter].macAddress); nOid = OID_802_3_CURRENT_ADDRESS; status = ZwDeviceIoControlFile(hDev, NULL, NULL, NULL, &IoStatusBlock, IOCTL_NDIS_QUERY_GLOBAL_STATS, &nOid, sizeof(nOid), pAIEX->pAI[uCounter].macAddress, uTmp); if (STATUS_SUCCESS != status) { //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,";ZwDeviceIoControlFile OID_802_3_PERMANENT_ADDRESS Error: 0x%x\n", status); break; } //DbgPrintEx(DPFLTR_IHVBUS_ID ,DPFLTR_ERROR_LEVEL,"Mac: %02X:%02X:%02X:%02X:%02X:%02X\n", pAIEX->pAI[uCounter].macAddress[0], pAIEX->pAI[uCounter].macAddress[1], pAIEX->pAI[uCounter].macAddress[2], pAIEX->pAI[uCounter].macAddress[3], pAIEX->pAI[uCounter].macAddress[4], pAIEX->pAI[uCounter].macAddress[5]); pAIEX->pAI[uCounter].GUID.Buffer = kmalloc(pKeyBasicInfo->NameLength); pAIEX->pAI[uCounter].GUID.Length = pAIEX->pAI[uCounter].GUID.MaximumLength = (USHORT)pKeyBasicInfo->NameLength; RtlCopyMemory(pAIEX->pAI[uCounter].GUID.Buffer, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength); if (1) { CHAR IPAddress[48]; ANSI_STRING aniString; UNICODE_STRING uniString; char *pTmp=NULL; UNICODE_STRING ustrAdapterInfo = UNICODE_STRING_CONST(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"); WCHAR *pPath =kmalloc(ustrAdapterInfo.Length+pKeyBasicInfo->NameLength+2); RtlZeroMemory(pPath, ustrAdapterInfo.Length+pKeyBasicInfo->NameLength+2); RtlCopyMemory(pPath, ustrAdapterInfo.Buffer, ustrAdapterInfo.Length); pTmp = (char*)pPath; RtlCopyMemory(&pTmp[ustrAdapterInfo.Length], pKeyBasicInfo->Name, pKeyBasicInfo->NameLength); uTmp=0; uTmp = sizeof(ULONG); status = KKGetKeyValue(pPath, L"EnableDHCP", &uTmp, &uTmp); if (NT_SUCCESS(status)) { RtlZeroMemory(IPAddress, sizeof(IPAddress)); //开启了DHCP情况 if (uTmp==1) { pAIEX->pAI[uCounter].bDhcp = TRUE; //够长了,应该会自动截断 RtlZeroMemory(IPAddress, sizeof(IPAddress)); uTmp = sizeof(IPAddress); status = KKGetKeyValue(pPath, L"DhcpIPAddress", IPAddress, &uTmp); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress); RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE); RtlZeroMemory(IPAddress, sizeof(IPAddress)); RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length); pAIEX->pAI[uCounter].IPAddr = inet_addr(IPAddress); RtlFreeAnsiString(&aniString); } else { kprintf("fail 2 get DhcpIPAddress\n"); } RtlZeroMemory(IPAddress, sizeof(IPAddress)); uTmp = sizeof(IPAddress); status = KKGetKeyValue(pPath, L"DhcpDefaultGateway", IPAddress, &uTmp); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress); RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE); RtlZeroMemory(IPAddress, sizeof(IPAddress)); RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length); pAIEX->pAI[uCounter].GatewayIpAddr = inet_addr(IPAddress); RtlFreeAnsiString(&aniString); } else { kprintf("fail 2 get DhcpDefaultGateway\n"); } }//if (uTmp==1) else { pAIEX->pAI[uCounter].bDhcp = FALSE; //够长了,应该会自动截断 RtlZeroMemory(IPAddress, sizeof(IPAddress)); uTmp = sizeof(IPAddress); status = KKGetKeyValue(pPath, L"IPAddress", IPAddress, &uTmp); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress); RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE); RtlZeroMemory(IPAddress, sizeof(IPAddress)); RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length); pAIEX->pAI[uCounter].IPAddr = inet_addr(IPAddress); RtlFreeAnsiString(&aniString); } else { kprintf("fail 2 get IPAddress\n"); } RtlZeroMemory(IPAddress, sizeof(IPAddress)); uTmp = sizeof(IPAddress); status = KKGetKeyValue(pPath, L"DefaultGateway", IPAddress, &uTmp); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&uniString, (WCHAR*)IPAddress); RtlUnicodeStringToAnsiString(&aniString, &uniString, TRUE); RtlZeroMemory(IPAddress, sizeof(IPAddress)); RtlCopyMemory(IPAddress, aniString.Buffer, aniString.Length); pAIEX->pAI[uCounter].GatewayIpAddr = inet_addr(IPAddress); RtlFreeAnsiString(&aniString); } else { kprintf("fail 2 get DefaultGateway\n"); } } }// end status = QueryRegistryValue(pPath, L"EnableDHCP if (pPath) { kfree(pPath);pPath=NULL; } } uCounter++; pAIEX->uNumber = uCounter; }while(0); if (hDev) { ZwClose(hDev); } if (pKeyBasicInfo) { kfree(pKeyBasicInfo); } if (STATUS_SUCCESS == status) { // break; } } }while(0); if (pKeyFullInfo) { kfree(pKeyFullInfo); } if (hAdapter) { ZwClose(hAdapter); } return status; }
GUID * AFSValidateProcessEntry( IN HANDLE ProcessId, IN BOOLEAN bProcessTreeLocked) { GUID *pAuthGroup = NULL; NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)ProcessId; UNICODE_STRING uniSIDString; ULONG ulSIDHash = 0; AFSSIDEntryCB *pSIDEntryCB = NULL; ULONG ulSessionId = 0; ULONGLONG ullTableHash = 0; AFSThreadCB *pParentThreadCB = NULL; UNICODE_STRING uniGUID; BOOLEAN bImpersonation = FALSE; __Enter { uniSIDString.Length = 0; uniSIDString.MaximumLength = 0; uniSIDString.Buffer = NULL; if ( !bProcessTreeLocked) { AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n", pDeviceExt->Specific.Control.ProcessTree.TreeLock, PsGetCurrentThread())); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); } AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { if ( !bProcessTreeLocked) { AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); } ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSProcessCreate( 0, ProcessId, 0, 0); } if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus = STATUS_UNSUCCESSFUL); } if ( !bProcessTreeLocked) { AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock); } } // // Locate and lock the ParentProcessCB if we have one // if( pProcessCB->ParentProcessId != 0) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Locating process entry for Parent ProcessID %I64X\n", __FUNCTION__, pProcessCB->ParentProcessId)); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)pProcessCB->ParentProcessId, (AFSBTreeEntry **)&pParentProcessCB); if( NT_SUCCESS( ntStatus) && pParentProcessCB != NULL) { AFSAcquireExcl( &pParentProcessCB->Lock, TRUE); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located process entry for Parent ProcessID %I64X\n", __FUNCTION__, pProcessCB->ParentProcessId)); } } else { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No parent ID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); } AFSAcquireExcl( &pProcessCB->Lock, TRUE); #if defined(_WIN64) // // Mark the process as 64-bit if it is. // if( !IoIs32bitProcess( NULL)) { SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); } else { ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); } #endif // // Locate the SID for the caller // ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate callers SID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus); } ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve session ID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId)); // // If there is an Auth Group for the current process, // our job is finished. // if ( bImpersonation == FALSE) { pAuthGroup = pProcessCB->ActiveAuthGroup; if( pAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pAuthGroup)) { uniGUID.Buffer = NULL; RtlStringFromGUID( *pAuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_return( ntStatus = STATUS_SUCCESS); } // // The current process does not yet have an Auth Group. Try to inherit // one from the parent process thread that created this process. // if( pParentProcessCB != NULL) { for ( pParentThreadCB = pParentProcessCB->ThreadList; pParentThreadCB != NULL; pParentThreadCB = pParentThreadCB->Next) { if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId) { break; } } // // If the creating thread was found and it has a thread specific // Auth Group, use that even if it is the No PAG // if( pParentThreadCB != NULL && pParentThreadCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup)) { pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n", __FUNCTION__, ullProcessID, ulSessionId, &uniGUID, pParentThreadCB->ThreadId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } } // // If the parent thread was not found or does not have an auth group // else if( pParentProcessCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) { pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n", __FUNCTION__, ullProcessID, ulSessionId, &uniGUID, pParentProcessCB->TreeEntry.HashIndex)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } } // // If an Auth Group was inherited, set it to be the active group // if( pProcessCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) { pAuthGroup = pProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_return( ntStatus); } } } // // If no Auth Group was inherited, assign one based upon the Session and SID // ntStatus = RtlHashUnicodeString( &uniSIDString, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &ulSIDHash); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, ntStatus)); try_return( ntStatus); } ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( !NT_SUCCESS( ntStatus) || pSIDEntryCB == NULL) { AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( !NT_SUCCESS( ntStatus) || pSIDEntryCB == NULL) { pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSSIDEntryCB), AFS_AG_ENTRY_CB_TAG); if( pSIDEntryCB == NULL) { AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pSIDEntryCB, sizeof( AFSSIDEntryCB)); pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash; while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, &uniGUID)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL) { pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB; } else { AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, &pSIDEntryCB->TreeEntry); } } AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); } AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); // // Store the auth group into the process cb // pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, &uniGUID)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } // // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID // is LOCAL_SYSTEM // if( AFSIsLocalSystemSID( &uniSIDString)) { SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n", __FUNCTION__, ullProcessID, ulSessionId)); } // // Return the auth group // pAuthGroup = pProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_exit: if( pProcessCB != NULL) { if( bImpersonation == FALSE && !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) && NT_SUCCESS( ntStatus)) { ntStatus = AFSProcessSetProcessDacl( pProcessCB); if( !NT_SUCCESS( ntStatus)) { pAuthGroup = NULL; } else { SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET); } } AFSReleaseResource( &pProcessCB->Lock); } if( pParentProcessCB != NULL) { AFSReleaseResource( &pParentProcessCB->Lock); } if( uniSIDString.Length > 0) { RtlFreeUnicodeString( &uniSIDString); } if ( !bProcessTreeLocked) { AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); } } return pAuthGroup; }
NTSTATUS XixFsNdasQueryLock( PDEVICE_OBJECT DeviceObject ) { NTSTATUS RC; PSRB_IO_CONTROL pSrbIoCtl = NULL; uint32 OutbuffSize = 0; PNDSCIOCTL_DEVICELOCK QueryLock = NULL; PDEVICE_OBJECT scsiAdpaterDeviceObject = NULL; BOOLEAN result = FALSE; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Enter XixFsNdasQueryLock \n")); result = XixFsGetScsiportAdapter(DeviceObject, &scsiAdpaterDeviceObject); if(result != TRUE){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixFsGetScsiportAdpater!!! \n")); return STATUS_UNSUCCESSFUL; } OutbuffSize = sizeof(SRB_IO_CONTROL) + sizeof(NDSCIOCTL_DEVICELOCK); OutbuffSize = SECTORALIGNSIZE_512(OutbuffSize); pSrbIoCtl = (PSRB_IO_CONTROL)ExAllocatePoolWithTag(NonPagedPool, OutbuffSize, TAG_BUFFER); if(!pSrbIoCtl){ ObDereferenceObject(scsiAdpaterDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } try{ RtlZeroMemory(pSrbIoCtl, OutbuffSize); pSrbIoCtl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(pSrbIoCtl->Signature, NDASSCSI_IOCTL_SIGNATURE, 8); pSrbIoCtl->Timeout = 10; pSrbIoCtl->ControlCode = NDASSCSI_IOCTL_DEVICE_LOCK; pSrbIoCtl->Length = sizeof(NDSCIOCTL_DEVICELOCK); QueryLock = (PNDSCIOCTL_DEVICELOCK)((PUCHAR)pSrbIoCtl + sizeof(SRB_IO_CONTROL)); QueryLock->LockId = NDSCLOCK_ID_XIFS; QueryLock->LockOpCode = NDSCLOCK_OPCODE_QUERY_OWNER; QueryLock->AdvancedLock = FALSE; QueryLock->AddressRangeValid = FALSE; QueryLock->RequireLockAcquisition = FALSE; QueryLock->StartingAddress = 0; QueryLock->EndingAddress = 0; QueryLock->ContentionTimeOut = 0; //Fist step Send Disk RC = XixFsRawDevIoCtrl ( DeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(NT_SUCCESS(RC)){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Status of Lock (0x%x) Info(0x%02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x)\n", RC, QueryLock->LockData[0], QueryLock->LockData[1], QueryLock->LockData[2], QueryLock->LockData[3], QueryLock->LockData[4], QueryLock->LockData[5], QueryLock->LockData[6], QueryLock->LockData[7] )); }else{ // Send port RC = XixFsRawDevIoCtrl ( scsiAdpaterDeviceObject, IOCTL_SCSI_MINIPORT, (uint8 *)pSrbIoCtl, OutbuffSize, (uint8 *)pSrbIoCtl, OutbuffSize, FALSE, NULL ); if(!NT_SUCCESS(RC)){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("Fail XixFsRawDevIoCtrl Status (0x%x)\n", RC)); }else{ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Status of Lock (0x%x) Info(0x%02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x)\n", RC, QueryLock->LockData[0], QueryLock->LockData[1], QueryLock->LockData[2], QueryLock->LockData[3], QueryLock->LockData[4], QueryLock->LockData[5], QueryLock->LockData[6], QueryLock->LockData[7] )); } } }finally{ ObDereferenceObject(scsiAdpaterDeviceObject); ExFreePool(pSrbIoCtl); } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_RESOURCE| DEBUG_TARGET_FCB|DEBUG_TARGET_LOCK), ("Exit XixFsNdasUnLock Status (0x%x)\n", RC)); return RC; }
NTSTATUS FatQueryDirectory ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This routine performs the query directory operation. It is responsible for either completing of enqueuing the input Irp. Arguments: Irp - Supplies the Irp to process Return Value: NTSTATUS - The return status for the operation --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PVCB Vcb; PDCB Dcb; PCCB Ccb; PBCB Bcb; ULONG i; PUCHAR Buffer; CLONG UserBufferLength; PUNICODE_STRING UniArgFileName; WCHAR LongFileNameBuffer[ FAT_CREATE_INITIAL_NAME_BUF_SIZE]; UNICODE_STRING LongFileName; FILE_INFORMATION_CLASS FileInformationClass; ULONG FileIndex; BOOLEAN RestartScan; BOOLEAN ReturnSingleEntry; BOOLEAN IndexSpecified; BOOLEAN InitialQuery; VBO CurrentVbo; BOOLEAN UpdateCcb; PDIRENT Dirent; UCHAR Fat8Dot3Buffer[12]; OEM_STRING Fat8Dot3String; ULONG DiskAllocSize; ULONG NextEntry; ULONG LastEntry; PFILE_DIRECTORY_INFORMATION DirInfo; PFILE_FULL_DIR_INFORMATION FullDirInfo; PFILE_BOTH_DIR_INFORMATION BothDirInfo; PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo; PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo; PFILE_NAMES_INFORMATION NamesInfo; PAGED_CODE(); // // Get the current Stack location // IrpSp = IoGetCurrentIrpStackLocation( Irp ); // // Display the input values. // DebugTrace(+1, Dbg, "FatQueryDirectory...\n", 0); DebugTrace( 0, Dbg, " Wait = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)); DebugTrace( 0, Dbg, " Irp = %08lx\n", Irp); DebugTrace( 0, Dbg, " ->Length = %08lx\n", IrpSp->Parameters.QueryDirectory.Length); DebugTrace( 0, Dbg, " ->FileName = %08lx\n", IrpSp->Parameters.QueryDirectory.FileName); DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", IrpSp->Parameters.QueryDirectory.FileInformationClass); DebugTrace( 0, Dbg, " ->FileIndex = %08lx\n", IrpSp->Parameters.QueryDirectory.FileIndex); DebugTrace( 0, Dbg, " ->UserBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer); DebugTrace( 0, Dbg, " ->RestartScan = %08lx\n", FlagOn( IrpSp->Flags, SL_RESTART_SCAN )); DebugTrace( 0, Dbg, " ->ReturnSingleEntry = %08lx\n", FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY )); DebugTrace( 0, Dbg, " ->IndexSpecified = %08lx\n", FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED )); // // Reference our input parameters to make things easier // UserBufferLength = IrpSp->Parameters.QueryDirectory.Length; FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass; FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex; UniArgFileName = IrpSp->Parameters.QueryDirectory.FileName; RestartScan = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN); ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY); IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED); // // Check on the type of open. We return invalid parameter for all // but UserDirectoryOpens. Also check that the filename is a valid // UNICODE string. // if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Dcb, &Ccb) != UserDirectoryOpen || (UniArgFileName && UniArgFileName->Length % sizeof(WCHAR))) { FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); DebugTrace(-1, Dbg, "FatQueryDirectory -> STATUS_INVALID_PARAMETER\n", 0); return STATUS_INVALID_PARAMETER; } // // Initialize the local variables. // Bcb = NULL; UpdateCcb = TRUE; Dirent = NULL; Fat8Dot3String.MaximumLength = 12; Fat8Dot3String.Buffer = Fat8Dot3Buffer; LongFileName.Length = 0; LongFileName.MaximumLength = sizeof( LongFileNameBuffer); LongFileName.Buffer = LongFileNameBuffer; InitialQuery = (BOOLEAN)((Ccb->UnicodeQueryTemplate.Buffer == NULL) && !FlagOn(Ccb->Flags, CCB_FLAG_MATCH_ALL)); Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; DiskAllocSize = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster; // // If this is the initial query, then grab exclusive access in // order to update the search string in the Ccb. We may // discover that we are not the initial query once we grab the Fcb // and downgrade our status. // if (InitialQuery) { if (!FatAcquireExclusiveFcb( IrpContext, Dcb )) { DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0); Status = FatFsdPostRequest( IrpContext, Irp ); DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status); return Status; } if (Ccb->UnicodeQueryTemplate.Buffer != NULL) { InitialQuery = FALSE; FatConvertToSharedFcb( IrpContext, Dcb ); } } else { if (!FatAcquireSharedFcb( IrpContext, Dcb )) { DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0); Status = FatFsdPostRequest( IrpContext, Irp ); DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status); return Status; } } try { ULONG BaseLength; ULONG BytesConverted; // // If we are in the Fsp now because we had to wait earlier, // we must map the user buffer, otherwise we can use the // user's buffer directly. // Buffer = FatMapUserBuffer( IrpContext, Irp ); // // Make sure the Dcb is still good. // FatVerifyFcb( IrpContext, Dcb ); // // Determine where to start the scan. Highest priority is given // to the file index. Lower priority is the restart flag. If // neither of these is specified, then the Vbo offset field in the // Ccb is used. // if (IndexSpecified) { CurrentVbo = FileIndex + sizeof( DIRENT ); } else if (RestartScan) { CurrentVbo = 0; } else { CurrentVbo = Ccb->OffsetToStartSearchFrom; } // // If this is the first try then allocate a buffer for the file // name. // if (InitialQuery) { // // If either: // // - No name was specified // - An empty name was specified // - We received a '*' // - The user specified the DOS equivolent of ????????.??? // // then match all names. // if ((UniArgFileName == NULL) || (UniArgFileName->Length == 0) || (UniArgFileName->Buffer == NULL) || ((UniArgFileName->Length == sizeof(WCHAR)) && (UniArgFileName->Buffer[0] == L'*')) || ((UniArgFileName->Length == 12*sizeof(WCHAR)) && (RtlEqualMemory( UniArgFileName->Buffer, Fat8QMdot3QM, 12*sizeof(WCHAR) )))) { Ccb->ContainsWildCards = TRUE; SetFlag( Ccb->Flags, CCB_FLAG_MATCH_ALL ); } else { BOOLEAN ExtendedName = FALSE; OEM_STRING LocalBestFit; // // First and formost, see if the name has wild cards. // Ccb->ContainsWildCards = FsRtlDoesNameContainWildCards( UniArgFileName ); // // Now check to see if the name contains any extended // characters // for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) { if (UniArgFileName->Buffer[i] >= 0x80) { ExtendedName = TRUE; break; } } // // OK, now do the conversions we need. // if (ExtendedName) { Status = RtlUpcaseUnicodeString( &Ccb->UnicodeQueryTemplate, UniArgFileName, TRUE ); if (!NT_SUCCESS(Status)) { try_return( Status ); } SetFlag( Ccb->Flags, CCB_FLAG_FREE_UNICODE ); // // Upcase the name and convert it to the Oem code page. // Status = RtlUpcaseUnicodeStringToCountedOemString( &LocalBestFit, UniArgFileName, TRUE ); // // If this conversion failed for any reason other than // an unmappable character fail the request. // if (!NT_SUCCESS(Status)) { if (Status == STATUS_UNMAPPABLE_CHARACTER) { SetFlag( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE ); } else { try_return( Status ); } } else { SetFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT ); } } else { PVOID Buffers; // // This case is optimized because I know I only have to // worry about a-z. // Buffers = FsRtlAllocatePoolWithTag( PagedPool, UniArgFileName->Length + UniArgFileName->Length / sizeof(WCHAR), TAG_FILENAME_BUFFER ); Ccb->UnicodeQueryTemplate.Buffer = Buffers; Ccb->UnicodeQueryTemplate.Length = UniArgFileName->Length; Ccb->UnicodeQueryTemplate.MaximumLength = UniArgFileName->Length; LocalBestFit.Buffer = (PUCHAR)Buffers + UniArgFileName->Length; LocalBestFit.Length = UniArgFileName->Length / sizeof(WCHAR); LocalBestFit.MaximumLength = LocalBestFit.Length; SetFlag( Ccb->Flags, CCB_FLAG_FREE_UNICODE ); for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) { WCHAR c = UniArgFileName->Buffer[i]; LocalBestFit.Buffer[i] = (UCHAR) (Ccb->UnicodeQueryTemplate.Buffer[i] = (c < 'a' ? c : c <= 'z' ? c - ('a' - 'A') : c)); } } // // At this point we now have the upcased unicode name, // and the two Oem names if they could be represented in // this code page. // // Now determine if the Oem names are legal for what we // going to try and do. Mark them as not usable is they // are not legal. Note that we can optimize extended names // since they are actually both the same string. // if (!FlagOn( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE ) && !FatIsNameShortOemValid( IrpContext, LocalBestFit, Ccb->ContainsWildCards, FALSE, FALSE )) { if (ExtendedName) { RtlFreeOemString( &LocalBestFit ); ClearFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT ); } SetFlag( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE ); } // // OK, now both locals oem strings correctly reflect their // usability. Now we want to load up the Ccb structure. // // Now we will branch on two paths of wheather the name // is wild or not. // if (!FlagOn( Ccb->Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE )) { if (Ccb->ContainsWildCards) { Ccb->OemQueryTemplate.Wild = LocalBestFit; } else { FatStringTo8dot3( IrpContext, LocalBestFit, &Ccb->OemQueryTemplate.Constant ); if (FlagOn(Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT)) { RtlFreeOemString( &LocalBestFit ); ClearFlag( Ccb->Flags, CCB_FLAG_FREE_OEM_BEST_FIT ); } } } } // // We convert to shared access. // FatConvertToSharedFcb( IrpContext, Dcb ); } LastEntry = 0; NextEntry = 0; switch (FileInformationClass) { case FileDirectoryInformation: BaseLength = FIELD_OFFSET( FILE_DIRECTORY_INFORMATION, FileName[0] ); break; case FileFullDirectoryInformation: BaseLength = FIELD_OFFSET( FILE_FULL_DIR_INFORMATION, FileName[0] ); break; case FileIdFullDirectoryInformation: BaseLength = FIELD_OFFSET( FILE_ID_FULL_DIR_INFORMATION, FileName[0] ); break; case FileNamesInformation: BaseLength = FIELD_OFFSET( FILE_NAMES_INFORMATION, FileName[0] ); break; case FileBothDirectoryInformation: BaseLength = FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, FileName[0] ); break; case FileIdBothDirectoryInformation: BaseLength = FIELD_OFFSET( FILE_ID_BOTH_DIR_INFORMATION, FileName[0] ); break; default: try_return( Status = STATUS_INVALID_INFO_CLASS ); } // // At this point we are about to enter our query loop. We have // determined the index into the directory file to begin the // search. LastEntry and NextEntry are used to index into the user // buffer. LastEntry is the last entry we've added, NextEntry is // current one we're working on. If NextEntry is non-zero, then // at least one entry was added. // while ( TRUE ) { VBO NextVbo; ULONG FileNameLength; ULONG BytesRemainingInBuffer; DebugTrace(0, Dbg, "FatQueryDirectory -> Top of loop\n", 0); // // If the user had requested only a single match and we have // returned that, then we stop at this point. // if (ReturnSingleEntry && NextEntry != 0) { try_return( Status ); } // // We call FatLocateDirent to lock down the next matching dirent. // FatLocateDirent( IrpContext, Dcb, Ccb, CurrentVbo, &Dirent, &Bcb, &NextVbo, NULL, &LongFileName); // // If we didn't receive a dirent, then we are at the end of the // directory. If we have returned any files, we exit with // success, otherwise we return STATUS_NO_MORE_FILES. // if (!Dirent) { DebugTrace(0, Dbg, "FatQueryDirectory -> No dirent\n", 0); if (NextEntry == 0) { UpdateCcb = FALSE; if (InitialQuery) { Status = STATUS_NO_SUCH_FILE; } else { Status = STATUS_NO_MORE_FILES; } } try_return( Status ); } // // Protect access to the user buffer with an exception handler. // Since (at our request) IO doesn't buffer these requests, we have // to guard against a user messing with the page protection and other // such trickery. // try { if (LongFileName.Length == 0) { // // Now we have an entry to return to our caller. We'll convert // the name from the form in the dirent to a <name>.<ext> form. // We'll case on the type of information requested and fill up // the user buffer if everything fits. // Fat8dot3ToString( IrpContext, Dirent, TRUE, &Fat8Dot3String ); // // Determine the UNICODE length of the file name. // FileNameLength = RtlOemStringToCountedUnicodeSize(&Fat8Dot3String); // // Here are the rules concerning filling up the buffer: // // 1. The Io system garentees that there will always be // enough room for at least one base record. // // 2. If the full first record (including file name) cannot // fit, as much of the name as possible is copied and // STATUS_BUFFER_OVERFLOW is returned. // // 3. If a subsequent record cannot completely fit into the // buffer, none of it (as in 0 bytes) is copied, and // STATUS_SUCCESS is returned. A subsequent query will // pick up with this record. // BytesRemainingInBuffer = UserBufferLength - NextEntry; if ( (NextEntry != 0) && ( (BaseLength + FileNameLength > BytesRemainingInBuffer) || (UserBufferLength < NextEntry) ) ) { DebugTrace(0, Dbg, "Next entry won't fit\n", 0); try_return( Status = STATUS_SUCCESS ); } ASSERT( BytesRemainingInBuffer >= BaseLength ); // // Zero the base part of the structure. // RtlZeroMemory( &Buffer[NextEntry], BaseLength ); switch ( FileInformationClass ) { // // Now fill the base parts of the strucure that are applicable. // case FileBothDirectoryInformation: case FileFullDirectoryInformation: case FileIdBothDirectoryInformation: case FileIdFullDirectoryInformation: DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0); // // Get the Ea file length. // FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry]; // // If the EAs are corrupt, ignore the error. We don't want // to abort the directory query. // try { FatGetEaLength( IrpContext, Vcb, Dirent, &FullDirInfo->EaSize ); } except(EXCEPTION_EXECUTE_HANDLER) { FatResetExceptionState( IrpContext ); FullDirInfo->EaSize = 0; } case FileDirectoryInformation: DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry]; FatGetDirTimes( IrpContext, Dirent, DirInfo ); DirInfo->EndOfFile.QuadPart = Dirent->FileSize; if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) { DirInfo->AllocationSize.QuadPart = (((Dirent->FileSize + DiskAllocSize - 1) / DiskAllocSize) * DiskAllocSize ); } DirInfo->FileAttributes = Dirent->Attributes != 0 ? Dirent->Attributes : FILE_ATTRIBUTE_NORMAL; DirInfo->FileIndex = NextVbo; DirInfo->FileNameLength = FileNameLength; DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String); break; case FileNamesInformation: DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0); NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry]; NamesInfo->FileIndex = NextVbo; NamesInfo->FileNameLength = FileNameLength; DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String ); break; default: FatBugCheck( FileInformationClass, 0, 0 ); } BytesConverted = 0; Status = RtlOemToUnicodeN( (PWCH)&Buffer[NextEntry + BaseLength], BytesRemainingInBuffer - BaseLength, &BytesConverted, Fat8Dot3String.Buffer, Fat8Dot3String.Length ); // // Check for the case that a single entry doesn't fit. // This should only get this far on the first entry // if (BytesConverted < FileNameLength) { ASSERT( NextEntry == 0 ); Status = STATUS_BUFFER_OVERFLOW; } // // Set up the previous next entry offset // *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry; // // And indicate how much of the user buffer we have currently // used up. We must compute this value before we long align // ourselves for the next entry // Irp->IoStatus.Information = QuadAlign( Irp->IoStatus.Information ) + BaseLength + BytesConverted; // // If something happened with the conversion, bail here. // if ( !NT_SUCCESS( Status ) ) { try_return( NOTHING ); } } else { ULONG ShortNameLength; FileNameLength = LongFileName.Length; // // Here are the rules concerning filling up the buffer: // // 1. The Io system garentees that there will always be // enough room for at least one base record. // // 2. If the full first record (including file name) cannot // fit, as much of the name as possible is copied and // STATUS_BUFFER_OVERFLOW is returned. // // 3. If a subsequent record cannot completely fit into the // buffer, none of it (as in 0 bytes) is copied, and // STATUS_SUCCESS is returned. A subsequent query will // pick up with this record. // BytesRemainingInBuffer = UserBufferLength - NextEntry; if ( (NextEntry != 0) && ( (BaseLength + FileNameLength > BytesRemainingInBuffer) || (UserBufferLength < NextEntry) ) ) { DebugTrace(0, Dbg, "Next entry won't fit\n", 0); try_return( Status = STATUS_SUCCESS ); } ASSERT( BytesRemainingInBuffer >= BaseLength ); // // Zero the base part of the structure. // RtlZeroMemory( &Buffer[NextEntry], BaseLength ); switch ( FileInformationClass ) { // // Now fill the base parts of the strucure that are applicable. // case FileBothDirectoryInformation: case FileIdBothDirectoryInformation: BothDirInfo = (PFILE_BOTH_DIR_INFORMATION)&Buffer[NextEntry]; // // Now we have an entry to return to our caller. We'll convert // the name from the form in the dirent to a <name>.<ext> form. // We'll case on the type of information requested and fill up // the user buffer if everything fits. // Fat8dot3ToString( IrpContext, Dirent, FALSE, &Fat8Dot3String ); ASSERT( Fat8Dot3String.Length <= 12 ); Status = RtlOemToUnicodeN( &BothDirInfo->ShortName[0], 12*sizeof(WCHAR), &ShortNameLength, Fat8Dot3String.Buffer, Fat8Dot3String.Length ); ASSERT( Status != STATUS_BUFFER_OVERFLOW ); ASSERT( ShortNameLength <= 12*sizeof(WCHAR) ); // // Copy the length into the dirinfo structure. Note // that the LHS below is a USHORT, so it can not // be specificed as the OUT parameter above. // BothDirInfo->ShortNameLength = (UCHAR)ShortNameLength; // // If something happened with the conversion, bail here. // if ( !NT_SUCCESS( Status ) ) { try_return( NOTHING ); } case FileFullDirectoryInformation: case FileIdFullDirectoryInformation: DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0); // // Get the Ea file length. // FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry]; // // If the EAs are corrupt, ignore the error. We don't want // to abort the directory query. // try { FatGetEaLength( IrpContext, Vcb, Dirent, &FullDirInfo->EaSize ); } except(EXCEPTION_EXECUTE_HANDLER) { FatResetExceptionState( IrpContext ); FullDirInfo->EaSize = 0; } case FileDirectoryInformation: DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry]; FatGetDirTimes( IrpContext, Dirent, DirInfo ); DirInfo->EndOfFile.QuadPart = Dirent->FileSize; if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) { DirInfo->AllocationSize.QuadPart = ( (( Dirent->FileSize + DiskAllocSize - 1 ) / DiskAllocSize ) * DiskAllocSize ); } DirInfo->FileAttributes = Dirent->Attributes != 0 ? Dirent->Attributes : FILE_ATTRIBUTE_NORMAL; DirInfo->FileIndex = NextVbo; DirInfo->FileNameLength = FileNameLength; DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String); break; case FileNamesInformation: DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0); NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry]; NamesInfo->FileIndex = NextVbo; NamesInfo->FileNameLength = FileNameLength; DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String ); break; default: FatBugCheck( FileInformationClass, 0, 0 ); } BytesConverted = BytesRemainingInBuffer - BaseLength >= FileNameLength ? FileNameLength : BytesRemainingInBuffer - BaseLength; RtlCopyMemory( &Buffer[NextEntry + BaseLength], &LongFileName.Buffer[0], BytesConverted ); // // Set up the previous next entry offset // *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry; // // And indicate how much of the user buffer we have currently // used up. We must compute this value before we long align // ourselves for the next entry // Irp->IoStatus.Information = QuadAlign( Irp->IoStatus.Information ) + BaseLength + BytesConverted; // // Check for the case that a single entry doesn't fit. // This should only get this far on the first entry. // if (BytesConverted < FileNameLength) { ASSERT( NextEntry == 0 ); try_return( Status = STATUS_BUFFER_OVERFLOW ); } } // // Finish up by filling in the FileId // switch ( FileInformationClass ) { case FileIdBothDirectoryInformation: IdBothDirInfo = (PFILE_ID_BOTH_DIR_INFORMATION)&Buffer[NextEntry]; IdBothDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo ); break; case FileIdFullDirectoryInformation: IdFullDirInfo = (PFILE_ID_FULL_DIR_INFORMATION)&Buffer[NextEntry]; IdFullDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo ); break; default: break; } } except (EXCEPTION_EXECUTE_HANDLER) { // // We had a problem filling in the user's buffer, so stop and // fail this request. This is the only reason any exception // would have occured at this level. // Irp->IoStatus.Information = 0; UpdateCcb = FALSE; try_return( Status = GetExceptionCode()); } // // Set ourselves up for the next iteration // LastEntry = NextEntry; NextEntry += (ULONG)QuadAlign(BaseLength + BytesConverted); CurrentVbo = NextVbo + sizeof( DIRENT ); } try_exit: NOTHING; } finally {
VOID IopInitializeResourceMap ( PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Initializes the resource map by adding in the physical memory which is in use by the system. --*/ { ULONG i, j, pass, length; LARGE_INTEGER li; HANDLE keyHandle; UNICODE_STRING unicodeString, systemString, listString; NTSTATUS status; PCM_RESOURCE_LIST ResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor; BOOLEAN IncludeType[LoaderMaximum]; ULONG MemoryAlloc[(sizeof(PHYSICAL_MEMORY_DESCRIPTOR) + sizeof(PHYSICAL_MEMORY_RUN)*MAX_PHYSICAL_MEMORY_FRAGMENTS) / sizeof(ULONG)]; PPHYSICAL_MEMORY_DESCRIPTOR MemoryBlock; RtlInitUnicodeString( &systemString, IopWstrSystem); RtlInitUnicodeString( &listString, IopWstrTranslated ); for (pass=0; pass < 2; pass++) { switch (pass) { case 0: // // Add MmPhysicalMemoryBlock to regitry // RtlInitUnicodeString( &unicodeString, IopWstrPhysicalMemory); MemoryBlock = MmPhysicalMemoryBlock; break; case 1: // // Add LoadSpecialMemory to registry // RtlInitUnicodeString( &unicodeString, IopWstrSpecialMemory); // // Computer memory limits of LoaderSpecialMemory // MemoryBlock = (PPHYSICAL_MEMORY_DESCRIPTOR)&MemoryAlloc; MemoryBlock->NumberOfRuns = MAX_PHYSICAL_MEMORY_FRAGMENTS; for (j=0; j < LoaderMaximum; j++) { IncludeType[j] = FALSE; } IncludeType[LoaderSpecialMemory] = TRUE; MmInitializeMemoryLimits( LoaderBlock, IncludeType, MemoryBlock ); break; } // // Allocate and build a CM_RESOURCE_LIST to describe all // of physical memory // j = MemoryBlock->NumberOfRuns; if (j == 0) { continue; } length = sizeof(CM_RESOURCE_LIST) + (j-1) * sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR); ResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (PagedPool, length); if (!ResourceList) { return; } RtlZeroMemory ((PVOID) ResourceList, length); ResourceList->Count = 1; ResourceList->List[0].PartialResourceList.Count = j; CmDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; for (i=0; i < j; i++) { CmDescriptor->Type = CmResourceTypeMemory; CmDescriptor->ShareDisposition = CmResourceShareDeviceExclusive; li.QuadPart = (LONGLONG)(MemoryBlock->Run[i].BasePage); li.QuadPart <<= PAGE_SHIFT; CmDescriptor->u.Memory.Start = li; // fixfix - handle page frame numbers greater than 32 bits. CmDescriptor->u.Memory.Length = (ULONG)(MemoryBlock->Run[i].PageCount << PAGE_SHIFT); CmDescriptor++; } // // Add the resoruce list to the resorucemap // status = IopOpenRegistryKey( &keyHandle, (HANDLE) NULL, &CmRegistryMachineHardwareResourceMapName, KEY_READ | KEY_WRITE, TRUE ); if (NT_SUCCESS( status )) { IopWriteResourceList ( keyHandle, &systemString, &unicodeString, &listString, ResourceList, length ); ZwClose( keyHandle ); } ExFreePool (ResourceList); } }
/* * @implemented */ VOID EXPORT NdisOpenAdapter( OUT PNDIS_STATUS Status, OUT PNDIS_STATUS OpenErrorStatus, OUT PNDIS_HANDLE NdisBindingHandle, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE NdisProtocolHandle, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_STRING AdapterName, IN UINT OpenOptions, IN PSTRING AddressingInformation OPTIONAL) /* * FUNCTION: Opens an adapter for communication * ARGUMENTS: * Status = Address of buffer for status information * OpenErrorStatus = Address of buffer for secondary error code * NdisBindingHandle = Address of buffer for adapter binding handle * SelectedMediumIndex = Address of buffer for selected medium * MediumArray = Pointer to an array of NDIS_MEDIUMs called can support * MediumArraySize = Number of elements in MediumArray * NdisProtocolHandle = Handle returned by NdisRegisterProtocol * ProtocolBindingContext = Pointer to caller suplied context area * AdapterName = Pointer to buffer with name of adapter * OpenOptions = Bitmask with flags passed to next-lower driver * AddressingInformation = Optional pointer to buffer with NIC specific information */ { UINT i; BOOLEAN Found; PLOGICAL_ADAPTER Adapter; PADAPTER_BINDING AdapterBinding; PPROTOCOL_BINDING Protocol = GET_PROTOCOL_BINDING(NdisProtocolHandle); NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); if(!NdisProtocolHandle) { NDIS_DbgPrint(MIN_TRACE, ("NdisProtocolHandle is NULL\n")); *OpenErrorStatus = *Status = NDIS_STATUS_FAILURE; return; } Adapter = MiniLocateDevice(AdapterName); if (!Adapter) { NDIS_DbgPrint(MIN_TRACE, ("Adapter not found.\n")); *Status = NDIS_STATUS_ADAPTER_NOT_FOUND; return; } /* Find the media type in the list provided by the protocol driver */ Found = FALSE; for (i = 0; i < MediumArraySize; i++) { if (Adapter->NdisMiniportBlock.MediaType == MediumArray[i]) { *SelectedMediumIndex = i; Found = TRUE; break; } } if (!Found) { NDIS_DbgPrint(MIN_TRACE, ("Medium is not supported.\n")); *Status = NDIS_STATUS_UNSUPPORTED_MEDIA; return; } /* Now that we have confirmed that the adapter can be opened, create a binding */ AdapterBinding = ExAllocatePool(NonPagedPool, sizeof(ADAPTER_BINDING)); if (!AdapterBinding) { NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); *Status = NDIS_STATUS_RESOURCES; return; } RtlZeroMemory(AdapterBinding, sizeof(ADAPTER_BINDING)); AdapterBinding->ProtocolBinding = Protocol; AdapterBinding->Adapter = Adapter; AdapterBinding->NdisOpenBlock.ProtocolBindingContext = ProtocolBindingContext; /* Set fields required by some NDIS macros */ AdapterBinding->NdisOpenBlock.BindingHandle = (NDIS_HANDLE)AdapterBinding; /* Set handlers (some NDIS macros require these) */ AdapterBinding->NdisOpenBlock.RequestHandler = ProRequest; AdapterBinding->NdisOpenBlock.ResetHandler = ProReset; AdapterBinding->NdisOpenBlock.SendHandler = ProSend; AdapterBinding->NdisOpenBlock.SendPacketsHandler = ProSendPackets; AdapterBinding->NdisOpenBlock.TransferDataHandler = ProTransferData; AdapterBinding->NdisOpenBlock.RequestCompleteHandler = Protocol->Chars.RequestCompleteHandler; /* Put on protocol's bound adapters list */ ExInterlockedInsertTailList(&Protocol->AdapterListHead, &AdapterBinding->ProtocolListEntry, &Protocol->Lock); /* Put protocol on adapter's bound protocols list */ NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); ExInterlockedInsertTailList(&Adapter->ProtocolListHead, &AdapterBinding->AdapterListEntry, &Adapter->NdisMiniportBlock.Lock); *NdisBindingHandle = (NDIS_HANDLE)AdapterBinding; *Status = NDIS_STATUS_SUCCESS; }
// get base address from the specified module in the process HMODULE engine_GetRemoteModuleHandle(HANDLE hProcess,LPSTR lpModule) { PROCESS_BASIC_INFORMATION pbi; PEB_LDR_DATA ldrData; LDR_MODULE ldrModule; UNICODE_STRING usModuleName; ANSI_STRING asModuleName; PEB Peb; LPVOID lpBase; LPVOID lpFirst; WCHAR* wcModuleName; if (!NT_SUCCESS(NtQueryInformationProcess(hProcess,ProcessBasicInformation,&pbi,sizeof(pbi),NULL))) return NULL; if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,pbi.PebBaseAddress,&Peb,sizeof(Peb),NULL))) return NULL; if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,Peb.Ldr,&ldrData,sizeof(ldrData),NULL))) { // temp workaround ? // this shit happens when we call this function in our NtResumethread hook // Ldr is NULL then... :/ // Vista's dllbaseaddress randomization changes per reboot anyway :-) return engine_NtGetModuleHandleA(lpModule); } lpFirst=lpBase=ldrData.InLoadOrderModuleList.Flink; while (1) { if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpBase,&ldrModule,sizeof(LDR_MODULE),NULL))) break; if ((DWORD)ldrModule.InLoadOrderModuleList.Flink==(DWORD)lpFirst) break; if (!(wcModuleName=(WCHAR*)misc_AllocBuffer(ldrModule.BaseDllName.Length+2))) break; RtlZeroMemory(wcModuleName,ldrModule.BaseDllName.Length+2); if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,ldrModule.BaseDllName.Buffer,wcModuleName,ldrModule.BaseDllName.Length,NULL))) { misc_FreeBuffer(&wcModuleName); break; } usModuleName.Buffer=wcModuleName; usModuleName.Length=ldrModule.BaseDllName.Length; usModuleName.MaximumLength=ldrModule.BaseDllName.MaximumLength; if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&asModuleName,&usModuleName,TRUE))) { if (strnicmp(asModuleName.Buffer,lpModule,strlen(lpModule))==0) { RtlFreeAnsiString(&asModuleName); misc_FreeBuffer(&wcModuleName); return ldrModule.BaseAddress; } } RtlFreeAnsiString(&asModuleName); misc_FreeBuffer(&wcModuleName); lpBase=ldrModule.InLoadOrderModuleList.Flink; } return NULL; }
DWORD MonitorAppRemoveCallouts() /*++ Routine Description: Sets the kernel callout ID's through the Monitor Sample device Arguments: [in] HANDLE monitorDevice - Monitor Sample device [in] CALLOUTS* callouts - Callout structure with ID's set [in] DWORD size - Size of the callout structure. Return Value: NO_ERROR or a specific DeviceIoControl result. --*/ { DWORD result; HANDLE engineHandle = NULL; FWPM_SESSION session; RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Sample Non-Dynamic Session"; session.displayData.description = L"For Adding callouts"; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Starting Transaction for Removing callouts\n"); result = FwpmTransactionBegin(engineHandle, 0); if (NO_ERROR != result) { goto abort; } printf("Successfully started the Transaction\n"); printf("Deleting Flow Established callout\n"); result = FwpmCalloutDeleteByKey(engineHandle, &MONITOR_SAMPLE_FLOW_ESTABLISHED_CALLOUT_V4); if (NO_ERROR != result) { goto abort; } printf("Successfully Deleted Flow Established callout\n"); printf("Deleting Stream callout\n"); result = FwpmCalloutDeleteByKey(engineHandle, &MONITOR_SAMPLE_STREAM_CALLOUT_V4); if (NO_ERROR != result) { goto abort; } printf("Successfully Deleted Stream callout\n"); printf("Committing Transaction\n"); result = FwpmTransactionCommit(engineHandle); if (NO_ERROR == result) { printf("Successfully Committed Transaction.\n"); } goto cleanup; abort: printf("Aborting Transaction\n"); result = FwpmTransactionAbort(engineHandle); if (NO_ERROR == result) { printf("Successfully Aborted Transaction.\n"); } cleanup: if (engineHandle) { FwpmEngineClose(engineHandle); } return result; }
// get address from given procedure in specified module LPVOID engine_GetRemoteProcAddress(HANDLE hProcess,HMODULE hModule,LPSTR lpFunction) { IMAGE_DOS_HEADER DosHdr; IMAGE_NT_HEADERS NtHdr; IMAGE_EXPORT_DIRECTORY ExtDir; UINT uj; CHAR* dwReadAddr; CHAR* pcExportAddr; CHAR* pcFuncName; CHAR* pcFuncPtr; DWORD dwFuncAddr; CHAR* pcBuffer; WORD wOrd; if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,hModule,&DosHdr,sizeof(IMAGE_DOS_HEADER),NULL))) return NULL; if (IMAGE_DOS_SIGNATURE==DosHdr.e_magic) { dwReadAddr=(char*)hModule+DosHdr.e_lfanew; if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,dwReadAddr,&NtHdr,sizeof(IMAGE_NT_HEADERS),NULL))) return NULL; if(IMAGE_NT_SIGNATURE==NtHdr.Signature||IMAGE_NT_SIGNATURE1==NtHdr.Signature) { pcExportAddr=(char*)((DWORD)hModule+(DWORD)NtHdr.OptionalHeader.DataDirectory[0].VirtualAddress); if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,pcExportAddr,&ExtDir,sizeof(IMAGE_EXPORT_DIRECTORY),NULL))) return NULL; pcExportAddr=(char*)((DWORD)hModule+(DWORD)ExtDir.AddressOfNames); for (uj=0;uj<ExtDir.NumberOfFunctions;uj++) { if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,pcExportAddr,&pcFuncName,sizeof(char*),NULL))) return NULL; pcBuffer=(CHAR*)misc_AllocBuffer(255); if (!pcBuffer) return NULL; RtlZeroMemory(pcBuffer,255); if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,(char*)((DWORD)hModule+(DWORD)pcFuncName),pcBuffer,254,NULL))) { misc_FreeBuffer(&pcBuffer); return NULL; } if (stricmp(pcBuffer,lpFunction)==0) { pcFuncPtr=(char*)((DWORD)hModule+(DWORD)ExtDir.AddressOfNameOrdinals+(uj*sizeof(WORD))); if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,pcFuncPtr,&wOrd,sizeof(WORD),NULL))) { misc_FreeBuffer(&pcBuffer); return NULL; } pcFuncPtr=(char*)((DWORD)hModule+(DWORD)ExtDir.AddressOfFunctions+(wOrd*sizeof(DWORD))); if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,pcFuncPtr,&dwFuncAddr,sizeof(DWORD),NULL))) { misc_FreeBuffer(&pcBuffer); return NULL; } misc_FreeBuffer(&pcBuffer); return (char*)hModule+dwFuncAddr; } misc_FreeBuffer(&pcBuffer); pcExportAddr+=sizeof(char*); } } } return NULL; }
DWORD MonitorAppDoMonitoring(PCWSTR AppPath) { HANDLE monitorDevice = NULL; HANDLE engineHandle = NULL; DWORD result; MONITOR_SETTINGS monitorSettings; FWPM_SESSION session; FWP_BYTE_BLOB* applicationId = NULL; RtlZeroMemory(&monitorSettings, sizeof(MONITOR_SETTINGS)); RtlZeroMemory(&session, sizeof(FWPM_SESSION)); session.displayData.name = L"Monitor Sample Session"; session.displayData.description = L"Monitors traffic at the Stream layer."; // Let the Base Filtering Engine cleanup after us. session.flags = FWPM_SESSION_FLAG_DYNAMIC; printf("Opening Filtering Engine\n"); result = FwpmEngineOpen( NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle ); if (NO_ERROR != result) { goto cleanup; } printf("Successfully opened Filtering Engine\n"); printf("Looking up Application ID from BFE\n"); result = MonitorAppIDFromPath(AppPath, &applicationId); if (NO_ERROR != result) { goto cleanup; } printf("Successfully retrieved Application ID\n"); printf("Opening Monitor Sample Device\n"); result = MonitorAppOpenMonitorDevice(&monitorDevice); if (NO_ERROR != result) { goto cleanup; } printf("Successfully opened Monitor Device\n"); printf("Adding Filters through the Filtering Engine\n"); result = MonitorAppAddFilters(engineHandle, applicationId); if (NO_ERROR != result) { goto cleanup; } printf("Successfully added Filters through the Filtering Engine\n"); printf("Enabling monitoring through the Monitor Sample Device\n"); monitorSettings.monitorOperation = monitorTraffic; result = MonitorAppEnableMonitoring(monitorDevice, &monitorSettings); if (NO_ERROR != result) { goto cleanup; } printf("Successfully enabled monitoring.\n"); printf("Events will be traced through WMI. Please press any key to exit and cleanup filters.\n"); #pragma prefast(push) #pragma prefast(disable:6031, "by design the return value of _getch() is ignored here") _getch(); #pragma prefast(pop) cleanup: if (NO_ERROR != result) { printf("Monitor.\tError 0x%x occurred during execution\n", result); } if (monitorDevice) { MonitorAppCloseMonitorDevice(monitorDevice); } // // Free the application Id that we retrieved. // if (applicationId) { FwpmFreeMemory((void**)&applicationId); } if (engineHandle) { result = FwpmEngineClose(engineHandle); engineHandle = NULL; } return result; }
NTSTATUS NTAPI CPortPinWavePci::Init( IN PPORTWAVEPCI Port, IN PPORTFILTERWAVEPCI Filter, IN KSPIN_CONNECT * ConnectDetails, IN KSPIN_DESCRIPTOR * KsPinDescriptor, IN PDEVICE_OBJECT DeviceObject) { NTSTATUS Status; PKSDATAFORMAT DataFormat; BOOLEAN Capture; ISubdevice * Subdevice = NULL; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; // check if it is a source / sink pin if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) { // sink pin Capture = FALSE; } else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) { // source pin Capture = TRUE; } else { DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); DbgBreakPoint(); while(TRUE); } // add port / filter reference Port->AddRef(); Filter->AddRef(); // initialize pin m_Port = Port; m_Filter = Filter; m_KsPinDescriptor = KsPinDescriptor; m_ConnectDetails = ConnectDetails; m_Miniport = GetWavePciMiniport(Port); m_DeviceObject = DeviceObject; m_State = KSSTATE_STOP; m_Capture = Capture; DPRINT("IPortPinWavePci_fnInit entered\n"); // get dataformat DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); // allocate data format m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!m_Format) { // release references m_Port->Release(); m_Filter->Release(); // no dangling pointers Port = NULL; Filter = NULL; // failed to allocate data format return STATUS_INSUFFICIENT_RESOURCES; } // copy data format RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); // allocate new stream Status = m_Miniport->NewStream(&m_Stream, NULL, NonPagedPool, PPORTWAVEPCISTREAM(this), ConnectDetails->PinId, Capture, m_Format, &m_DmaChannel, &m_ServiceGroup); DPRINT("IPortPinWavePci_fnInit Status %x\n", Status); if (!NT_SUCCESS(Status)) { // free references Port->Release(); Filter->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Port = NULL; m_Filter = NULL; m_Format = NULL; // failed to allocate stream return Status; } // get allocator requirements for pin Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming); if (NT_SUCCESS(Status)) { DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); } // allocate new irp queue Status = NewIrpQueue(&m_IrpQueue); if (!NT_SUCCESS(Status)) { // free references Port->Release(); Filter->Release(); m_Stream->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Port = NULL; m_Filter = NULL; m_Format = NULL; m_Stream = NULL; // failed to allocate irp queue return Status; } // initialize irp queue Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, TRUE); if (!NT_SUCCESS(Status)) { // this should never happen ASSERT(0); } // get subdevice interface Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); if (!NT_SUCCESS(Status)) { // this function should never fail ASSERT(0); } // get subdevice descriptor Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); if (!NT_SUCCESS(Status)) { // this function should never fail ASSERT(0); } // release subdevice Subdevice->Release(); /* set up subdevice descriptor */ RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); m_Descriptor.FilterPropertySet = PinWavePciPropertySet; m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET); m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; m_Descriptor.PortPin = (PVOID)this; if (m_ServiceGroup) { Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); if (!NT_SUCCESS(Status)) { // free references m_Stream->Release(); Port->Release(); Filter->Release(); // free data format FreeItem(m_Format, TAG_PORTCLASS); // no dangling pointers m_Stream = NULL; m_Port = NULL; m_Filter = NULL; m_Format = NULL; // failed to add to service group return Status; } } return STATUS_SUCCESS; }
NTSTATUS LurCreate ( IN PLURELATION_DESC LurDesc2, IN BOOLEAN EnableSecondaryOnly, IN BOOLEAN EnableW2kReadOnlyPacth, IN PDEVICE_OBJECT AdapterFunctionDeviceObject, IN PVOID AdapterHardwareExtension, IN LURN_EVENT_CALLBACK LurnEventCallback, OUT PLURELATION *Lur ) { NTSTATUS status; PLURELATION tmpLur; ULONG tmpLurLength; PLURELATION_NODE tmpLurn[LUR_MAX_LURNS_PER_LUR]; PLURELATION_NODE_DESC currentLurnDesc; LONG idx_lurn; LONG idx_child; ULONG child; BOOLEAN writeCheckRequired = FALSE; ULONG lowestHwVersion; NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); if (LurDesc2->LurnDescCount <= 0 || LurDesc2->LurnDescCount > LUR_MAX_LURNS_PER_LUR) { NDAS_ASSERT(FALSE); return STATUS_INVALID_PARAMETER; } #if __ENABLE_CONTENTENCRYPT_AES_TEST__ InitialEcrKey( LurDesc ); #endif // create LURELATION tmpLurLength = sizeof(LURELATION) + sizeof(PLURELATION_NODE) * (LurDesc2->LurnDescCount - 1) + LurDesc2->Length; tmpLur = (PLURELATION)ExAllocatePoolWithTag( NonPagedPool, tmpLurLength, LUR_POOL_TAG ); if (!tmpLur) { NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES ); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory( tmpLur, tmpLurLength ); tmpLur->LurDesc = (PLURELATION_DESC) ((PUCHAR)tmpLur + (sizeof(LURELATION) + sizeof(PLURELATION_NODE) * (LurDesc2->LurnDescCount - 1))); RtlCopyMemory( tmpLur->LurDesc, LurDesc2, LurDesc2->Length ); tmpLur->Type = LSSTRUC_TYPE_LUR; tmpLur->Length = sizeof(LURELATION); tmpLur->DeviceMode = tmpLur->LurDesc->DeviceMode; tmpLur->EndingBlockAddr = tmpLur->LurDesc->EndingBlockAddr; tmpLur->LowestHwVer = -1; tmpLur->LurFlags = 0; tmpLur->SupportedNdasFeatures = 0; tmpLur->EnabledNdasFeatures = 0; tmpLur->StartOffset = tmpLur->LurDesc->StartOffset; tmpLur->LockImpossible = tmpLur->LurDesc->LockImpossible; tmpLur->EmergencyMode = tmpLur->LurDesc->EmergencyMode; tmpLur->UnitBlocks = tmpLur->LurDesc->EndingBlockAddr + 1; tmpLur->MaxChildrenSectorCount = tmpLur->UnitBlocks; tmpLur->NodeCount = tmpLur->LurDesc->LurnDescCount; RtlCopyMemory( tmpLur->LurId, tmpLur->LurDesc->LurId, LURID_LENGTH ); tmpLur->AdapterFunctionDeviceObject = AdapterFunctionDeviceObject; tmpLur->AdapterHardwareExtension = AdapterHardwareExtension; tmpLur->LurnEventCallback = LurnEventCallback; LsuInitializeBlockAcl( &tmpLur->SystemBacl ); LsuInitializeBlockAcl( &tmpLur->UserBacl ); InitializeListHead( &tmpLur->ListEntry ); NDAS_ASSERT( tmpLur->StartOffset == 0 || tmpLur->StartOffset == NDAS_RAID_DEFAULT_START_OFFSET ); #if __ENABLE_BACL_TEST__ { PLSU_BLOCK_ACE blockAce; blockAce = LsuCreateBlockAce(LSUBACE_ACCESS_READ, 0x3f, 0x3f); if (blockAce) { LsuInsertAce( &tmpLur->SystemBacl, blockAce ); } } #endif // Content encryption tmpLur->CntEcrMethod = tmpLur->LurDesc->CntEcrMethod; tmpLur->CntEcrKeyLength = tmpLur->LurDesc->CntEcrKeyLength; if (tmpLur->LurDesc->CntEcrKeyLength) { RtlCopyMemory( tmpLur->CntEcrKey, tmpLur->LurDesc->CntEcrKey, tmpLur->CntEcrKeyLength ); #if DBG { ULONG keyIdx; DebugTrace( NDASSCSI_DBG_LUR_INFO, ("Encryption key method:%02x, key length:%d * 4bytes, ", tmpLur->LurDesc->CntEcrMethod, (int)tmpLur->LurDesc->CntEcrKeyLength) ); for (keyIdx = 0; keyIdx<tmpLur->CntEcrKeyLength; keyIdx++) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("%02x ", (int)tmpLur->CntEcrKey[keyIdx]) ); if ((keyIdx%4) == 0) { DebugTrace( NDASSCSI_DBG_LUR_INFO, (" ") ); } } DebugTrace( NDASSCSI_DBG_LUR_INFO, ("\n") ); } #endif } status = NdasRaidStart( &NdasrGlobalData ); if (status != STATUS_SUCCESS) { goto error_out; } // Allocate LURNs to LURN descriptor Table and sanity check. RtlZeroMemory( tmpLurn, sizeof(PLURELATION_NODE) * LUR_MAX_LURNS_PER_LUR ); lowestHwVersion = -1; currentLurnDesc = tmpLur->LurDesc->LurnDesc; for (idx_lurn = 0; idx_lurn < (LONG)tmpLur->LurDesc->LurnDescCount; idx_lurn++) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("Idx:%d LurnDesc:%p NextOffset:%d %d\n", idx_lurn, currentLurnDesc, currentLurnDesc->NextOffset, currentLurnDesc->LurnChildrenCnt) ); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LurnDesc->MaxDataSendLength = %d, LurnDesc->MaxDataRecvLength = %d\n", currentLurnDesc->MaxDataSendLength, currentLurnDesc->MaxDataRecvLength) ); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LurnDesc->LurnIde.HWVersion = %d, LurnDesc->LurnIde.HWRevision = %d\n", currentLurnDesc->LurnIde.HWVersion, currentLurnDesc->LurnIde.HWRevision) ); // Save the lowest hardware version from leaf nodes. if (currentLurnDesc->LurnChildrenCnt == 0) { if (lowestHwVersion > currentLurnDesc->LurnIde.HWVersion) { lowestHwVersion = currentLurnDesc->LurnIde.HWVersion; DebugTrace( NDASSCSI_DBG_LUR_INFO, ("lowestHwVersion = %d\n", lowestHwVersion) ); } } if (currentLurnDesc->NextOffset == 0 && (LONG)idx_lurn + 1 < (LONG)tmpLur->LurDesc->LurnDescCount) { NDAS_ASSERT(FALSE); status = STATUS_INVALID_PARAMETER; } if (currentLurnDesc->LurnType < 0 || currentLurnDesc->LurnType > LURN_LAST_DEVICE_TYPE) { NDAS_ASSERT(FALSE); status = STATUS_INVALID_PARAMETER; break; } status = LurnAllocate( &tmpLurn[idx_lurn], currentLurnDesc->LurnChildrenCnt ); if (status != STATUS_SUCCESS) { NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES ); break; } // Also initialize LURN index in the LUR. tmpLurn[idx_lurn]->LurnStatus = LURN_STATUS_INIT; tmpLur->Nodes[idx_lurn] = tmpLurn[idx_lurn]; tmpLurn[idx_lurn]->LurnDesc = currentLurnDesc; currentLurnDesc = (PLURELATION_NODE_DESC)((PBYTE)tmpLur->LurDesc + currentLurnDesc->NextOffset); } if (status != STATUS_SUCCESS) { goto error_out; } if (lowestHwVersion > LANSCSIIDE_CURRENT_VERSION) { NDAS_ASSERT(FALSE); status = STATUS_INVALID_PARAMETER; goto error_out; } if (lowestHwVersion < LANSCSIIDE_VERSION_1_1) { if (tmpLur->LurDesc->LurnDescCount > 1) { if (tmpLur->LockImpossible == FALSE) { tmpLur->LockImpossible = TRUE; } } } if (tmpLur->LockImpossible) { NDAS_ASSERT( tmpLur->StartOffset == 0 ); if (tmpLur->LurDesc->LurnDescCount > 1) { lowestHwVersion = LANSCSIIDE_VERSION_1_0; } } // Detect supported NDAS features based on the lowest hardware version // We can only support minimum of all child hardware for RAID. LurDetectSupportedNdasFeatures( &tmpLur->SupportedNdasFeatures, lowestHwVersion ); // Enable features to default values or values set by a user. // User requests overrides the default features. status = LurEnableNdasFeauresByDeviceMode( &tmpLur->EnabledNdasFeatures, tmpLur->SupportedNdasFeatures, EnableW2kReadOnlyPacth, tmpLur->DeviceMode ); if (status != STATUS_SUCCESS) { NDAS_ASSERT(FALSE); goto error_out; } status = LurEnableNdasFeaturesByUserRequest( &tmpLur->EnabledNdasFeatures, tmpLur->SupportedNdasFeatures, tmpLur->LurDesc->LurOptions ); if (status != STATUS_SUCCESS) { NDAS_ASSERT(FALSE); goto error_out; } DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LurOptions=%08lx Supported features=%08lx Enabled features=%08lx tmpLur->DeviceMode = %x\n", tmpLur->LurDesc->LurOptions, tmpLur->SupportedNdasFeatures, tmpLur->EnabledNdasFeatures, tmpLur->DeviceMode) ); // Build tree. Set up LURN. // Initialize nodes from leaves to a root. // Node 0 is root. status = STATUS_SUCCESS; for (idx_lurn = tmpLur->LurDesc->LurnDescCount - 1; idx_lurn >= 0; idx_lurn--) { // Set LURN IDs of itself, parent,and children. // LURN ID must be the index number in LUR->Nodes[] array. tmpLurn[idx_lurn]->LurnId = tmpLurn[idx_lurn]->LurnDesc->LurnId; tmpLurn[idx_lurn]->LurnParent = tmpLurn[tmpLurn[idx_lurn]->LurnDesc->LurnParent]; // Children tmpLurn[idx_lurn]->LurnChildrenCnt = tmpLurn[idx_lurn]->LurnDesc->LurnChildrenCnt; status = STATUS_SUCCESS; for (idx_child = 0; idx_child < (LONG)tmpLurn[idx_lurn]->LurnDesc->LurnChildrenCnt; idx_child++) { child = tmpLurn[idx_lurn]->LurnDesc->LurnChildren[idx_child]; if (child > tmpLur->LurDesc->LurnDescCount) { NDAS_ASSERT(FALSE); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("invalid child number.\n") ); status = STATUS_INVALID_PARAMETER; break; } tmpLurn[idx_lurn]->LurnChildren[idx_child] = tmpLurn[child]; tmpLurn[child]->LurnChildIdx = idx_child; } if (status != STATUS_SUCCESS) { break; } // LUR Node's access right tmpLurn[idx_lurn]->LurnDesc->AccessRight = 0; if (tmpLur->DeviceMode == DEVMODE_SHARED_READONLY) { tmpLurn[idx_lurn]->LurnDesc->AccessRight = GENERIC_READ; } else if (tmpLur->DeviceMode == DEVMODE_SHARED_READWRITE) { if (FlagOn(tmpLur->LurDesc->LurOptions, LUROPTION_DONOT_ADJUST_PRIM_SEC_ROLE)) { if (EnableSecondaryOnly) { tmpLurn[idx_lurn]->LurnDesc->AccessRight = GENERIC_READ; tmpLur->EnabledNdasFeatures |= NDASFEATURE_SECONDARY; } else { tmpLurn[idx_lurn]->LurnDesc->AccessRight = GENERIC_WRITE | GENERIC_READ; } } else { tmpLur->EnabledNdasFeatures |= NDASFEATURE_SECONDARY; tmpLurn[idx_lurn]->LurnDesc->AccessRight = GENERIC_READ; } } else { //NDAS_ASSERT( tmpLur->DeviceMode == DEVMODE_EXCLUSIVE_READWRITE ); tmpLurn[idx_lurn]->LurnDesc->AccessRight = GENERIC_WRITE | GENERIC_READ; } // LUR node options if ((tmpLur->EnabledNdasFeatures & NDASFEATURE_BUFFER_CONTROL) == 0) { tmpLurn[idx_lurn]->LurnDesc->LurnOptions |= LURNOPTION_NO_BUFF_CONTROL; } if (tmpLurn[idx_lurn]->LurnDesc->LurnOptions & LURNOPTION_RESTRICT_UDMA) { tmpLurn[idx_lurn]->UDMARestrictValid = TRUE; tmpLurn[idx_lurn]->UDMARestrict = tmpLurn[idx_lurn]->LurnDesc->UDMARestrict; } else { tmpLurn[idx_lurn]->UDMARestrictValid = FALSE; } if (LURN_DIRECT_ACCESS == tmpLurn[idx_lurn]->LurnDesc->LurnType && LANSCSIIDE_VERSION_2_0 == tmpLurn[idx_lurn]->LurnDesc->LurnIde.HWVersion) { writeCheckRequired = TRUE; } DebugTrace( NDASSCSI_DBG_LUR_INFO, ("tmpLurn[idx_lurn]->LurnDesc->LurnOptions = %x\n", tmpLurn[idx_lurn]->LurnDesc->LurnOptions) ); if (!FlagOn(tmpLurn[idx_lurn]->LurnDesc->LurnOptions, LURNOPTION_SET_RECONNECTION)) { if (!LURN_IS_ROOT_NODE(tmpLurn[idx_lurn])) { if (tmpLurn[idx_lurn]->LurnParent->LurnDesc->LurnType == LURN_NDAS_RAID1 || tmpLurn[idx_lurn]->LurnParent->LurnDesc->LurnType == LURN_NDAS_RAID5) { tmpLurn[idx_lurn]->LurnDesc->ReconnTrial = RECONNECTION_MAX_TRY / 4; tmpLurn[idx_lurn]->LurnDesc->ReconnInterval = MAX_RECONNECTION_INTERVAL / NANO100_PER_MSEC; if (FlagOn(tmpLur->LurDesc->LurOptions, LUROPTION_REDUCE_TIMEOUT)) { tmpLurn[idx_lurn]->LurnDesc->ReconnTrial /= 2; } DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LURNOPTION_SET_RECONNECTION\n") ); SetFlag( tmpLurn[idx_lurn]->LurnDesc->LurnOptions, LURNOPTION_SET_RECONNECTION ); } } } // Initialize the LURN status = LurnCreate( tmpLur, tmpLurn[idx_lurn] ); if (status != STATUS_SUCCESS) { if (tmpLurn[idx_lurn]->LurnDesc->LurnChildrenCnt != 0) { NDAS_ASSERT( NDAS_ASSERT_NODE_UNRECHABLE ); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LurnCreate() failed. LURN#:%d NTSTATUS:%08lx\n", idx_lurn, status) ); break; } } } error_out: if (status != STATUS_SUCCESS) { for (idx_lurn = 0; (ULONG)idx_lurn < tmpLur->LurDesc->LurnDescCount; idx_lurn++) { if (tmpLurn[idx_lurn]) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("Freeing LURN:%p(%d)\n", tmpLurn[idx_lurn], idx_lurn) ); if (LURN_IS_RUNNING(tmpLurn[idx_lurn]->LurnStatus)) { LurnSendStopCcb( tmpLurn[idx_lurn] ); LurnClose( tmpLurn[idx_lurn] ); } LurnFree( tmpLurn[idx_lurn] ); tmpLurn[idx_lurn] = NULL; } } if (tmpLur) { LsuFreeAllBlockAce( &tmpLur->UserBacl.BlockAclHead ); LsuFreeAllBlockAce( &tmpLur->SystemBacl.BlockAclHead ); ExFreePoolWithTag( tmpLur, LUR_POOL_TAG ); } NdasRaidClose( &NdasrGlobalData ); NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); return status; } NDAS_ASSERT( status == STATUS_SUCCESS ); // Block access control list if (tmpLur->LurDesc->BACLOffset) { PNDAS_BLOCK_ACL srcBACL; srcBACL = (PNDAS_BLOCK_ACL)((PUCHAR)tmpLur->LurDesc + tmpLur->LurDesc->BACLOffset); NDAS_ASSERT( srcBACL->Length == tmpLur->LurDesc->BACLLength ); NDAS_ASSERT( tmpLur->BlockBytes ); status = LsuConvertNdasBaclToLsuBacl( &tmpLur->SystemBacl, srcBACL, tmpLur->BlockBytes ); if (status != STATUS_SUCCESS) { NDAS_ASSERT(FALSE); } } if (tmpLur->DeviceMode == DEVMODE_SHARED_READWRITE) { if (EnableSecondaryOnly) { } else if (FlagOn(tmpLur->LurDesc->LurOptions, LUROPTION_DONOT_ADJUST_PRIM_SEC_ROLE)) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("DONOT_ADJUST_ACCESSMODE is set. Can not go to Secondary mode.\n") ); } else { UCHAR ccbStatus; status = LurUpdateSynchrously( tmpLurn[0], LURN_UPDATECLASS_WRITEACCESS_USERID, &ccbStatus ); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("LurUpdateSynchrously status = %x, ccbStatus = %x", status, ccbStatus) ); } } // Indicate Win2K read-only patch if (EnableW2kReadOnlyPacth) { if (RtlCheckRegistryKey(RTL_REGISTRY_SERVICES, NDAS_ROFS_NAME) != STATUS_SUCCESS) { tmpLur->LurFlags |= LURFLAG_W2K_READONLY_PATCH; } } if (writeCheckRequired) { if (tmpLur->LurDesc->LurOptions & LUROPTION_ON_NDAS_2_0_WRITE_CHECK) { tmpLur->LurFlags |= LURFLAG_WRITE_CHECK_REQUIRED; } else if (tmpLur->LurDesc->LurOptions & LUROPTION_OFF_NDAS_2_0_WRITE_CHECK) { tmpLur->LurFlags &= ~LURFLAG_WRITE_CHECK_REQUIRED; } else { // Default on. tmpLur->LurFlags |= LURFLAG_WRITE_CHECK_REQUIRED; } } // set Lur RtlCopyMemory( LurDesc2, tmpLur->LurDesc, LurDesc2->Length ); *Lur = tmpLur; return STATUS_SUCCESS; }
_IRQL_requires_same_ inline VOID KrnlHlprPendDataPurge(_Inout_ PEND_DATA* pPendData) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprPendDataPurge()\n"); #endif /// DBG NT_ASSERT(pPendData); #if(NTDDI_VERSION >= NTDDI_WIN7) if(pPendData->layerID == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V4 || pPendData->layerID == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V6) { if(pPendData->classifyHandle && pPendData->isPended) { FwpsCompleteClassify(pPendData->classifyHandle, 0, &(pPendData->classifyOut)); FwpsReleaseClassifyHandle(pPendData->classifyHandle); pPendData->classifyHandle = 0; pPendData->pPCPendData = 0; pPendData->isPended = FALSE; } } else #endif /// (NTDDI_VERSION >= NTDDI_WIN7) { if(pPendData->completionContext && pPendData->isPended) { FwpsCompleteOperation(pPendData->completionContext, pPendData->pNBL); pPendData->completionContext = 0; pPendData->pNBL = 0; pPendData->pPendAuthorizationData = 0; pPendData->isPended = FALSE; } } RtlZeroMemory(pPendData, sizeof(PEND_DATA)); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprPendDataPurge()\n"); #endif /// DBG return; }
NTSTATUS LurUpdateSynchrously ( IN PLURELATION_NODE Lurn, IN UINT16 UpdateClass, OUT PUCHAR CcbStatus ) { NTSTATUS status; CCB ccb; LURN_UPDATE lurnUpdate; KEVENT completionEvent; LARGE_INTEGER interval; retry: LsCcbInitialize( NULL, NULL, TRUE, &ccb ); LsCcbSetFlag( &ccb, CCB_FLAG_CALLED_INTERNEL ); ccb.OperationCode = CCB_OPCODE_UPDATE; ccb.DataBuffer = &lurnUpdate; ccb.DataBufferLength = sizeof(LURN_UPDATE); RtlZeroMemory( &lurnUpdate, sizeof(LURN_UPDATE) ); lurnUpdate.UpdateClass = UpdateClass; lurnUpdate.TryCount = 1; KeInitializeEvent( &completionEvent, SynchronizationEvent, FALSE ); LsCcbSetCompletionRoutine( &ccb, LurnUpdateSynchrouslyCompletionRoutine, &completionEvent ); status = LurnRequest( Lurn, &ccb ); DebugTrace( NDASSCSI_DBG_LUR_NOISE, ("LurnRequest status : %08x\n", status) ); if (!NT_SUCCESS(status)) { NDAS_ASSERT(FALSE); } if (status == STATUS_PENDING) { status = KeWaitForSingleObject( &completionEvent, Executive, KernelMode, FALSE, NULL ); NDAS_ASSERT( status == STATUS_SUCCESS ); } if (status != STATUS_SUCCESS) { NDAS_ASSERT(FALSE); DebugTrace( NDASSCSI_DBG_LUR_INFO, ("Failed : Status %08lx\n", status) ); status = STATUS_CLUSTER_NODE_UNREACHABLE; LsCcbCleanUp( &ccb ); return status; } if (ccb.CcbStatus == CCB_STATUS_SUCCESS || ccb.OperationCode == CCB_OPCODE_UPDATE && ccb.CcbStatus == CCB_STATUS_NO_ACCESS) { if (CcbStatus) { *CcbStatus = ccb.CcbStatus; } LsCcbCleanUp( &ccb ); return status; } if (ccb.CcbStatus == CCB_STATUS_BUSY) { interval.QuadPart = (-5*NANO100_PER_SEC); //delay 5 seconds KeDelayExecutionThread( KernelMode, FALSE, &interval ); LsCcbCleanUp( &ccb ); goto retry; } if (ccb.CcbStatus == CCB_STATUS_RESET) { NDAS_ASSERT( ccb.OperationCode != CCB_OPCODE_RESETBUS ); interval.QuadPart = (-5*NANO100_PER_SEC); //delay 5 seconds KeDelayExecutionThread( KernelMode, FALSE, &interval ); LsCcbCleanUp( &ccb ); goto retry; } if (ccb.OperationCode == CCB_OPCODE_DEVLOCK && ccb.CcbStatus == CCB_STATUS_LOST_LOCK) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("ccb.CcbStatus = %x\n", ccb.CcbStatus) ); status = STATUS_LOCK_NOT_GRANTED; } else { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("ccb.CcbStatus = %x\n", ccb.CcbStatus) ); if (ccb.CcbStatus != CCB_STATUS_STOP && !(ccb.OperationCode == CCB_OPCODE_DEVLOCK && ccb.CcbStatus == CCB_STATUS_COMMAND_FAILED) && ccb.CcbStatus != CCB_STATUS_NOT_EXIST) { DebugTrace( NDASSCSI_DBG_LUR_INFO, ("ccb.CcbStatus = %x\n", ccb.CcbStatus) ); NDAS_ASSERT(FALSE); } status = STATUS_CLUSTER_NODE_UNREACHABLE; } if (CcbStatus) { *CcbStatus = ccb.CcbStatus; } LsCcbCleanUp( &ccb ); return status; }
NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine gets called by the system to initialize the driver. Arguments: DriverObject - the system supplied driver object. RegistryPath - the system supplied registry path for this driver. Return Value: NTSTATUS --*/ { NTSTATUS status; PFAST_IO_DISPATCH fastIoDispatch; FS_FILTER_CALLBACKS filterCallbacks; PDOKAN_GLOBAL dokanGlobal = NULL; UNREFERENCED_PARAMETER(RegistryPath); DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__, __TIME__); status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal); if (NT_ERROR(status)) { return status; } // // Set up dispatch entry points for the driver. // DriverObject->DriverUnload = DokanUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_READ] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_WRITE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_PNP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = DokanBuildRequest; fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH)); if (!fastIoDispatch) { IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->DeviceObject); DDbgPrint(" ExAllocatePool failed"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible; // fastIoDispatch->FastIoRead = DokanFastIoRead; fastIoDispatch->FastIoRead = FsRtlCopyRead; fastIoDispatch->FastIoWrite = FsRtlCopyWrite; fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection; fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection; fastIoDispatch->MdlRead = FsRtlMdlReadDev; fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev; fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev; fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev; DriverObject->FastIoDispatch = fastIoDispatch; #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, POOL_NX_ALLOCATION, sizeof(IRP_ENTRY), TAG, 0); #else ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, 0, sizeof(IRP_ENTRY), TAG, 0); #endif #if _WIN32_WINNT < 0x0501 RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts"); DokanFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress(&functionName); #endif RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS)); // only be used by filter driver? filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); filterCallbacks.PreAcquireForSectionSynchronization = DokanFilterCallbackAcquireForCreateSection; status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks); if (!NT_SUCCESS(status)) { IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->DeviceObject); DDbgPrint(" FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n", status); return status; } if (!DokanLookasideCreate(&g_DokanCCBLookasideList, sizeof(DokanCCB))) { IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->DeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanFCBLookasideList, sizeof(DokanFCB))) { IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->DeviceObject); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanEResourceLookasideList, sizeof(ERESOURCE))) { IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->DeviceObject); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); ExDeleteLookasideListEx(&g_DokanFCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } DDbgPrint("<== DriverEntry\n"); return (status); }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvRegQueryValueKey // Queries the value of a value key in the registry // // Arguments: // IN RegKeyHandle // Handle to the root key // // IN SubKeyName // Optional subkey path string // // IN ValueName // Value name string // // OUT Length // Storage for return length of data buffer // // Return Value: // Pointer to data buffer, or NULL on error // PVOID testdrvRegQueryValueKey( IN HANDLE RegKeyHandle, IN PWSTR SubKeyName, IN PWSTR ValueName, OUT PULONG Length ) { NTSTATUS status; PKEY_VALUE_PARTIAL_INFORMATION buffer; ULONG length; UNICODE_STRING regPath; UNICODE_STRING name; PVOID retBuffer; OBJECT_ATTRIBUTES objAttributes; HANDLE hReg; BOOLEAN bFreeHandle; // Callers of ZwQueryValueKey must be at PASSIVE_LEVEL IRQL ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT(RegKeyHandle != NULL); ASSERT(ValueName != NULL); ASSERT(Length != NULL); buffer = NULL; retBuffer = NULL; bFreeHandle = FALSE; // Initialize the return length *Length = 0; do { // Check for subkey path if (SubKeyName != NULL) { // Open a new handle RtlInitUnicodeString(®Path, SubKeyName); // Initialize a new object attributes InitializeObjectAttributes( &objAttributes, ®Path, OBJ_CASE_INSENSITIVE, RegKeyHandle, NULL ); status = ZwOpenKey(&hReg, KEY_ALL_ACCESS, &objAttributes); if (!NT_SUCCESS(status)) { testdrvDebugPrint(DBG_PNP, DBG_WARN, __FUNCTION__ ": ZwOpenKey failed %x", status); break; } // Indicate that we need to free a handle here bFreeHandle = TRUE; } else { hReg = RegKeyHandle; } RtlInitUnicodeString(&name, ValueName); status = ZwQueryValueKey( hReg, &name, KeyValuePartialInformation, NULL, 0, &length ); if ((status != STATUS_BUFFER_TOO_SMALL) && (status != STATUS_BUFFER_OVERFLOW)) { testdrvDebugPrint(DBG_PNP, DBG_WARN, __FUNCTION__ ": ZwQueryValueKey failed %x", status); break; } buffer = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, TESTDRV_POOL_TAG); if (buffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } status = ZwQueryValueKey( hReg, &name, KeyValuePartialInformation, buffer, length, &length ); if (!NT_SUCCESS(status)) { testdrvDebugPrint(DBG_PNP, DBG_WARN, __FUNCTION__ ": ZwQueryValueKey failed %x", status); break; } } while (FALSE); // Allocate a buffer to return if (NT_SUCCESS(status)) { // Zero terminate strings just for ease of handling if ((buffer->Type == REG_EXPAND_SZ) || (buffer->Type == REG_MULTI_SZ) || (buffer->Type == REG_SZ)) { // Allocate buffer retBuffer = ExAllocatePoolWithTag( PagedPool, buffer->DataLength + sizeof(WCHAR), TESTDRV_POOL_TAG ); // Zero the buffer RtlZeroMemory(retBuffer, buffer->DataLength + sizeof(WCHAR)); } else { // Allocate buffer retBuffer = ExAllocatePoolWithTag(PagedPool, buffer->DataLength, TESTDRV_POOL_TAG); } } if (retBuffer != NULL) { // Copy the registry data to the return buffer RtlCopyMemory(retBuffer, (PVOID)buffer->Data, buffer->DataLength); // Set the return buffer length *Length = buffer->DataLength; } if (buffer != NULL) { // Free our allocated memory ExFreePool(buffer); buffer = NULL; } if (bFreeHandle) { // Close our reg key handle ZwClose(hReg); } return retBuffer; }
NTSTATUS Bus_AddDevice(__in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS status; PDEVICE_OBJECT deviceObject = NULL; PFDO_DEVICE_DATA deviceData = NULL; PWCHAR deviceName = NULL; ULONG nameLength; UNREFERENCED_PARAMETER(nameLength); PAGED_CODE(); Bus_KdPrint(("Add Device: 0x%p\n", PhysicalDeviceObject)); status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &deviceObject); if (!NT_SUCCESS (status)) { goto End; } deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension; RtlZeroMemory(deviceData, sizeof (FDO_DEVICE_DATA)); INITIALIZE_PNP_STATE(deviceData); deviceData->IsFDO = TRUE; deviceData->Self = deviceObject; ExInitializeFastMutex(&deviceData->Mutex); InitializeListHead(&deviceData->ListOfPDOs); deviceData->UnderlyingPDO = PhysicalDeviceObject; deviceData->DevicePowerState = PowerDeviceUnspecified; deviceData->SystemPowerState = PowerSystemWorking; deviceData->OutstandingIO = 1; KeInitializeEvent(&deviceData->RemoveEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&deviceData->StopEvent, SynchronizationEvent, TRUE); deviceObject->Flags |= DO_POWER_PAGABLE; status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID) &GUID_DEVINTERFACE_SCPVBUS, NULL, &deviceData->InterfaceName); if (!NT_SUCCESS(status)) { Bus_KdPrint(("AddDevice: IoRegisterDeviceInterface failed (%x)", status)); goto End; } deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if (deviceData->NextLowerDriver == NULL) { status = STATUS_NO_SUCH_DEVICE; goto End; } deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; End: if (deviceName) { ExFreePool(deviceName); } if (!NT_SUCCESS(status) && deviceObject) { if (deviceData && deviceData->NextLowerDriver) { IoDetachDevice(deviceData->NextLowerDriver); } IoDeleteDevice(deviceObject); } return status; }