Example #1
0
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;
}
Example #2
0
VOID
LurnResetFaultInfo(PLURELATION_NODE Lurn)
{
	RtlZeroMemory(&Lurn->FaultInfo, sizeof(LURN_FAULT_INFO));
}
Example #3
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}
Example #5
0
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;
}
Example #6
0
/*
 * @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;
}
Example #12
0
// 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);
}
Example #13
0
/*
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;
}
Example #14
0
//////////////////////////////////////////////////////////////////////////
//如果提供的缓存区不够大,返回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;
}
Example #15
0
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;

}
Example #17
0
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 {
Example #18
0
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);
    }
}
Example #19
0
/*
 * @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;
}
Example #20
0
// 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;
}
Example #21
0
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;
}
Example #22
0
// 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;
}
Example #23
0
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;
}
Example #24
0
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;
}
Example #25
0
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;
}
Example #27
0
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;
}
Example #28
0
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);
}
Example #29
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  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(&regPath, SubKeyName);

            // Initialize a new object attributes
            InitializeObjectAttributes(
                &objAttributes,
                &regPath,
                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;
}
Example #30
0
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;
}