Exemplo n.º 1
0
NTSTATUS
NTAPI
StreamClassAddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
    PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
    PDEVICE_OBJECT DeviceObject, LowerDeviceObject;
    PSTREAM_DEVICE_EXTENSION DeviceExtension;
    PKSOBJECT_CREATE_ITEM ItemList;
    NTSTATUS Status;

    /* Fetch driver object extension */
    DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice);
    if (!DriverObjectExtension)
    {
        /* Failed to get driver extension */
        return STATUS_DEVICE_DOES_NOT_EXIST;
    }
    /* Allocate Create Item */
    ItemList = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
    if (!ItemList)
    {
        /* Failed to allocated Create Item */
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Create the FDO */
    Status = IoCreateDevice(DriverObject, DriverObjectExtension->Data.DeviceExtensionSize + sizeof(STREAM_DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 0, &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to create the FDO */
        ExFreePool(ItemList);
        return Status;
    }

    /* Attach to device stack */
    LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
    if (!LowerDeviceObject)
    {
        /* Failed to attach */
        IoDeleteDevice(DeviceObject);
        ExFreePool(ItemList);
        return STATUS_UNSUCCESSFUL;
    }

    /* Zero Create item */
    RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
    /* Setup object class */
    RtlInitUnicodeString(&ItemList->ObjectClass, L"GLOBAL");
    /* Setup CreateDispatch routine */
    ItemList->Create = StreamClassCreateFilter;

    /* Get device extension */
    DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    /* Zero device extension */
    RtlZeroMemory(DeviceExtension, sizeof(STREAM_DEVICE_EXTENSION));
    /* Initialize Ks streaming */
    Status = KsAllocateDeviceHeader(&DeviceExtension->Header, 1, ItemList);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup resources */
        IoDetachDevice(LowerDeviceObject);
        IoDeleteDevice(DeviceObject);
        ExFreePool(ItemList);
        return Status;
    }

    /* Store lower device object */
    DeviceExtension->LowerDeviceObject = LowerDeviceObject;

    /* Store physical device object */
    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    /* Store driver object extension */
    DeviceExtension->DriverExtension = DriverObjectExtension;
    /* Initialize memory list */
    InitializeListHead(&DeviceExtension->MemoryResourceList);
    /* Setup device extension */
    DeviceExtension->DeviceExtension = (PVOID) (DeviceExtension + 1);
    /* Init interrupt dpc */
    KeInitializeDpc(&DeviceExtension->InterruptDpc, StreamClassInterruptDpc, (PVOID)DeviceExtension);

    /* Set device transfer method */
    DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    /* Clear init flag */
    DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;

    return Status;
}
Exemplo n.º 2
0
NTSTATUS
DfsFsctrlSetDomainGluon(
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp,
    IN PVOID InputBuffer,
    IN ULONG InputBufferLength
)
{
    NTSTATUS status = STATUS_SUCCESS;
    MARSHAL_BUFFER marshalBuffer;
    DS_GLUON_P     domainGluonP;
    PDS_GLUON      pDomainGluon;
    DFS_PKT_ENTRY_ID domainId;
    DFS_PKT_ENTRY_INFO domainInfo;
    PDFS_SERVICE pActiveService;
    PDFS_PKT_ENTRY pDCEntry;
    PDFS_PKT pkt;
    ULONG j;
    BOOLEAN pktLocked;


    STD_FSCTRL_PROLOGUE(DfsFsctrlSetDomainGluon, TRUE, FALSE, FALSE);

    //
    // Unmarshal the gluon.
    //

    MarshalBufferInitialize(&marshalBuffer, InputBufferLength, InputBuffer);
    status = DfsRtlGet(&marshalBuffer, &MiDSGluonP, &domainGluonP);

    if (!NT_SUCCESS(status)) {
        DfsDbgTrace(0, Dbg, "Unmarshalling of gluon failed %08lx\n", status);

        DfsCompleteRequest( IrpContext, Irp, status );

        DfsDbgTrace(-1, Dbg, "DfsFsctrlSetDomainGluon: Exited %08lx\n", status);

        return(status);
    }
    pDomainGluon = domainGluonP.pDSGluon;

    DfsDbgTrace(0, Dbg, "Unmarshalled gluon @ %08lx\n", pDomainGluon);
    DfsDbgTrace(0, Dbg, "Name is %ws\n", pDomainGluon->pwszName);
    DfsDbgTrace(0, Dbg, "# of services is %d\n", pDomainGluon->cMachines);
    DfsDbgTrace(0, Dbg, "Unpacking gluon...\n", 0);

    //
    // Initialize the entry id for the domain service.
    //

    domainId.Prefix.Length = wcslen(pDomainGluon->pwszName)*sizeof(WCHAR);
    domainId.Prefix.MaximumLength = domainId.Prefix.Length + sizeof(WCHAR);
    domainId.Prefix.Buffer = ExAllocatePool(PagedPool, domainId.Prefix.MaximumLength);
    if (domainId.Prefix.Buffer == NULL) {

        status = STATUS_INSUFFICIENT_RESOURCES;
        DfsDbgTrace(0, Dbg, "Unable to convert name to prefix %08lx\n", status);

        DfspFreeGluon(pDomainGluon);

        DfsCompleteRequest( IrpContext, Irp, status );
        DfsDbgTrace(-1, Dbg, "DfsFsctrlSetDomainGluon: Exit -> %08lx\n", status);
        return status;
    }

    domainId.ShortPrefix.Length = domainId.Prefix.Length;
    domainId.ShortPrefix.MaximumLength = domainId.Prefix.MaximumLength;
    domainId.ShortPrefix.Buffer = ExAllocatePool(PagedPool, domainId.ShortPrefix.MaximumLength);
    if (domainId.ShortPrefix.Buffer == NULL) {

        status = STATUS_INSUFFICIENT_RESOURCES;
        DfsDbgTrace(0, Dbg, "Unable to convert name to short prefix %08lx\n", status);

        ExFreePool(domainId.Prefix.Buffer);

        DfspFreeGluon(pDomainGluon);

        DfsCompleteRequest( IrpContext, Irp, status );
        DfsDbgTrace(-1, Dbg, "DfsFsctrlSetDomainGluon: Exit -> %08lx\n", status);
        return status;
    }

    wcscpy(domainId.Prefix.Buffer, pDomainGluon->pwszName);
    wcscpy(domainId.ShortPrefix.Buffer, pDomainGluon->pwszName);

    DfsDbgTrace(0, Dbg, "Prefix is %wZ\n", &domainId.Prefix);

    RtlCopyMemory(&domainId.Uid, &pDomainGluon->guidThis, sizeof(GUID));

    //
    // Create a new info structure by disassembling the gluon
    //
    // BUGBUG - temporary code till we move to using DS_MACHINES entirely
    //

    domainInfo.ServiceList = ExAllocatePool(PagedPool,
                        pDomainGluon->cMachines * sizeof(DFS_SERVICE));

    if (domainInfo.ServiceList == NULL) {
        DfsDbgTrace(0, Dbg, "Unable to allocated %d bytes\n",
                        (pDomainGluon->cMachines * sizeof(DFS_SERVICE)));

        DfspFreeGluon(pDomainGluon);

        status = STATUS_INSUFFICIENT_RESOURCES;

        DfsCompleteRequest( IrpContext, Irp, status );

        DfsDbgTrace(-1, Dbg, "DfsFsctrlSetDomainGluon: Exit -> %08lx\n", status);

        return status;
    }

    DfspSvcListFromGluon(&domainInfo, &pActiveService, pDomainGluon);

    //
    // Now, lets acquire the Pkt and  insert the domain pkt entry. That's
    // all it takes!
    //

    pkt = _GetPkt();
    PktAcquireExclusive(TRUE, &pktLocked);

    status = PktCreateEntry(
                    pkt,
                    PKT_ENTRY_TYPE_REFERRAL_SVC,
                    &domainId,
                    &domainInfo,
                    PKT_ENTRY_SUPERSEDE,
                    &pDCEntry);
    if (NT_SUCCESS(status)) {
        DfsDbgTrace(0, Dbg, "Created domain pkt entry @ %08lx\n", pDCEntry);
        pDCEntry->ActiveService = pActiveService;
    } else {
        DfsDbgTrace(0, Dbg, "Error %08lx creating domain pkt entry\n", status);
        status = DFS_STATUS_INCONSISTENT;

        //
        // Do some cleanup.
        //

        ExFreePool(domainId.Prefix.Buffer);
        for (j = 0; j < domainInfo.ServiceCount; j++) {
            PktServiceDestroy(&domainInfo.ServiceList[j], FALSE);
        }
        ExFreePool(domainInfo.ServiceList);
    }

    PktRelease();

    DfspFreeGluon(pDomainGluon);

    DfsDbgTrace(-1, Dbg, "DfsFsctrlSetDomainGluon: exited %08lx\n", status);

    DfsCompleteRequest( IrpContext, Irp, status );

    return(status);
}
Exemplo n.º 3
0
BOOL DbgInitDebugChannels()
{
    WCHAR valBuffer[100];
    UNICODE_STRING Value;
    UNICODE_STRING Name = RTL_CONSTANT_STRING(L"DEBUGCHANNEL");
    NTSTATUS Status;
    PPROCESSINFO ppi;
    BOOL ret;

    /* Initialize all channels to ERROR */
    ppi = PsGetCurrentProcessWin32Process();
    RtlFillMemory( ppi->DbgChannelLevel,
                   sizeof(ppi->DbgChannelLevel),
                   ERR_LEVEL);

    /* Find DEBUGCHANNEL env var */
    Value.Buffer = valBuffer;
    Value.Length = 0;
    Value.MaximumLength = sizeof(valBuffer);
    Status = QueryEnvironmentVariable(&Name, &Value);

    /* It does not exist */
    if(Status == STATUS_VARIABLE_NOT_FOUND)
    {
        /* There is nothing more to do */
        return TRUE;
    }

    /* If the buffer in the stack is not enough allocate it */
    if(Status == STATUS_BUFFER_TOO_SMALL)
    {
        Value.Buffer = ExAllocatePool(PagedPool, Value.MaximumLength);
        if(Value.Buffer == NULL)
        {
            return FALSE;
        }

        /* Get the env var again */
        Status = QueryEnvironmentVariable(&Name, &Value);
    }

   /* Check for error */
    if(!NT_SUCCESS(Status))
    {
        if(Value.Buffer != valBuffer)
        {
            ExFreePool(Value.Buffer);
        }

        return FALSE;
    }

    /* Parse the variable */
    ret = DbgParseDebugChannels(ppi, &Value);

    /* Clean up */
    if(Value.Buffer != valBuffer)
    {
        ExFreePool(Value.Buffer);
    }

    return ret;
}
Exemplo n.º 4
0
VOID
NTAPI
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
                     IN PCC_FILE_SIZES FileSizes,
                     IN BOOLEAN PinAccess,
                     IN PCACHE_MANAGER_CALLBACKS Callbacks,
                     IN PVOID LazyWriteContext)
{
    PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
    PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;

    CcpLock();
    /* We don't have a shared cache map.  First find out if we have a sibling
       stream file object we can take it from. */
    if (!Map && FileObject->Flags & FO_STREAM_FILE)
    {
        PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
        if (IdenticalStreamFileObject)
            Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
        if (Map)
        {
            DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
                    FileObject,
                    IdenticalStreamFileObject,
                    Map);
        }
    }
    /* We still don't have a shared cache map.  We need to create one. */
    if (!Map)
    {
        DPRINT("Initializing file object for (%p) %wZ\n",
               FileObject,
               &FileObject->FileName);

        Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
        FileObject->SectionObjectPointer->SharedCacheMap = Map;
        Map->FileSizes = *FileSizes;
        Map->LazyContext = LazyWriteContext;
        Map->ReadAheadGranularity = PAGE_SIZE;
        RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));

        /* For now ... */
        DPRINT("FileSizes->ValidDataLength %I64x\n",
               FileSizes->ValidDataLength.QuadPart);

        InitializeListHead(&Map->AssociatedBcb);
        InitializeListHead(&Map->PrivateCacheMaps);
        InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
        DPRINT("New Map %p\n", Map);
    }
    /* We don't have a private cache map.  Link it with the shared cache map
       to serve as a held reference. When the list in the shared cache map
       is empty, we know we can delete it. */
    if (!PrivateCacheMap)
    {
        PrivateCacheMap = ExAllocatePool(NonPagedPool,
                                         sizeof(*PrivateCacheMap));

        FileObject->PrivateCacheMap = PrivateCacheMap;
        PrivateCacheMap->FileObject = FileObject;
        ObReferenceObject(PrivateCacheMap->FileObject);
    }

    PrivateCacheMap->Map = Map;
    InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);

    CcpUnlock();
}
Exemplo n.º 5
0
NTSTATUS
DfspProtocolToService(
    IN PDS_TRANSPORT pdsTransport,
    IN PWSTR         pwszPrincipalName,
    IN PWSTR         pwszShareName,
    IN OUT PDFS_SERVICE pService)
{
    NTSTATUS status = STATUS_SUCCESS;
    PTA_ADDRESS pTaddr = &pdsTransport->taddr;
    PTDI_ADDRESS_NETBIOS pNBAddress;
    USHORT i;
    WCHAR    NetBiosAddress[ TDI_ADDRESS_LENGTH_NETBIOS + 1];
    ULONG cbUnused;
    PUNICODE_STRING pServiceAddr;

    DfsDbgTrace(+1, Dbg, "DfspProtocolToService - entered\n", 0);

    //
    // Initialize the service to nulls
    //

    RtlZeroMemory(pService, sizeof(DFS_SERVICE));

    ASSERT(pTaddr->AddressType == TDI_ADDRESS_TYPE_NETBIOS);

    pNBAddress = (PTDI_ADDRESS_NETBIOS) pTaddr->Address;
    ASSERT(pTaddr->AddressLength == sizeof(TDI_ADDRESS_NETBIOS));

    RtlMultiByteToUnicodeN(
        NetBiosAddress,
        sizeof(NetBiosAddress),
        &cbUnused,
        pNBAddress->NetbiosName,
        16);

    //
    // Process a NetBIOS name. Throw away char 16, then ignore the trailing
    // spaces
    //

    for (i = 14; NetBiosAddress[i] == L' '; i--) {
        NOTHING;
    }
    NetBiosAddress[i+1] = UNICODE_NULL;

    DfsDbgTrace(0, Dbg, "NetBIOS address is %ws\n", NetBiosAddress);

    pService->Name.Length = wcslen(pwszPrincipalName) * sizeof(WCHAR);
    pService->Name.MaximumLength = pService->Name.Length +
                                        sizeof(UNICODE_NULL);
    pService->Name.Buffer = ExAllocatePool(
                                PagedPool,
                                pService->Name.MaximumLength);

    if (!pService->Name.Buffer) {
        DfsDbgTrace(0, Dbg, "Unable to create principal name!\n", 0);
        status = STATUS_INSUFFICIENT_RESOURCES;
        DfsDbgTrace(-1, Dbg, "DfsProtocolToService returning %08lx\n", status);
        return(status);
    }

    RtlCopyMemory(pService->Name.Buffer, pwszPrincipalName, pService->Name.Length);

    pService->Address.MaximumLength =
        sizeof(UNICODE_PATH_SEP) +
            pService->Name.Length +
                sizeof(UNICODE_PATH_SEP) +
                    wcslen(pwszShareName) * sizeof(WCHAR) +
                        sizeof(UNICODE_NULL);

    pService->Address.Buffer = ExAllocatePool(
                                    PagedPool,
                                    pService->Address.MaximumLength);

    if (!pService->Address.Buffer) {
        DfsDbgTrace(0, Dbg, "Unable to create address!\n", 0);
        ExFreePool(pService->Name.Buffer);
        pService->Name.Buffer = NULL;
        status = STATUS_INSUFFICIENT_RESOURCES;
        DfsDbgTrace(-1, Dbg, "DfsProtocolToService returning %08lx\n", status);
        return(status);
    }

    pService->Address.Length = sizeof(UNICODE_PATH_SEP);

    pService->Address.Buffer[0] = UNICODE_PATH_SEP;

    DnrConcatenateFilePath(
        &pService->Address,
        pService->Name.Buffer,
        pService->Name.Length);

    DnrConcatenateFilePath(
        &pService->Address,
        pwszShareName,
        (USHORT) (wcslen(pwszShareName) * sizeof(WCHAR)));

    DfsDbgTrace(0, Dbg, "Server Name is %wZ\n", &pService->Name);

    DfsDbgTrace(0, Dbg, "Address is %wZ\n", &pService->Address);

    pService->Type = DFS_SERVICE_TYPE_MASTER | DFS_SERVICE_TYPE_REFERRAL;
    pService->Capability = PROV_DFS_RDR;
    pService->ProviderId = PROV_ID_DFS_RDR;
    pService->pProvider = NULL;

    DfsDbgTrace(-1, Dbg, "DfsProtocolToService returning %08lx\n", status);
    return(status);
}
Exemplo n.º 6
0
NDIS_STATUS
NDISFilterDriverRegisterDevice(OUT PFILTER_DEVICE_EXTENSION *Extension)
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    NDIS_DEVICE_OBJECT_ATTRIBUTES   DeviceAttribute;
    PFILTER_DEVICE_EXTENSION        FilterDeviceExtension;
    PDRIVER_OBJECT                  DriverObject;
   
    DEBUGP(DL_TRACE, "==>NDISFilterDriverRegisterDevice\n");
   
    
    NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
    
    DispatchTable[IRP_MJ_CREATE] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_CLEANUP] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_CLOSE] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_DEVICE_CONTROL] = NDISFilterDriverDeviceIoControl;
    
    
    NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
    NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
    
    //
    // Create a device object and register our dispatch handlers
    //
    NdisZeroMemory(&DeviceAttribute, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));
    
    DeviceAttribute.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
    DeviceAttribute.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
    DeviceAttribute.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);
    
    DeviceAttribute.DeviceName = &DeviceName;
    DeviceAttribute.SymbolicName = &DeviceLinkUnicodeString;
    DeviceAttribute.MajorFunctions = &DispatchTable[0];
    DeviceAttribute.ExtensionSize = sizeof(FILTER_DEVICE_EXTENSION);
    
    Status = NdisRegisterDeviceEx(
                FilterDriverHandle,
                &DeviceAttribute,
                &DeviceObject,
                &NdisFilterDeviceHandle
                );
   
   
    if (Status == NDIS_STATUS_SUCCESS)
    {
		*Extension = FilterDeviceExtension = NdisGetDeviceReservedExtension(DeviceObject);
   
        FilterDeviceExtension->Signature = 'FTDR';
        FilterDeviceExtension->Handle = FilterDriverHandle;
		KeInitializeSpinLock(&FilterDeviceExtension->QLock);
		PRULES_LISTS FilterRules = ExAllocatePool(PagedPool, sizeof(RULES_LISTS));
		FilterRules->IsActive = FALSE;
		FilterRules->FirstRuleIPv4 = NULL;
		FilterRules->FirstRuleIPv6 = NULL;
		FilterDeviceExtension->FilterRules = FilterRules;

        //
        // Workaround NDIS bug
        //
        DriverObject = (PDRIVER_OBJECT)FilterDriverObject;
    }
              
        
    DEBUGP(DL_TRACE, "<==NDISFilterDriverRegisterDevice: %x\n", Status);
        
    return (Status);
        
}
Exemplo n.º 7
0
NTSTATUS
IopApplySystemPartitionProt(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine applies protection to the system partition that
    prevents all users except administrators from accessing the
    partition.


    This routine is only used during system initialization.
    As such, all memory allocations are expected to succeed.
    Success is tested only with assertions.


Arguments:

    LoaderBlock - Supplies a pointer to the loader parameter block that was
        created by the OS Loader.

Return Value:

    The function value is the final status from attempting to set the system
    partition protection.


--*/

{
    NTSTATUS status;
    PACL dacl;
    SECURITY_DESCRIPTOR securityDescriptor;
    OBJECT_ATTRIBUTES objectAttributes;
    ULONG length;
    CHAR ArcNameFmt[12];

    ArcNameFmt[0] = '\\';
    ArcNameFmt[1] = 'A';
    ArcNameFmt[2] = 'r';
    ArcNameFmt[3] = 'c';
    ArcNameFmt[4] = 'N';
    ArcNameFmt[5] = 'a';
    ArcNameFmt[6] = 'm';
    ArcNameFmt[7] = 'e';
    ArcNameFmt[8] = '\\';
    ArcNameFmt[9] = '%';
    ArcNameFmt[10] = 's';
    ArcNameFmt[11] = '\0';

    ASSERT( ARGUMENT_PRESENT( LoaderBlock ) );
    ASSERT( ARGUMENT_PRESENT( LoaderBlock->ArcHalDeviceName ) );

    //
    // Build an appropriate discretionary ACL.
    //

    length = (ULONG) sizeof( ACL ) +
             ( 2 * ((ULONG) sizeof( ACCESS_ALLOWED_ACE ))) +
             SeLengthSid( SeLocalSystemSid ) +
             SeLengthSid( SeAliasAdminsSid ) +
             8; // The 8 is just for good measure

    dacl = (PACL) ExAllocatePool( PagedPool, length );
    if (!dacl) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = RtlCreateAcl( dacl, length, ACL_REVISION2 );
    if (NT_SUCCESS( status )) {

        status = RtlAddAccessAllowedAce( dacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SeLocalSystemSid );
        if (NT_SUCCESS( status )) {

            status = RtlAddAccessAllowedAce( dacl,
                                             ACL_REVISION2,
                                             GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | READ_CONTROL,
                                             SeAliasAdminsSid );
            if (NT_SUCCESS( status )) {

                //
                // Put it in a security descriptor so that it may be applied to
                // the system partition device.
                //

                status = RtlCreateSecurityDescriptor( &securityDescriptor,
                                                      SECURITY_DESCRIPTOR_REVISION );
                if (NT_SUCCESS( status )) {

                    status = RtlSetDaclSecurityDescriptor( &securityDescriptor,
                                                           TRUE,
                                                           dacl,
                                                           FALSE );
                }
            }
        }
    }

    if (!NT_SUCCESS( status )) {
        ExFreePool( dacl );
        return status;
    }

    //
    // Open the ARC boot device and apply the ACL.
    //

    {
        NTSTATUS tmpStatus;
        UCHAR deviceNameBuffer[256];
        STRING deviceNameString;
        UNICODE_STRING deviceNameUnicodeString;
        HANDLE deviceHandle;
        IO_STATUS_BLOCK ioStatusBlock;

        //
        // Begin by formulating the ARC name of the boot device in the ARC
        // name space.
        //

        sprintf( deviceNameBuffer,
                 ArcNameFmt,
                 LoaderBlock->ArcHalDeviceName );

        RtlInitAnsiString( &deviceNameString, deviceNameBuffer );

        status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString,
                                               &deviceNameString,
                                               TRUE );

        if (NT_SUCCESS( status )) {

            InitializeObjectAttributes( &objectAttributes,
                                        &deviceNameUnicodeString,
                                        OBJ_CASE_INSENSITIVE,
                                        NULL,
                                        NULL );

            status = ZwOpenFile( &deviceHandle,
                                 WRITE_DAC,
                                 &objectAttributes,
                                 &ioStatusBlock,
                                 TRUE,
                                 0 );

            RtlFreeUnicodeString( &deviceNameUnicodeString );

            if (NT_SUCCESS( status )) {


                //
                // Apply the ACL built above to the system partition device
                // object.
                //

                status = ZwSetSecurityObject( deviceHandle,
                                              DACL_SECURITY_INFORMATION,
                                              &securityDescriptor );

                tmpStatus = NtClose( deviceHandle );
            }
        }
    }

    //
    // Free the memory used to hold the ACL.
    //

    ExFreePool( dacl );

    return status;
}
Exemplo n.º 8
0
BOOLEAN
IopChangeInterfaceType(
    IN OUT PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
    IN OUT PCM_RESOURCE_LIST *AllocatedResources
    )

/*++

Routine Description:

    This routine takes an Io resourcelist and changes its interfacetype
    from internal to default type (isa or eisa or mca).

Arguments:

    IoResources - Pointer to requirement list.

    AllocatedResources - Pointer to a variable that receives the pointer to the resource list.

Return Value:

    BOOLEAN value to indicates if change made or not.

--*/

{
    PIO_RESOURCE_LIST       IoResourceList;
    PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor;
    PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd;
    LONG                    IoResourceListCount;
    BOOLEAN                 changed;

    ASSERT(AllocatedResources);

    changed = FALSE;

    if (!IoResources) {

        return changed;

    }

    if (IoResources->InterfaceType == Internal) {

        IoResources->InterfaceType = PnpDefaultInterfaceType;
        changed = TRUE;

    }

    IoResourceList = IoResources->List;
    IoResourceListCount = IoResources->AlternativeLists;
    while (--IoResourceListCount >= 0) {

        IoResourceDescriptor = IoResourceList->Descriptors;
        IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count;

        for (;IoResourceDescriptor < IoResourceDescriptorEnd; IoResourceDescriptor++) {

            if (IoResourceDescriptor->Type == CmResourceTypeReserved &&
                IoResourceDescriptor->u.DevicePrivate.Data[0] == Internal) {

                IoResourceDescriptor->u.DevicePrivate.Data[0] = PnpDefaultInterfaceType;
                changed = TRUE;

            }
        }
        IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd;
    }

    if (changed) {

        PCM_RESOURCE_LIST               oldResources = *AllocatedResources;
        PCM_RESOURCE_LIST               newResources;
        PCM_FULL_RESOURCE_DESCRIPTOR    cmFullDesc;
        PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
        ULONG                           size;

        if (oldResources) {

            size = IopDetermineResourceListSize(oldResources);
            newResources = ExAllocatePool(PagedPool, size);
            if (newResources == NULL) {

                changed = FALSE;

            } else {

                ULONG   i;
                ULONG   j;


                RtlCopyMemory(newResources, oldResources, size);

                //
                // Fix up the interface type
                //

                cmFullDesc = &newResources->List[0];
                for (i = 0; i < oldResources->Count; i++) {

                    if (cmFullDesc->InterfaceType == Internal) {

                        cmFullDesc->InterfaceType = PnpDefaultInterfaceType;

                    }
                    cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
                    for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {

                        size = 0;
                        switch (cmPartDesc->Type) {

                        case CmResourceTypeDeviceSpecific:
                            size = cmPartDesc->u.DeviceSpecificData.DataSize;
                            break;

                        }
                        cmPartDesc++;
                        cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
                    }

                    cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
                }

                *AllocatedResources = newResources;
            }
        }
    }

    return changed;
}
Exemplo n.º 9
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);
    }
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
NTSTATUS
IoReportHalResourceUsage(
    IN PUNICODE_STRING HalName,
    IN PCM_RESOURCE_LIST RawResourceList,
    IN PCM_RESOURCE_LIST TranslatedResourceList,
    IN ULONG ResourceListSize
    )

/*++

Routine Description:

    This routine is called by the HAL to report its resources.
    The Hal is the first component to report its resources, so we don't need
    to acquire the resourcemap semaphore, and we do not need to check for
    conflicts.

Arguments:

    HalName - Name of the HAL reporting the resources.

    RawResourceList - Pointer to the HAL's raw resource list.

    TranslatedResourceList - Pointer to the HAL's translated resource list.

    DriverListSize - Value determining the size of the HAL's resource list.

Return Value:

    The status returned is the final completion status of the operation.

--*/

{
    HANDLE keyHandle;
    UNICODE_STRING halString;
    UNICODE_STRING listString;
    NTSTATUS status;

    PAGED_CODE();

    //
    // First open a handle to the RESOURCEMAP key.
    //

    RtlInitUnicodeString( &halString, IopWstrHal );

    status = IopOpenRegistryKey( &keyHandle,
                                 (HANDLE) NULL,
                                 &CmRegistryMachineHardwareResourceMapName,
                                 KEY_READ | KEY_WRITE,
                                 TRUE );

    //
    // Write out the raw resource list
    //

    if (NT_SUCCESS( status )) {

        RtlInitUnicodeString( &listString, IopWstrRaw);

        status = IopWriteResourceList( keyHandle,
                                       &halString,
                                       HalName,
                                       &listString,
                                       RawResourceList,
                                       ResourceListSize );

        //
        // If we successfully wrote out the raw resource list, write out
        // the translated resource list.
        //

        if (NT_SUCCESS( status )) {

            RtlInitUnicodeString( &listString, IopWstrTranslated);
            status = IopWriteResourceList( keyHandle,
                                           &halString,
                                           HalName,
                                           &listString,
                                           TranslatedResourceList,
                                           ResourceListSize );

        }
        ZwClose( keyHandle );
    }

    //
    // If every looks fine, we will make a copy of the Hal resources so will
    // can call Arbiters to reserve the resources after they initialized.
    //

    if (NT_SUCCESS(status)) {
        IopInitHalResources = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool, ResourceListSize);
        if (IopInitHalResources) {
            RtlMoveMemory(IopInitHalResources, RawResourceList, ResourceListSize);
        } else {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    return status;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
void *
mt_malloc(ULONG size, const char *file, ULONG line)
{
	KIRQL irql;
	struct prefix *data;
	struct postfix *pd;

#if 1
	// check pool integrity
	KeAcquireSpinLock(&guard, &irql);
	
	for (data = first; data; data = data->next)
		check(data);
	
	for (data = last; data; data = data->prev)
		check(data);
	
	KeReleaseSpinLock(&guard, irql);
#endif

	if (size == 0) {
		KdPrint(("memtrack: mt_malloc: size == 0!\n"));
		INT_3;
		return NULL;
	}

	data = (struct prefix *)ExAllocatePool(NonPagedPool,
		sizeof(struct prefix) + size + sizeof(struct postfix));
	if (data == NULL)
		return NULL;

	data->magic = MAGIC;
	data->next = NULL;
	data->prev = NULL;
	data->size = size;
	data->file = file;
	data->line = line;

	memset(data->data, 0xcc, size);		// fill by 0xcc: new

	pd = (struct postfix *)(data->data + data->size);

	pd->size = size;
	pd->magic = MAGIC;

	KeAcquireSpinLock(&guard, &irql);
	
	if (last) {
		last->next = data;
		data->prev = last;
		last = data;
	}
	else {
		data->prev = NULL;
		first = last = data;
	}
	count++;

	KeReleaseSpinLock(&guard, irql);
	return data->data;
}
Exemplo n.º 14
0
VOID
NTAPI
StreamClassReenumerateStreams(
    IN PVOID  HwDeviceExtension,
    IN ULONG  StreamDescriptorSize)
{
    HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
    PSTREAM_DEVICE_EXTENSION DeviceExtension;
    PHW_STREAM_DESCRIPTOR StreamDescriptor;

    if (!HwDeviceExtension || !StreamDescriptorSize)
        return;

    StreamDescriptor = ExAllocatePool(NonPagedPool, StreamDescriptorSize);
    if (!StreamDescriptor)
        return;

    /* Zero stream descriptor */
    RtlZeroMemory(StreamDescriptor, StreamDescriptorSize);

    /* Get our DeviceExtension */
    DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
    ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);


    /* Zero RequestBlock */
    RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));

    /* Setup get stream info struct */
    RequestBlock.Block.SizeOfThisPacket = sizeof(HW_STREAM_REQUEST_BLOCK);
    RequestBlock.Block.Command = SRB_GET_STREAM_INFO;
    RequestBlock.Block.CommandData.StreamBuffer = StreamDescriptor;
    KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);

    /* FIXME SYNCHRONIZATION */

    /* Send the request */
    DeviceExtension->DriverExtension->Data.HwReceivePacket ((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);

    /* Is the device already completed? */
    if (RequestBlock.Block.Status == STATUS_PENDING)
    {
        /* Request is pending, wait for result */
        KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
    }

    if (!NT_SUCCESS(RequestBlock.Block.Status))
    {
        /* Release Stream descriptor */
        ExFreePool(StreamDescriptor);
    }
    else
    {
        if (DeviceExtension->StreamDescriptor)
        {
            /* Release old stream descriptor */
            ExFreePool(DeviceExtension->StreamDescriptor);
        }

        /* Store stream descriptor */
        DeviceExtension->StreamDescriptor = StreamDescriptor;
        DeviceExtension->StreamDescriptorSize = StreamDescriptorSize;
    }

}
Exemplo n.º 15
0
VOID
IopSaveBootLogToFile(VOID)
{
    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
    WCHAR ValueNameBuffer[8];
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    HANDLE KeyHandle;
    ULONG BufferSize;
    ULONG ResultLength;
    ULONG i;
    NTSTATUS Status;

    if (IopBootLogCreate == FALSE)
        return;

    DPRINT("IopSaveBootLogToFile() called\n");

    ExAcquireResourceExclusiveLite(&IopBootLogResource, TRUE);

    Status = IopCreateLogFile();
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopCreateLogFile() failed (Status %lx)\n", Status);
        ExReleaseResourceLite(&IopBootLogResource);
        return;
    }

    //Status = IopWriteLogFile(L"ReactOS "KERNEL_VERSION_STR);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopWriteLogFile() failed (Status %lx)\n", Status);
        ExReleaseResourceLite(&IopBootLogResource);
        return;
    }

    Status = IopWriteLogFile(NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopWriteLogFile() failed (Status %lx)\n", Status);
        ExReleaseResourceLite(&IopBootLogResource);
        return;
    }


    BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR);
    KeyInfo = ExAllocatePool(PagedPool,
                             BufferSize);
    if (KeyInfo == NULL)
    {
        ExReleaseResourceLite(&IopBootLogResource);
        return;
    }

    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\System\\CurrentControlSet\\BootLog");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = ZwOpenKey(&KeyHandle,
                       KEY_ALL_ACCESS,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        ExFreePool(KeyInfo);
        ExReleaseResourceLite(&IopBootLogResource);
        return;
    }

    for (i = 0; ; i++)
    {
        swprintf(ValueNameBuffer,
                 L"%lu", i);

        RtlInitUnicodeString(&ValueName,
                             ValueNameBuffer);

        Status = ZwQueryValueKey(KeyHandle,
                                 &ValueName,
                                 KeyValuePartialInformation,
                                 KeyInfo,
                                 BufferSize,
                                 &ResultLength);
        if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
        {
            break;
        }

        if (!NT_SUCCESS(Status))
        {
            ZwClose(KeyHandle);
            ExFreePool(KeyInfo);
            ExReleaseResourceLite(&IopBootLogResource);
            return;
        }

        Status = IopWriteLogFile((PWSTR)&KeyInfo->Data);
        if (!NT_SUCCESS(Status))
        {
            ZwClose(KeyHandle);
            ExFreePool(KeyInfo);
            ExReleaseResourceLite(&IopBootLogResource);
            return;
        }

        /* Delete keys */
        ZwDeleteValueKey(KeyHandle,
                         &ValueName);
    }

    ZwClose(KeyHandle);

    ExFreePool(KeyInfo);

    IopLogFileEnabled = TRUE;
    ExReleaseResourceLite(&IopBootLogResource);

    DPRINT("IopSaveBootLogToFile() done\n");
}
Exemplo n.º 16
0
NTSTATUS
Bus_IoCtl (
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:

    Handle user mode PlugIn, UnPlug and device Eject requests.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

   NT status code

--*/
{
    PIO_STACK_LOCATION      irpStack;
    NTSTATUS                status;
    ULONG                   inlen, outlen;
    PFDO_DEVICE_DATA        fdoData;
    PVOID                   buffer;

    PAGED_CODE ();
    
    fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    //
    // We only take Device Control requests for the FDO.
    // That is the bus itself.
    //

    if (!fdoData->IsFDO) {
    
        //
        // These commands are only allowed to go to the FDO.
        //   
        status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;

    }

    //
    // Check to see whether the bus is removed
    //
    
    if (fdoData->DevicePnPState == Deleted) {
        Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }
    
    Bus_IncIoCount (fdoData);
    
    irpStack = IoGetCurrentIrpStackLocation (Irp);

    buffer			= Irp->AssociatedIrp.SystemBuffer;  
    inlen			= irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outlen			= irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    status = STATUS_INVALID_PARAMETER;

	Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("%d called\n", irpStack->Parameters.DeviceIoControl.IoControlCode));
    switch (irpStack->Parameters.DeviceIoControl.IoControlCode) 
	{

	case IOCTL_LANSCSI_ADD_TARGET:
	{
		PPDO_DEVICE_DATA	pdoData;

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("IOCTL_LANSCSI_ADD_TARGET inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n", inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));

		if ((inlen == outlen) &&
			(sizeof(LANSCSI_ADD_TARGET_DATA) <= inlen)) 
		{
			ULONG						ulSize;
			PLANSCSI_ADD_TARGET_DATA	addTargetData = buffer;
			
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_ADD_TARGET called\n"));
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("IOCTL_LANSCSI_ADD_TARGET Target Type %d\n", addTargetData->ucTargetType));
			
			// Check Parameter.
			switch(addTargetData->ucTargetType) 
			{
			case DISK_TYPE_NORMAL: 
			case DISK_TYPE_DVD: 
			case DISK_TYPE_VDVD: 
			case DISK_TYPE_MO:

				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA);
				if(addTargetData->ulNumberOfUnitDiskList != 1)
				{
					ulSize = 0;	// Exit when Check if(ulSize != inlen)...
				}

				break;

			case DISK_TYPE_MIRROR:

				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA) + sizeof(LSBUS_UNITDISK);
					
				if(2 != addTargetData->ulNumberOfUnitDiskList)
				{
					ulSize = 0;	// Exit when Check if(ulSize != inlen)...
				}

				break;

			case DISK_TYPE_AGGREGATION:

				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA) + 
					sizeof(LSBUS_UNITDISK) * (addTargetData->ulNumberOfUnitDiskList - 1);

				if (addTargetData->ulNumberOfUnitDiskList < 2 || 
					addTargetData->ulNumberOfUnitDiskList > MAX_NR_TC_PER_TARGET) 
				{
					ulSize = 0;	// Exit when Check if(ulSize != inlen)...
				}
				
				break;

			case DISK_TYPE_BIND_RAID0:
				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA) + sizeof(LSBUS_UNITDISK) * (addTargetData->ulNumberOfUnitDiskList - 1);
				switch(addTargetData->ulNumberOfUnitDiskList)
				{
				case 2:
				case 4:
				case 8:
					break;
				default: // do not accept
					ulSize = 0;
					break;
				}
				break;
			case DISK_TYPE_BIND_RAID1:

				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA) + 
					sizeof(LSBUS_UNITDISK) * (addTargetData->ulNumberOfUnitDiskList - 1);
				if (addTargetData->ulNumberOfUnitDiskList < 2 || 
					addTargetData->ulNumberOfUnitDiskList > MAX_NR_TC_PER_TARGET) 
				{
					ulSize = 0;	// Exit when Check if(ulSize != inlen)...
				}
				if (addTargetData->ulNumberOfUnitDiskList % 2) 
				{
					// should be the multiples of 2 
					ulSize = 0;	// Exit when Check if(ulSize != inlen)...
				}

				break;
			case DISK_TYPE_BIND_RAID4:
				ulSize = sizeof(LANSCSI_ADD_TARGET_DATA) + sizeof(LSBUS_UNITDISK) * (addTargetData->ulNumberOfUnitDiskList - 1);
				switch(addTargetData->ulNumberOfUnitDiskList)
				{
				case 3: // 2 + 1
				case 5: // 4 + 1
				case 9: // 8 + 1
					break;
				default: // do not accept
					ulSize = 0;
					break;
				}
				break;
			default:
				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("IOCTL_LANSCSI_ADD_TARGET: Bad Disk Type.\n"));
				status = STATUS_UNSUCCESSFUL;
				break;
			}
						
			// Check Size.
			if(ulSize != inlen) 
			{
				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("IOCTL_LANSCSI_ADD_TARGET: Size mismatch. Req %d, in %d\n", ulSize, inlen));
				status = STATUS_UNSUCCESSFUL;
				break;
			}

			// Find Pdo Data...
			pdoData = LookupPdoData(fdoData, addTargetData->ulSlotNo);
			if(pdoData == NULL) 
			{
				Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
					("no pdo\n"));
				status = STATUS_UNSUCCESSFUL;
				break;
			}

			pdoData->LanscsiAdapterPDO.AddDevInfo = ExAllocatePool(NonPagedPool, inlen);
			
			if(pdoData->LanscsiAdapterPDO.AddDevInfo == NULL) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
			else 
			{
				RtlCopyMemory(pdoData->LanscsiAdapterPDO.AddDevInfo, addTargetData, inlen);
				status = STATUS_SUCCESS;
			}

			pdoData->LanscsiAdapterPDO.AddDevInfoLength = inlen;

			//
			//	Notify to LanscsiMiniport
			//
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("IOCTL_LANSCSI_ADD_TARGET SetEvent AddTargetEvent!\n"));
			KeSetEvent(&pdoData->LanscsiAdapterPDO.AddTargetEvent, IO_NO_INCREMENT, FALSE);

			//
			//	Register Target
			//
			if(pdoData->Persistent) {
				status = LSBus_RegisterTarget(fdoData, addTargetData);
				if(!NT_SUCCESS(status)) {
					Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("ADD_TARGET: LSBus_RegisterTarget() failed. STATUS=%08lx\n", status));
					status = STATUS_INTERNAL_DB_ERROR;
				} else {
					Bus_KdPrint(fdoData, BUS_DBG_IOCTL_INFO, ("ADD_TARGET: Successfully registered.\n"));
				}
			}

			ObDereferenceObject(pdoData->Self);

			Irp->IoStatus.Information = outlen;
		}        
		else
		{
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR,
								("IOCTL_LANSCSI_ADD_TARGET length mismatch!!!"
								" inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
								inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		}

	}
		break;

	case IOCTL_LANSCSI_REMOVE_TARGET:
	{
	    PPDO_DEVICE_DATA	pdoData;
		PLANSCSI_REMOVE_TARGET_DATA	removeTarget;

        Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_REMOVE_TARGET called\n"));

        if (sizeof (LANSCSI_REMOVE_TARGET_DATA) != inlen)
			break;

		removeTarget = (PLANSCSI_REMOVE_TARGET_DATA)buffer;
		pdoData = LookupPdoData(fdoData, removeTarget->ulSlotNo);
		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
						("no pdo\n"));
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		//
		//	redirect to the NDAS SCSI Device
		//
		status = LSBus_IoctlToLSMPDevice(
				pdoData,
				LANSCSIMINIPORT_IOCTL_REMOVE_TARGET,
				buffer,
				sizeof(LANSCSI_REMOVE_TARGET_DATA),
				NULL,
				0
			);

		if(NT_SUCCESS(status) && pdoData->Persistent) {

			status = LSBus_UnregisterTarget(fdoData, removeTarget->ulSlotNo, removeTarget->ulTargetId);
			if(!NT_SUCCESS(status)) {
				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_INFO, (	"REMOVE_TARGET: Removed  Target instance,"
															" but LSBus_UnregisterTarget() failed.\n"));
				status = STATUS_INTERNAL_DB_ERROR;
			}
#if DBG
			else {
				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_INFO, ("REMOVE_TARGET: LSBus_UnregisterTarget() succeeded.\n"));
			}
#endif
		}

		ObDereferenceObject(pdoData->Self);

        Irp->IoStatus.Information = 0;
		break;
	}

	case IOCTL_LANSCSI_RECOVER_TARGET:
	{
	    PPDO_DEVICE_DATA	pdoData;

        Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_RECOVER_TARGET called\n"));

        if (sizeof (LANSCSI_RECOVER_TARGET_DATA) != inlen)
			break;

		pdoData = LookupPdoData(fdoData, ((PLANSCSI_RECOVER_TARGET_DATA)buffer)->ulSlotNo);
		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
						("no pdo\n"));
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		//
		//	redirect to the LanscsiMiniport Device
		//
		status = LSBus_IoctlToLSMPDevice(
				pdoData,
				LANSCSIMINIPORT_IOCTL_RECOVER_TARGET,
				buffer,
				sizeof(LANSCSI_RECOVER_TARGET_DATA),
				NULL,
				0
			);

		ObDereferenceObject(pdoData->Self);

        Irp->IoStatus.Information = outlen;
		break;
	}

	case IOCTL_LANSCSI_REGISTER_DEVICE:
	{

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
							"REGISTER_DEVICE: inlen %d, outlen %d,"
							" sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
							inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		if ((inlen == outlen)) {

			PBUSENUM_PLUGIN_HARDWARE_EX2	PlugIn = buffer;

			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("REGISTER_DEVICE: entered\n"));

			status = LSBus_RegisterDevice(fdoData, PlugIn);

			Irp->IoStatus.Information = 0;
		}
		else
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR,
									("REGISTER_DEVICE: length mismatch!!!"
									" inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));

	}
		break;
	case IOCTL_LANSCSI_REGISTER_TARGET:
	{

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"REGISTER_TARGET: inlen %d, outlen %d,"
									" sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		if ((inlen == outlen)) {

			PLANSCSI_ADD_TARGET_DATA	AddTargetData = buffer;

			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("REGISTER_TARGET: entered\n"));

			status = LSBus_RegisterTarget(fdoData, AddTargetData);

			Irp->IoStatus.Information = 0;
		}
		else {
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"REGISTER_TARGET: length mismatch!!!"
									" inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		}

	}
		break;
	case IOCTL_LANSCSI_UNREGISTER_DEVICE:
	{
		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"UNREGISTER_DEVICE: inlen %d, outlen %d,"
									" sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		if ((inlen == outlen)) {

			PLANSCSI_UNREGISTER_NDASDEV	UnregDev = buffer;

			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("UNREGISTER_DEVICE: entered\n"));

			status = LSBus_UnregisterDevice(fdoData, UnregDev->SlotNo);

			Irp->IoStatus.Information = 0;
		}
		else {
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"UNREGISTER_DEVICE: length mismatch!!!"
									" inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		}
	}
	break;
	case IOCTL_LANSCSI_UNREGISTER_TARGET:
	{
		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"UNREGISTER_TARGET: inlen %d, outlen %d,"
									" sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		if ((inlen == outlen)) {

			PLANSCSI_UNREGISTER_TARGET	UnregTarget = buffer;

			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("UNREGISTER_TARGET: entered\n"));

			status = LSBus_UnregisterTarget(fdoData, UnregTarget->SlotNo, UnregTarget->TargetId);

			Irp->IoStatus.Information = 0;
		}
		else {
			Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, (
									"UNREGISTER_TARGET: length mismatch!!!"
									" inlen %d, outlen %d, sizeof(LANSCSI_ADD_TARGET_DATA) %d\n",
									inlen, outlen, sizeof(LANSCSI_ADD_TARGET_DATA)));
		}
	}
	break;
	case IOCTL_LANSCSI_SETPDOINFO:
		{
	    PPDO_DEVICE_DATA	pdoData;
		PBUSENUM_SETPDOINFO	SetPdoInfo;
		KIRQL				oldIrql;
		PVOID				sectionHandle;

        Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_SETPDOINFO called\n"));

        if (sizeof (BUSENUM_SETPDOINFO) != inlen)
			break;

		SetPdoInfo = (PBUSENUM_SETPDOINFO)buffer;
		pdoData = LookupPdoData(fdoData, (SetPdoInfo)->SlotNo);
		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
						("no pdo\n"));
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		//
		//	lock the code section of this function to acquire spinlock in raised IRQL.
		//
	    sectionHandle = MmLockPagableCodeSection(Bus_IoCtl);

		KeAcquireSpinLock(&pdoData->LanscsiAdapterPDO.LSDevDataSpinLock, &oldIrql);

        Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("!!!!!!!!!!!!!!!!!!  IOCTL_LANSCSI_SETPDOINFO: %08lx %08lx %08lx\n",
										SetPdoInfo->AdapterStatus, SetPdoInfo->DesiredAccess, SetPdoInfo->GrantedAccess));


		//
		//	Set status values to the corresponding physical device object.
		//

		if(ADAPTERINFO_ISSTATUS(SetPdoInfo->AdapterStatus, ADAPTERINFO_STATUS_STOPPING) &&
			ADAPTERINFO_ISSTATUS(pdoData->LanscsiAdapterPDO.AdapterStatus, ADAPTERINFO_STATUS_STOPPED)) {

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_ERROR, ("SETPDOINFO: 'Stopping' event occured after 'Stopped' event\n",
					SetPdoInfo->AdapterStatus, SetPdoInfo->DesiredAccess, SetPdoInfo->GrantedAccess));

		} else {
			pdoData->LanscsiAdapterPDO.AdapterStatus = SetPdoInfo->AdapterStatus;
			pdoData->LanscsiAdapterPDO.DesiredAccess = SetPdoInfo->DesiredAccess;
			pdoData->LanscsiAdapterPDO.GrantedAccess = SetPdoInfo->GrantedAccess;
		}


		KeReleaseSpinLock(&pdoData->LanscsiAdapterPDO.LSDevDataSpinLock, oldIrql);


		//
		//	Release the code section.
		//

	    MmUnlockPagableImageSection(sectionHandle);

		status = STATUS_SUCCESS;
		ObDereferenceObject(pdoData->Self);

        Irp->IoStatus.Information = outlen;
	}
		break;

	case IOCTL_BUSENUM_QUERY_NODE_ALIVE: 
		{

		PPDO_DEVICE_DATA		pdoData;
		BOOLEAN					bAlive;
		PBUSENUM_NODE_ALIVE_IN	pNodeAliveIn;
		BUSENUM_NODE_ALIVE_OUT	nodeAliveOut;

		// Check Parameter.
		if(inlen != sizeof(BUSENUM_NODE_ALIVE_IN) || 
			outlen != sizeof(BUSENUM_NODE_ALIVE_OUT)) {
			status = STATUS_UNKNOWN_REVISION;
			break;
		}
		
		pNodeAliveIn = (PBUSENUM_NODE_ALIVE_IN)Irp->AssociatedIrp.SystemBuffer;  
		
		Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_NOISE,
			("FDO: IOCTL_BUSENUM_QUERY_NODE_ALIVE SlotNumber = %d\n",
			pNodeAliveIn->SlotNo));
		
		pdoData = LookupPdoData(fdoData, pNodeAliveIn->SlotNo);

		if(pdoData == NULL) {
//			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_TRACE,
//				("[LanScsiBus]Bus_IoCtl: IOCTL_BUSENUM_QUERY_NODE_ALIVE No pdo\n"));
			
			bAlive = FALSE;
		} else {
			//
			// Check this PDO would be removed...
			//
			if(pdoData->Present == TRUE) 
				bAlive = TRUE;
			else
				bAlive = FALSE;
		}

		// For Result...
		nodeAliveOut.SlotNo = pNodeAliveIn->SlotNo;
		nodeAliveOut.bAlive = bAlive;
		// Get Adapter Status.
		if(bAlive == TRUE)
		{
			if(	ADAPTERINFO_ISSTATUS(pdoData->LanscsiAdapterPDO.AdapterStatus, ADAPTERINFO_STATUS_IN_ERROR) ||
				ADAPTERINFO_ISSTATUS(pdoData->LanscsiAdapterPDO.AdapterStatus, ADAPTERINFO_STATUS_STOPPING) /*||
				ADAPTERINFO_ISSTATUSFLAG(pdoData->LanscsiAdapterPDO.AdapterStatus, ADAPTERINFO_STATUSFLAG_MEMBER_FAULT) */
				) {

				nodeAliveOut.bHasError = TRUE;
				Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
					("IOCTL_BUSENUM_QUERY_NODE_ALIVE Adapter has Error 0x%x\n", nodeAliveOut.bHasError));
			} else {
				nodeAliveOut.bHasError = FALSE;
			}

		}

		if(pdoData)
			ObDereferenceObject(pdoData->Self);

		RtlCopyMemory(
			Irp->AssociatedIrp.SystemBuffer,
			&nodeAliveOut,
			sizeof(BUSENUM_NODE_ALIVE_OUT)
			);
		
		Irp->IoStatus.Information = sizeof(BUSENUM_NODE_ALIVE_OUT);
		status = STATUS_SUCCESS;
		}
		break;

	//
	//	added by hootch 01172004
	//
	case IOCTL_LANSCSI_UPGRADETOWRITE:
		{
		PPDO_DEVICE_DATA				pdoData;

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_UPGRADETOWRITE called\n"));
		// Check Parameter.
		if(inlen != sizeof(BUSENUM_UPGRADE_TO_WRITE)) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_UPGRADETOWRITE: Invalid input buffer length\n"));
			status = STATUS_UNKNOWN_REVISION;
			break;
		}

		pdoData = LookupPdoData(fdoData, ((PBUSENUM_UPGRADE_TO_WRITE)buffer)->SlotNo);
		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_UPGRADETOWRITE: No pdo for Slotno:%d\n", ((PBUSENUM_UPGRADE_TO_WRITE)buffer)->SlotNo));
			status = STATUS_NO_SUCH_DEVICE;
		} else {
			//
			//	redirect to the LanscsiMiniport Device
			//
			status = LSBus_IoctlToLSMPDevice(
					pdoData,
					LANSCSIMINIPORT_IOCTL_UPGRADETOWRITE,
					buffer,
					inlen,
					buffer,
					outlen
				);

			ObDereferenceObject(pdoData->Self);
		}
		Irp->IoStatus.Information = 0;
	}
		break;

	case IOCTL_LANSCSI_REDIRECT_NDASSCSI:
		{
		PPDO_DEVICE_DATA				pdoData;
		PBUSENUM_REDIRECT_NDASSCSI		redirectIoctl;

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_REDIRECT_NDASSCSI called\n"));
		// Check Parameter.
		if(inlen < sizeof(BUSENUM_REDIRECT_NDASSCSI)) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_REDIRECT_NDASSCSI: Invalid input buffer length\n"));
			status = STATUS_UNKNOWN_REVISION;
			break;
		}

		redirectIoctl = (PBUSENUM_REDIRECT_NDASSCSI)buffer;

		pdoData = LookupPdoData(fdoData, redirectIoctl->SlotNo);
		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_REDIRECT_NDASSCSI: No pdo for Slotno:%d\n", redirectIoctl->SlotNo));
			status = STATUS_NO_SUCH_DEVICE;
		} else {
			//
			//	redirect to the LanscsiMiniport Device
			//
			status = LSBus_IoctlToLSMPDevice(
					pdoData,
					redirectIoctl->IoctlCode,
					redirectIoctl->IoctlData,
					redirectIoctl->IoctlDataSize,
					redirectIoctl->IoctlData,
					redirectIoctl->IoctlDataSize
				);

			ObDereferenceObject(pdoData->Self);
		}
		Irp->IoStatus.Information = 0;
	}
		break;

	case IOCTL_LANSCSI_QUERY_LSMPINFORMATION:
		{
		PPDO_DEVICE_DATA				pdoData;

		Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_QUERY_LSMPINFORMATION called\n"));
		// Check Parameter.
		if(inlen < FIELD_OFFSET(LSMPIOCTL_QUERYINFO, QueryData) ) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_QUERY_LSMPINFORMATION: Invalid input buffer length too small.\n"));
			status = STATUS_UNKNOWN_REVISION;
			break;
		}
		pdoData = LookupPdoData(fdoData, ((PLSMPIOCTL_QUERYINFO)buffer)->SlotNo);

		if(pdoData == NULL) {
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("IOCTL_LANSCSI_QUERY_LSMPINFORMATION No pdo\n"));
			status = STATUS_NO_SUCH_DEVICE;
		} else {
			//
			//	redirect to the LanscsiMiniport Device
			//
			status = LSBus_IoctlToLSMPDevice(
					pdoData,
					LANSCSIMINIPORT_IOCTL_QUERYINFO_EX,
					buffer,
					inlen,
					buffer,
					outlen
				);

			ObDereferenceObject(pdoData->Self);
		}
        Irp->IoStatus.Information = outlen;
		}
		break;

	case IOCTL_BUSENUM_QUERY_INFORMATION:
		{

//		PPDO_DEVICE_DATA				pdoData;
		BUSENUM_QUERY_INFORMATION		Query;
		PBUSENUM_INFORMATION			Information;
		LONG							BufferLenNeeded;

		// Check Parameter.
		if(	inlen < sizeof(BUSENUM_QUERY_INFORMATION) /*|| 
			outlen < sizeof(BUSENUM_INFORMATION) */) {
			status = STATUS_UNKNOWN_REVISION;
			break;
		}

		RtlCopyMemory(&Query, buffer, sizeof(BUSENUM_QUERY_INFORMATION));
		Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_TRACE,
			("FDO: IOCTL_BUSENUM_QUERY_INFORMATION QueryType : %d  SlotNumber = %d\n",
			Query.InfoClass, Query.SlotNo));

		Information = (PBUSENUM_INFORMATION)buffer;
		ASSERT(Information);
		Information->InfoClass = Query.InfoClass;
		status = LSBus_QueryInformation(fdoData, &Query, Information, outlen, &BufferLenNeeded);
		if(NT_SUCCESS(status)) {
			Information->Size = BufferLenNeeded;
			Irp->IoStatus.Information = BufferLenNeeded;
		} else {
			Irp->IoStatus.Information = BufferLenNeeded;
		}
		}
		break;

	case IOCTL_BUSENUM_PLUGIN_HARDWARE_EX:
		{
			if ((inlen == outlen) &&
				//
				// Make sure it has at least two nulls and the size 
				// field is set to the declared size of the struct
				//
				((sizeof (BUSENUM_PLUGIN_HARDWARE_EX) + sizeof(UNICODE_NULL) * 2) <=
				inlen) &&

				//
				// The size field should be set to the sizeof the struct as declared
				// and *not* the size of the struct plus the multi_sz
				//
				(sizeof (BUSENUM_PLUGIN_HARDWARE_EX) ==
				((PBUSENUM_PLUGIN_HARDWARE_EX) buffer)->Size)) {

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("PlugIn called\n"));

				status= Bus_PlugInDeviceEx((PBUSENUM_PLUGIN_HARDWARE_EX)buffer,
											inlen, fdoData, Irp->RequestorMode);
	           
				Irp->IoStatus.Information = outlen;

			}
		}
        break;

	case IOCTL_BUSENUM_PLUGIN_HARDWARE_EX2:
		{
			if ((inlen == outlen) &&
				//
				// Make sure it has at least two nulls and the size 
				// field is set to the declared size of the struct
				//
				((sizeof (BUSENUM_PLUGIN_HARDWARE_EX2) + sizeof(UNICODE_NULL) * 2) <=
				inlen) &&

				//
				// The size field should be set to the sizeof the struct as declared
				// and *not* the size of the struct plus the multi_sz
				//
				(sizeof (BUSENUM_PLUGIN_HARDWARE_EX2) ==
				((PBUSENUM_PLUGIN_HARDWARE_EX2) buffer)->Size)) {

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("PlugIn called\n"));

				status= Bus_PlugInDeviceEx2((PBUSENUM_PLUGIN_HARDWARE_EX2)buffer,
											inlen, fdoData, Irp->RequestorMode, FALSE);

				Irp->IoStatus.Information = outlen;

			}
		}
        break;

	case IOCTL_LANSCSI_GETVERSION:
		{
			if (outlen >= sizeof(BUSENUM_GET_VERSION)) {
				PBUSENUM_GET_VERSION version = (PBUSENUM_GET_VERSION)buffer;

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("IOCTL_LANSCSI_GETVERSION: called\n"));

			try {
				version->VersionMajor = VER_FILEMAJORVERSION;
				version->VersionMinor = VER_FILEMINORVERSION;
				version->VersionBuild = VER_FILEBUILD;
				version->VersionPrivate = VER_FILEBUILD_QFE;

					Irp->IoStatus.Information = sizeof(BUSENUM_GET_VERSION);
					status = STATUS_SUCCESS;

				} except (EXCEPTION_EXECUTE_HANDLER) {

					status = GetExceptionCode();
					Irp->IoStatus.Information = 0;
				}

			}
		}			
		break;

    case IOCTL_BUSENUM_UNPLUG_HARDWARE:
		{
			if ((sizeof (BUSENUM_UNPLUG_HARDWARE) == inlen) &&
				(inlen == outlen) &&
				(((PBUSENUM_UNPLUG_HARDWARE)buffer)->Size == inlen)) {

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("UnPlug called\n"));

				status= Bus_UnPlugDevice(
						(PBUSENUM_UNPLUG_HARDWARE)buffer, fdoData);
				Irp->IoStatus.Information = outlen;

			}
		}
        break;

    case IOCTL_BUSENUM_EJECT_HARDWARE:
		{
			if ((sizeof (BUSENUM_EJECT_HARDWARE) == inlen) &&
				(inlen == outlen) &&
				(((PBUSENUM_EJECT_HARDWARE)buffer)->Size == inlen)) {

				Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("Eject called\n"));

				status= Bus_EjectDevice((PBUSENUM_EJECT_HARDWARE)buffer, fdoData);

				Irp->IoStatus.Information = outlen;
			}
		}
		break;

	case IOCTL_DVD_GET_STATUS:
		{
			PPDO_DEVICE_DATA		pdoData;
			PBUSENUM_DVD_STATUS		pDvdStatusData;


			// Check Parameter.
			if((inlen != outlen)
				|| (sizeof(BUSENUM_DVD_STATUS) >  inlen))
			{
				status = STATUS_UNSUCCESSFUL ;
				break;
			}
			
			pDvdStatusData = (PBUSENUM_DVD_STATUS)Irp->AssociatedIrp.SystemBuffer;  
			
			Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
				("FDO: IOCTL_DVD_GET_STATUS SlotNumber = %d\n",
				pDvdStatusData->SlotNo));	

			pdoData = LookupPdoData(fdoData, pDvdStatusData->SlotNo);
			
			if(pdoData == NULL) {
				Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
					("IOCTL_DVD_GET_STATUS No pdo\n"));
				status = STATUS_UNSUCCESSFUL;
				break;	
			} else {

				if(pdoData->LanscsiAdapterPDO.Flags & LSDEVDATA_FLAG_LURDESC) {
					//
					//	A LUR descriptor is set.
					//
					if(((PLURELATION_DESC)pdoData->LanscsiAdapterPDO.AddDevInfo)->DevType != DISK_TYPE_DVD)
				{
					Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
						("IOCTL_DVD_GET_STATUS  No DVD Device\n"));
					status = STATUS_UNSUCCESSFUL;
					break;
				}
				} else {
					//
					//	ADD_TARGET_DATA is set.
					//
					if(((PLANSCSI_ADD_TARGET_DATA)pdoData->LanscsiAdapterPDO.AddDevInfo)->ucTargetType != DISK_TYPE_DVD)
					{
						Bus_KdPrint_Cont (fdoData, BUS_DBG_IOCTL_ERROR,
							("IOCTL_DVD_GET_STATUS  No DVD Device\n"));
						status = STATUS_UNSUCCESSFUL;
						break;
					}
				}
				//
				//	redirect to the LanscsiMiniport Device
				//
				status = LSBus_IoctlToLSMPDevice(
						pdoData,
						LANSCSIMINIPORT_IOCTL_GET_DVD_STATUS,
						buffer,
						inlen,
						buffer,
						outlen
					);

				ObDereferenceObject(pdoData->Self);
				status = STATUS_SUCCESS;
				Irp->IoStatus.Information = outlen;
			}					
		}
		break;
    default:
        break; // default status is STATUS_INVALID_PARAMETER
    }
Exemplo n.º 17
0
_Use_decl_annotations_                
NTSTATUS
NDISFilterDriverDeviceIoControl(
    PDEVICE_OBJECT        DeviceObject,
    PIRP                  Irp
    )
{
	DbgPrint("NDISFilterDriverDeviceIoControl\n");
    PIO_STACK_LOCATION          IrpSp;
    NTSTATUS                    Status = STATUS_SUCCESS;
    PFILTER_DEVICE_EXTENSION    FilterDeviceExtension;
    PUCHAR                      InputBuffer;
    PUCHAR                      OutputBuffer;
    ULONG                       InputBufferLength, OutputBufferLength;
    PLIST_ENTRY                 Link;
    PUCHAR                      pInfo;
    ULONG                       InfoLength = 0;
    PMS_FILTER                  pFilter = NULL;
    BOOLEAN                     bFalse = FALSE;


    UNREFERENCED_PARAMETER(DeviceObject);

	KIRQL OldIrql;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    if (IrpSp->FileObject == NULL)
    {
        return(STATUS_UNSUCCESSFUL);
    }


    FilterDeviceExtension = (PFILTER_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(DeviceObject);

    ASSERT(FilterDeviceExtension->Signature == 'FTDR');
    
    Irp->IoStatus.Information = 0;

	KeAcquireSpinLock(&FilterDeviceExtension->QLock, &OldIrql);
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
    {
		case IOCTL_ADD_IPV4_RULE:
			DbgPrint("IOCTL_ADD_IPV4_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(RULE_IPV4))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			PRULE_IPV4 pRuleIPv4 = ExAllocatePool(NonPagedPool, sizeof(RULE_IPV4));
			RtlCopyMemory(pRuleIPv4, InputBuffer, InputBufferLength);
			AddIPv4Rule(FilterDeviceExtension, pRuleIPv4);
			DbgPrint("IOCTL_ADD_IPV4_RULE END\n");
			break;
		case IOCTL_DEL_IPV4_RULE:
			DbgPrint("IOCTL_DEL_IPV4_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(ULONG))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ULONG IdIPv4 = *((PULONG)(InputBuffer));
			DelIPv4Rule(FilterDeviceExtension, IdIPv4);
			DbgPrint("IOCTL_DEL_IPV4_RULE END\n");
			break;
		case IOCTL_ADD_IPV6_RULE:
			DbgPrint("IOCTL_ADD_IPV6_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(RULE_IPV6))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			PRULE_IPV6 pRuleIPv6 = ExAllocatePool(NonPagedPool, sizeof(RULE_IPV6));
			RtlCopyMemory(pRuleIPv6, InputBuffer, InputBufferLength);
			AddIPv6Rule(FilterDeviceExtension, pRuleIPv6);
			DbgPrint("IOCTL_ADD_IPV6_RULE END\n");
			break;
		case IOCTL_DEL_IPV6_RULE:
			DbgPrint("IOCTL_DEL_IPV6_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(ULONG))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ULONG IdIPv6 = *((PULONG)(InputBuffer));
			DelIPv6Rule(FilterDeviceExtension, IdIPv6);
			DbgPrint("IOCTL_END_IPV6_RULE END\n");
			break;
		case IOCTL_ACTIVATE_FILTER:
			DbgPrint("IOCTL_ACTIVATE_FILTER BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != 0)
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ActivateRules(FilterDeviceExtension);
			DbgPrint("IOCTL_ACTIVATE_FILTER END\n");
			break;
		case IOCTL_DEACTIVATE_FILTER:
			DbgPrint("IOCTL_DEACTIVATE_FILTER BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != 0)
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			DeactivateRules(FilterDeviceExtension);
			DbgPrint("IOCTL_DEACTIVATE_FILTER END\n");
			break;
        case IOCTL_FILTER_RESTART_ALL:
            break;

        case IOCTL_FILTER_RESTART_ONE_INSTANCE:
            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;

            pFilter = filterFindFilterModule (InputBuffer, InputBufferLength);

            if (pFilter == NULL)
            {
                
                break;
            }

            NdisFRestartFilter(pFilter->FilterHandle);

            break;

        case IOCTL_FILTER_ENUERATE_ALL_INSTANCES:
            
            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
            OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
            
            
            pInfo = OutputBuffer;
            
            FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
            
            Link = FilterModuleList.Flink;
            
            while (Link != &FilterModuleList)
            {
                pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink);

                
                InfoLength += (pFilter->FilterModuleName.Length + sizeof(USHORT));
                        
                if (InfoLength <= OutputBufferLength)
                {
                    *(PUSHORT)pInfo = pFilter->FilterModuleName.Length;
                    NdisMoveMemory(pInfo + sizeof(USHORT), 
                                   (PUCHAR)(pFilter->FilterModuleName.Buffer),
                                   pFilter->FilterModuleName.Length);
                            
                    pInfo += (pFilter->FilterModuleName.Length + sizeof(USHORT));
                }
                
                Link = Link->Flink;
            }
               
            FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
            if (InfoLength <= OutputBufferLength)
            {
       
                Status = NDIS_STATUS_SUCCESS;
            }
            //
            // Buffer is small
            //
            else
            {
                Status = STATUS_BUFFER_TOO_SMALL;
            }
            break;

             
        default:
            break;
    }
	KeReleaseSpinLock(&FilterDeviceExtension->QLock, OldIrql);
    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = InfoLength;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
            

}
Exemplo n.º 18
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);
}
Exemplo n.º 19
0
/****************************************************************************
PARAMETERS:
szKey       - Key to query (can contain version number formatting)
szValue     - Value to get information for
value       - Place to store the registry key data read
size        - Size of the string buffer to read into

RETURNS:
true if the key was found, false if not.
****************************************************************************/
ibool REG_queryString(
    char *szKey,
    const char *szValue,
    char *value,
    DWORD size)
{
    ibool                           status;
    NTSTATUS                        rval;
    ULONG                           length;
    HANDLE                          Handle;
    OBJECT_ATTRIBUTES               keyAttributes;
    UNICODE_STRING                  *uniKey = NULL;
    UNICODE_STRING                  *uniValue = NULL;
    PKEY_VALUE_FULL_INFORMATION     fullInfo = NULL;
    STRING                          stringdata;
    UNICODE_STRING                  unidata;

    // Convert strings to UniCode
    status = false;
    if ((uniKey = _PM_CStringToUnicodeString(szKey)) == NULL)
        goto Exit;
    if ((uniValue = _PM_CStringToUnicodeString(szValue)) == NULL)
        goto Exit;

    // Open the key
    InitializeObjectAttributes( &keyAttributes,
                                uniKey,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL );
    rval = ZwOpenKey( &Handle,
                      KEY_ALL_ACCESS,
                      &keyAttributes );
    if (!NT_SUCCESS(rval))
        goto Exit;

    // Query the value
    length = sizeof (KEY_VALUE_FULL_INFORMATION)
           + size * sizeof(WCHAR);
    if ((fullInfo = ExAllocatePool (PagedPool, length)) == NULL)
        goto Exit;
    RtlZeroMemory(fullInfo, length);
    rval = ZwQueryValueKey (Handle,
                            uniValue,
                            KeyValueFullInformation,
                            fullInfo,
                            length,
                            &length);
    if (NT_SUCCESS (rval)) {
        // Create the UniCode string so we can convert it
        unidata.Buffer = (PWCHAR)(((PCHAR)fullInfo) + fullInfo->DataOffset);
        unidata.Length = (USHORT)fullInfo->DataLength;
        unidata.MaximumLength = (USHORT)fullInfo->DataLength + sizeof(WCHAR);

        // Convert unicode univalue to ansi string.
        rval = RtlUnicodeStringToAnsiString(&stringdata, &unidata, TRUE);
        if (NT_SUCCESS(rval)) {
            strcpy(value,stringdata.Buffer);
            status = true;
            }
        }

Exit:
    if (fullInfo) ExFreePool(fullInfo);
    if (uniKey) _PM_FreeUnicodeString(uniKey);
    if (uniValue) _PM_FreeUnicodeString(uniValue);
    return status;
}
Exemplo n.º 20
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;
  }
}
Exemplo n.º 21
0
static
NTSTATUS
FdcFdoQueryBusRelations(
    IN PDEVICE_OBJECT DeviceObject,
    OUT PDEVICE_RELATIONS *DeviceRelations)
{
    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
    INTERFACE_TYPE InterfaceType = Isa;
    CONFIGURATION_TYPE ControllerType = DiskController;
    CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
    PDEVICE_RELATIONS Relations;
    PDRIVE_INFO DriveInfo;
    PDEVICE_OBJECT Pdo;
    WCHAR DeviceNameBuffer[80];
    UNICODE_STRING DeviceName;
    ULONG DeviceNumber = 0;
    ULONG Size;
    ULONG i;
    NTSTATUS Status;

    DPRINT1("FdcFdoQueryBusRelations() called\n");

    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    Status = IoQueryDeviceDescription(&InterfaceType,
                                      NULL,
                                      &ControllerType,
                                      NULL,
                                      &PeripheralType,
                                      NULL,
                                      FdcFdoConfigCallback,
                                      FdoDeviceExtension);
    if (!NT_SUCCESS(Status) && (Status != STATUS_NO_MORE_ENTRIES))
        return Status;

    Size = sizeof(DEVICE_RELATIONS) +
           sizeof(Relations->Objects) * (FdoDeviceExtension->ControllerInfo.NumberOfDrives - 1);
    Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
    if (Relations == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Relations->Count = FdoDeviceExtension->ControllerInfo.NumberOfDrives;

    for (i = 0; i < FdoDeviceExtension->ControllerInfo.NumberOfDrives; i++)
    {
        DriveInfo = &FdoDeviceExtension->ControllerInfo.DriveInfo[i];

        if (DriveInfo->DeviceObject == NULL)
        {
            do
            {
                swprintf(DeviceNameBuffer, L"\\Device\\FloppyPDO%lu", DeviceNumber++);
                RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
                DPRINT1("Device name: %S\n", DeviceNameBuffer);

                /* Create physical device object */
                Status = IoCreateDevice(FdoDeviceExtension->Common.DeviceObject->DriverObject,
                                        sizeof(PDO_DEVICE_EXTENSION),
                                        &DeviceName,
                                        FILE_DEVICE_MASS_STORAGE,
                                        FILE_DEVICE_SECURE_OPEN,
                                        FALSE,
                                        &Pdo);
            }
            while (Status == STATUS_OBJECT_NAME_COLLISION);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("PDO creation failed (Status 0x%08lx)\n", Status);
                goto done;
            }

            DPRINT1("PDO created: %S\n", DeviceNameBuffer);

            DriveInfo->DeviceObject = Pdo;

            PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
            RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));

            PdoDeviceExtension->Common.IsFDO = FALSE;
            PdoDeviceExtension->Common.DeviceObject = Pdo;

            PdoDeviceExtension->Fdo = FdoDeviceExtension->Common.DeviceObject;
            PdoDeviceExtension->DriveInfo = DriveInfo;

            Pdo->Flags |= DO_DIRECT_IO;
            Pdo->Flags |= DO_POWER_PAGABLE;
            Pdo->Flags &= ~DO_DEVICE_INITIALIZING;

            /* Add Device ID string */
            RtlCreateUnicodeString(&PdoDeviceExtension->DeviceId,
                                   L"FDC\\GENERIC_FLOPPY_DRIVE");
            DPRINT1("DeviceID: %S\n", PdoDeviceExtension->DeviceId.Buffer);

            /* Add Hardware IDs string */
            Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIds);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add Compatible IDs string */
            Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIds);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add Instance ID string */
            Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceId,
                                               DriveInfo->PeripheralNumber);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

#if 0
             /* Add device description string */
            Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }

            /* Add device location string */
            Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
            if (!NT_SUCCESS(Status))
            {
//                ErrorStatus = Status;
//                ErrorOccurred = TRUE;
                break;
            }
#endif
        }

        ObReferenceObject(DriveInfo->DeviceObject);
        Relations->Objects[i] = DriveInfo->DeviceObject;
    }

done:
    if (NT_SUCCESS(Status))
    {
        *DeviceRelations = Relations;
    }
    else
    {
        if (Relations != NULL)
            ExFreePool(Relations);
    }

    return Status;
}
Exemplo n.º 22
0
NDIS_STATUS
ProIndicatePacket(
    PLOGICAL_ADAPTER Adapter,
    PNDIS_PACKET Packet)
/*
 * FUNCTION: Indicates a packet to bound protocols
 * ARGUMENTS:
 *     Adapter = Pointer to logical adapter
 *     Packet  = Pointer to packet to indicate
 * RETURNS:
 *     STATUS_SUCCESS in all cases
 * NOTES:
 *     - XXX ATM, this only handles loopback packets - is that its designed function?
 */
{
  UINT BufferedLength;
  UINT PacketLength;
  KIRQL OldIrql;
  PUCHAR LookaheadBuffer;

  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));

#if DBG
  MiniDisplayPacket(Packet);
#endif

  NdisQueryPacket(Packet, NULL, NULL, NULL, &PacketLength);

  LookaheadBuffer = ExAllocatePool(NonPagedPool, PacketLength);
  if (!LookaheadBuffer) {
      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
      return NDIS_STATUS_RESOURCES;
  }

  NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
  KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
    {
      BufferedLength = CopyPacketToBuffer(LookaheadBuffer, Packet, 0, PacketLength);
      Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()] = Packet;
    }
  KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);

  if (BufferedLength > Adapter->MediumHeaderSize)
    {
      /* XXX Change this to call SendPackets so we don't have to duplicate this wacky logic */
      MiniIndicateData(Adapter, NULL, LookaheadBuffer, Adapter->MediumHeaderSize,
          &LookaheadBuffer[Adapter->MediumHeaderSize], BufferedLength - Adapter->MediumHeaderSize,
          PacketLength - Adapter->MediumHeaderSize);
    }
  else
    {
      MiniIndicateData(Adapter, NULL, LookaheadBuffer, Adapter->MediumHeaderSize, NULL, 0, 0);
    }

  ExFreePool(LookaheadBuffer);

  KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
    {
      Adapter->NdisMiniportBlock.IndicatedPacket[KeGetCurrentProcessorNumber()] = NULL;
    }
  KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);

  return NDIS_STATUS_SUCCESS;
}
Exemplo n.º 23
0
/*

This could be implemented much more intelligently by mapping instances
of a CoW zero page into the affected regions.  We just RtlZeroMemory
for now.

*/
BOOLEAN
NTAPI
CcZeroData(IN PFILE_OBJECT FileObject,
           IN PLARGE_INTEGER StartOffset,
           IN PLARGE_INTEGER EndOffset,
           IN BOOLEAN Wait)
{
    PNOCC_BCB Bcb = NULL;
    PLIST_ENTRY ListEntry = NULL;
    LARGE_INTEGER LowerBound = *StartOffset;
    LARGE_INTEGER UpperBound = *EndOffset;
    LARGE_INTEGER Target, End;
    PVOID PinnedBcb, PinnedBuffer;
    PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;

    DPRINT("S %I64x E %I64x\n",
           StartOffset->QuadPart,
           EndOffset->QuadPart);

    if (!Map)
    {
        NTSTATUS Status;
        IO_STATUS_BLOCK IOSB;
        PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
        ULONG ToWrite;

        if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
        DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
        RtlZeroMemory(ZeroBuf, PAGE_SIZE);

        Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
        End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);

        // Handle leading page
        if (LowerBound.QuadPart != Target.QuadPart)
        {
            ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
                          (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));

            DPRINT("Zero last half %I64x %lx\n",
                   Target.QuadPart,
                   ToWrite);

            Status = MiSimpleRead(FileObject,
                                  &Target,
                                  ZeroBuf,
                                  PAGE_SIZE,
                                  TRUE,
                                  &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }

            DPRINT1("RtlZeroMemory(%p, %lx)\n",
                    ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
                    ToWrite);

            RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
                          ToWrite);

            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   MIN(PAGE_SIZE,
                                       UpperBound.QuadPart-Target.QuadPart),
                                   &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
        RtlZeroMemory(ZeroBuf, PAGE_SIZE);

        while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
        {
            DPRINT("Zero full page %I64x\n",
                   Target.QuadPart);

            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   PAGE_SIZE,
                                   &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        if (UpperBound.QuadPart > Target.QuadPart)
        {
            ToWrite = UpperBound.QuadPart - Target.QuadPart;
            DPRINT("Zero first half %I64x %lx\n",
                   Target.QuadPart,
                   ToWrite);

            Status = MiSimpleRead(FileObject,
                                  &Target,
                                  ZeroBuf,
                                  PAGE_SIZE,
                                  TRUE,
                                  &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
            RtlZeroMemory(ZeroBuf, ToWrite);
            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   MIN(PAGE_SIZE,
                                       UpperBound.QuadPart-Target.QuadPart),
                                   &IOSB);
            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        ExFreePool(ZeroBuf);
        return TRUE;
    }

    CcpLock();
    ListEntry = Map->AssociatedBcb.Flink;

    while (ListEntry != &Map->AssociatedBcb)
    {
        Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
        CcpReferenceCache(Bcb - CcCacheSections);

        if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
            Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
        {
            DPRINT("Bcb #%x (@%I64x)\n",
                   Bcb - CcCacheSections,
                   Bcb->FileOffset.QuadPart);

            Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
                                  LowerBound.QuadPart);

            End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
                               UpperBound.QuadPart);

            End.QuadPart = MIN(End.QuadPart,
                               Bcb->FileOffset.QuadPart + Bcb->Length);

            CcpUnlock();

            if (!CcPreparePinWrite(FileObject,
                                   &Target,
                                   End.QuadPart - Target.QuadPart,
                                   TRUE,
                                   Wait,
                                   &PinnedBcb,
                                   &PinnedBuffer))
            {
                return FALSE;
            }

            ASSERT(PinnedBcb == Bcb);

            CcpLock();
            ListEntry = ListEntry->Flink;
            /* Return from pin state */
            CcpUnpinData(PinnedBcb, TRUE);
        }

        CcpUnpinData(Bcb, TRUE);
    }

    CcpUnlock();

    return TRUE;
}
Exemplo n.º 24
0
NDIS_STATUS NTAPI
ProSend(
    IN  NDIS_HANDLE     MacBindingHandle,
    IN  PNDIS_PACKET    Packet)
/*
 * FUNCTION: Forwards a request to send a packet to an NDIS miniport
 * ARGUMENTS:
 *     MacBindingHandle = Adapter binding handle
 *     Packet           = Pointer to NDIS packet descriptor
 * RETURNS:
 *     NDIS_STATUS_SUCCESS if the packet was successfully sent
 *     NDIS_STATUS_PENDING if the miniport was busy or a serialized miniport returned NDIS_STATUS_RESOURCES
 */
{
  PADAPTER_BINDING AdapterBinding;
  PLOGICAL_ADAPTER Adapter;
  PNDIS_BUFFER NdisBuffer;
  PDMA_CONTEXT Context;
  NDIS_STATUS NdisStatus;
  UINT PacketLength;
  KIRQL OldIrql;

  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));

  ASSERT(MacBindingHandle);
  AdapterBinding = GET_ADAPTER_BINDING(MacBindingHandle);

  ASSERT(AdapterBinding);
  Adapter = AdapterBinding->Adapter;

  ASSERT(Adapter);

  /* if the following is not true, KeRaiseIrql() below will break */
  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

  /* XXX what is this crazy black magic? */
  Packet->Reserved[1] = (ULONG_PTR)MacBindingHandle;

  /*
   * Test the packet to see if it is a MAC loopback.
   *
   * We may have to loop this packet if miniport cannot.
   * If dest MAC address of packet == MAC address of adapter,
   * this is a loopback frame.
   */

  if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) &&
      MiniAdapterHasAddress(Adapter, Packet))
    {
#if WORKER_TEST
        MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet, FALSE);
        return NDIS_STATUS_PENDING;
#else
        return ProIndicatePacket(Adapter, Packet);
#endif
    } else {
        if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0)
        {
            NDIS_DbgPrint(MID_TRACE, ("Using Scatter/Gather DMA\n"));

            NdisQueryPacket(Packet,
                            NULL,
                            NULL,
                            &NdisBuffer,
                            &PacketLength);

            Context = ExAllocatePool(NonPagedPool, sizeof(DMA_CONTEXT));
            if (!Context) {
                NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
                return NDIS_STATUS_RESOURCES;
            }

            Context->Adapter = Adapter;
            Context->Packet = Packet;

            KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);

            KeFlushIoBuffers(NdisBuffer, FALSE, TRUE);

            NdisStatus = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->GetScatterGatherList(
                          Adapter->NdisMiniportBlock.SystemAdapterObject,
                          Adapter->NdisMiniportBlock.PhysicalDeviceObject,
                          NdisBuffer,
                          MmGetMdlVirtualAddress(NdisBuffer),
                          PacketLength,
                          ScatterGatherSendPacket,
                          Context,
                          TRUE);

            KeLowerIrql(OldIrql);

            if (!NT_SUCCESS(NdisStatus)) {
                NDIS_DbgPrint(MIN_TRACE, ("GetScatterGatherList failed! (%x)\n", NdisStatus));
                return NdisStatus;
            }

            return NDIS_STATUS_PENDING;
        }


        return proSendPacketToMiniport(Adapter, Packet);
    }
}
Exemplo n.º 25
0
//+----------------------------------------------------------------------------
//
//  Function:   DfspSvcListFromGluon
//
//  Synopsis:   Creates a service list corresponding to the list of DS_MACHINEs
//              in a gluon. For each Service that this function creates it will
//              strip the relevant DS_MACHINE structure from the gluon.
//
//  Arguments:
//
//  Returns:    No error code. But if for some reason one of the services is
//              not created then there can be less SERVICES than the DS_MACHINEs
//              passed in.
//
//-----------------------------------------------------------------------------
VOID
DfspSvcListFromGluon(
    PDFS_PKT_ENTRY_INFO pServiceInfo,
    PDFS_SERVICE        *ppActiveService,
    PDS_GLUON           pGluon
)
{
    ULONG       i, j, k;
    NTSTATUS    status;

    *ppActiveService = NULL;

    //
    // We'll traverse through each machine and each transport, and wean
    // out the netbios names to create DFS_SERVICE structures.
    //

    for (i=0, j=0; i < pGluon->cMachines; i++) {
        PDS_MACHINE     pdsMachine;

        pdsMachine = pGluon->rpMachines[i];

        for (k=0; k < pdsMachine->cTransports; k++) {
            PDS_TRANSPORT pdsTransport;

            pdsTransport = pdsMachine->rpTrans[k];

            //
            // Support only SMB redir with NetBIOS addresses for now.
            //

            if (    pdsTransport->usFileProtocol == FSP_SMB

                                    &&

                    pdsTransport->taddr.AddressType == TDI_ADDRESS_TYPE_NETBIOS) {

                ASSERT(j <= pGluon->cMachines);

                status = DfspProtocolToService(
                            pdsTransport,
                            pdsMachine->prgpwszPrincipals[pdsTransport->iPrincipal],
                            pdsMachine->pwszShareName,
                            &pServiceInfo->ServiceList[j]);

                if (NT_SUCCESS(status)) {
                    pServiceInfo->ServiceList[j].pMachEntry =
                        ExAllocatePool( PagedPool, sizeof(DFS_MACHINE_ENTRY) );
                    if (pServiceInfo->ServiceList[j].pMachEntry == NULL) {
                        status = STATUS_INSUFFICIENT_RESOURCES;
                    } else {
                        RtlZeroMemory(
                            (PVOID) pServiceInfo->ServiceList[j].pMachEntry,
                            sizeof(DFS_MACHINE_ENTRY));
                    }
                }
                if (NT_SUCCESS(status)) {
                    DfsDbgTrace(0, Dbg, "Added service # %d\n", j);
                    DfsDbgTrace(0, Dbg, "Name = %wZ\n",
                                &pServiceInfo->ServiceList[j].Name);
                    DfsDbgTrace(0, Dbg, "Address = %wZ\n",
                                &pServiceInfo->ServiceList[j].Address);
                    pServiceInfo->ServiceList[j].pMachEntry->pMachine = pdsMachine;
                    pServiceInfo->ServiceList[j].pMachEntry->UseCount = 1;

                    //
                    // Now strip the pdsMachine Structure from Gluon.
                    //
                    pGluon->rpMachines[i] = NULL;

                    //
                    // DfsSetDomainInfo in api\gluonapi.c sets the grfFlags
                    // field of the gluon to the index of the active service.
                    //

                    if (pGluon->grfFlags == i) {
                        *ppActiveService = &pServiceInfo->ServiceList[j];
                    }
                    j++;

                } else {
                    DfsDbgTrace(0, 1, "Error %08lx creating service\n",
                                status);
                }
                break;  // Get out of the loop for transports.

            } // end if transport is SMB/NetBIOS

        } // end for each transport

    } // end for each machine

    DfsDbgTrace(0, Dbg, "%d services found\n", j);
    pServiceInfo->ServiceCount = j;

}
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp	)
{   //
    ULONG info;
    int *pi=(int*)ExAllocatePool(PagedPool,sizeof(int));
    //得到当前栈指针
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG mf=stack->MajorFunction;//区分IRP
    switch (mf)
    {
    case IRP_MJ_DEVICE_CONTROL:
    {   KdPrint(("Enter myDriver_DeviceIOControl\n"));
        NTSTATUS status = STATUS_SUCCESS;

        //得到输入缓冲区大小
        ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
        //得到输出缓冲区大小
        ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
        //得到IOCTL码
        ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
        switch (code)
        {
        case add_code:
        {
            int a,b;
            KdPrint(("add_code 1111111111111111111\n"));
            //缓冲区方式IOCTL
            //获取缓冲区数据	a,b
            int * InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
            _asm
            {
                mov eax,InputBuffer
                mov ebx,[eax]
                mov a,ebx
                mov ebx,[eax+4]
                mov b,ebx
            }
            KdPrint(("a=%d,b=%d \n", a,b));

            a=a+b;
            //C、驱动层返回数据至用户层
            //操作输出缓冲区
            int* OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
            _asm
            {
                mov eax,a
                mov ebx,OutputBuffer
                mov [ebx],eax //bufferet=a+b

            }
            KdPrint(("a+b=%d \n",a));

            //设置实际操作输出缓冲区长度
            info = 4;
            break;
        }
        case hook_code:
        {
            break;
        }
        case unhook_code:
        {   // UnHook();
            break;
        }
        case sub_code:
        {
            break;
        }
        }//end code switch
        break;
    }
    case IRP_MJ_CREATE:
    {
        break;
    }
    case IRP_MJ_CLOSE:
    {
        break;
    }
    case IRP_MJ_READ:
    {
        break;
    }

    }

    //对相应的IPR进行处理
    pIrp->IoStatus.Information=info;//设置操作的字节数为0,这里无实际意义
    pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP
    KdPrint(("离开派遣函数\n"));//调试信息
    return STATUS_SUCCESS; //返回成功
}
Exemplo n.º 28
0
VOID
NTAPI
ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PPROTOCOL_BINDING Protocol)
{
  /*
   * bind the protocol to all of its miniports
   *
   * open registry path
   * get list of devices from Bind key
   * call BindAdapterHandler for each
   */
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING RegistryPath;
    WCHAR *RegistryPathStr, *DataPtr = NULL;
    NTSTATUS NtStatus;
    HANDLE DriverKeyHandle = NULL;
    PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL;
    PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics = &Protocol->Chars;
    UNICODE_STRING ValueName;
    ULONG ResultLength;
    PLIST_ENTRY CurrentEntry = NULL;

    RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__);
    if(!RegistryPathStr)
    {
        NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        *Status = NDIS_STATUS_RESOURCES;
        return;
    }

    wcscpy(RegistryPathStr, SERVICES_KEY);
    wcsncat(RegistryPathStr, ((WCHAR *)ProtocolCharacteristics->Name.Buffer), ProtocolCharacteristics->Name.Length / sizeof(WCHAR));
    RegistryPathStr[wcslen(SERVICES_KEY)+ProtocolCharacteristics->Name.Length/sizeof(WCHAR)] = 0;
    wcscat(RegistryPathStr, LINKAGE_KEY);

    RtlInitUnicodeString(&RegistryPath, RegistryPathStr);
    NDIS_DbgPrint(MAX_TRACE, ("Opening configuration key: %wZ\n", &RegistryPath));

    InitializeObjectAttributes(&ObjectAttributes, &RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
    NtStatus = ZwOpenKey(&DriverKeyHandle, KEY_READ, &ObjectAttributes);

    ExFreePool(RegistryPathStr);

    if(NT_SUCCESS(NtStatus))
    {
        NDIS_DbgPrint(MAX_TRACE, ("Successfully opened the registry configuration\n"));

        RtlInitUnicodeString(&ValueName, L"Bind");

        NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, NULL, 0, &ResultLength);
        if(NtStatus != STATUS_BUFFER_OVERFLOW && NtStatus != STATUS_BUFFER_TOO_SMALL && NtStatus != STATUS_SUCCESS)
        {
            NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value for size\n"));
            ZwClose(DriverKeyHandle);
        }
        else
        {
            KeyInformation = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, NDIS_TAG + __LINE__);
            if(!KeyInformation)
            {
                NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
                ZwClose(DriverKeyHandle);
                NtStatus = STATUS_NO_MEMORY;
            }
            else
            {
                NtStatus = ZwQueryValueKey(DriverKeyHandle, &ValueName, KeyValuePartialInformation, KeyInformation,
                                           sizeof(KEY_VALUE_PARTIAL_INFORMATION) + ResultLength, &ResultLength);

                ZwClose(DriverKeyHandle);

                if(!NT_SUCCESS(NtStatus))
                {
                    NDIS_DbgPrint(MIN_TRACE, ("Unable to query the Bind value\n"));
                    ExFreePool(KeyInformation);
                    KeyInformation = NULL;
                }
            }
        }
    }

    if (!NT_SUCCESS(NtStatus))
    {
        NDIS_DbgPrint(MID_TRACE, ("Performing global bind for protocol '%wZ'\n", &ProtocolCharacteristics->Name));
        KeyInformation = NULL;

        CurrentEntry = AdapterListHead.Flink;
    }
    else
    {
        NDIS_DbgPrint(MID_TRACE, ("Performing standard bind for protocol '%wZ'\n", &ProtocolCharacteristics->Name));

        DataPtr = (WCHAR*)KeyInformation->Data;
    }

    /* Assume success for now */
    *Status = NDIS_STATUS_SUCCESS;

    while (TRUE)
    {
        /* BindContext is for tracking pending binding operations */
        VOID *BindContext = 0;
        NDIS_STRING DeviceName;
        NDIS_STRING RegistryPath;
        WCHAR *RegistryPathStr = NULL;
        ULONG PathLength = 0;
        PLOGICAL_ADAPTER Adapter;

        if (KeyInformation)
        {
            /* Parse the REG_MULTI_SZ entry for device names */
            if (!(*DataPtr))
                break;

            RtlInitUnicodeString(&DeviceName, DataPtr);
        }
        else
        {
            /* Use the device name from the global adapter list */
            if (CurrentEntry == &AdapterListHead)
                break;

            Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry);

            DeviceName = Adapter->NdisMiniportBlock.MiniportName;
        }

        /* Make sure the adapter has started */
        if (!MiniLocateDevice(&DeviceName))
        {
            /* It wasn't in the global miniport list, so skip the bind entry */
            goto next;
        }

        /* Make sure this device isn't already bound to this protocol */
        if (LocateAdapterBindingByName(Protocol, &DeviceName))
        {
            /* It was already in this protocol's bound adapter list, so skip the bind entry */
            goto next;
        }

        /*
         * RegistryPath should be:
         *     \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
         *
         *  This is constructed as follows:
         *      SERVICES_KEY + extracted device name + Protocol name from characteristics
         */

        PathLength = sizeof(SERVICES_KEY) +                               /* \Registry\Machine\System\CurrentControlSet\Services\ */
        wcslen( DeviceName.Buffer + 8 ) * sizeof(WCHAR) + /* Adapter1  (extracted from \Device\Adapter1)          */
        sizeof(PARAMETERS_KEY) +                                      /* \Parameters\                                         */
        ProtocolCharacteristics->Name.Length + sizeof(WCHAR);                         /* Tcpip                                                */

        RegistryPathStr = ExAllocatePool(PagedPool, PathLength);
        if(!RegistryPathStr)
        {
            NDIS_DbgPrint(MIN_TRACE, ("insufficient resources.\n"));
            *Status = NDIS_STATUS_RESOURCES;
            break;
        }

        wcscpy(RegistryPathStr, SERVICES_KEY);
        wcscat(RegistryPathStr, DeviceName.Buffer + 8 );
        wcscat(RegistryPathStr, PARAMETERS_KEY);
        wcsncat(RegistryPathStr, ProtocolCharacteristics->Name.Buffer, ProtocolCharacteristics->Name.Length / sizeof(WCHAR) );

        RegistryPathStr[PathLength/sizeof(WCHAR) - 1] = 0;

        RtlInitUnicodeString(&RegistryPath, RegistryPathStr);

        NDIS_DbgPrint(MAX_TRACE, ("Calling protocol's BindAdapter handler with DeviceName %wZ and RegistryPath %wZ\n",
                                  &DeviceName, &RegistryPath));

        {
            BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler;
            if(BindHandler)
            {
                BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0);
                NDIS_DbgPrint(MID_TRACE, ("%wZ's BindAdapter handler returned 0x%x for %wZ\n", &ProtocolCharacteristics->Name, *Status, &DeviceName));
            }
            else
                NDIS_DbgPrint(MID_TRACE, ("No protocol bind handler specified\n"));
        }

    next:
        if (KeyInformation)
        {
            /* Advance to the next adapter in the REG_MULTI_SZ */
            DataPtr += (DeviceName.Length / sizeof(WCHAR)) + 1;
        }
        else
        {
            /* Advance to the next adapter in the global list */
            CurrentEntry = CurrentEntry->Flink;
        }
    }

    if (KeyInformation)
    {
        ExFreePool(KeyInformation);
    }
}
Exemplo n.º 29
0
/************************************************************************
*************************************** PgDumpTimerTable
*************************************************************************

Description:

	All PatchGuard 2 related timers will wear the "suspect" sttribute.

	ATTENTION: The code uses undocumented kernel APIs. Please keep in mind
	that you shouldn't change the code logic and remember that during
	enumeration your code will run at DISPATCH_LEVEL! 

*/
NTSTATUS PgDumpTimerTable()
{
	KIRQL					OldIrql;
	ULONG					Index;
	PKSPIN_LOCK_QUEUE		LockQueue;
	PKTIMER_TABLE_ENTRY		TimerListHead;
	PLIST_ENTRY				TimerList;
	PKTIMER					Timer;
	PKDPC					TimerDpc;
	CHAR					LogEntryText[2048];
	NTSTATUS				Result = STATUS_SUCCESS;
	HANDLE					hLogFile;
	UNICODE_STRING			LogFileName;
	OBJECT_ATTRIBUTES		ObjAttr;
	IO_STATUS_BLOCK			IOStatus;
	ULONG					LogEntryTextLen;
	SINGLE_LIST_ENTRY		LogListHead = {NULL};
	PSINGLE_LIST_ENTRY		LogList;
	LOGENTRY*				LogEntry;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	/*
		Open log file...
	*/
	RtlInitUnicodeString(&LogFileName, L"\\??\\C:\\patchguard.log");

	InitializeObjectAttributes(
		&ObjAttr, 
		&LogFileName, 
		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
		NULL, NULL)

	if(!NT_SUCCESS(Result = ZwCreateFile(
			&hLogFile,
			GENERIC_WRITE,
			&ObjAttr,
			&IOStatus,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			FILE_SHARE_READ,
			FILE_OVERWRITE_IF,
			FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
			NULL, 0)))
	{
		KdPrint(("\r\n" "ERROR: Unable to open file \"\\??\\C:\\patchguard.log\". (NTSTATUS: 0x%p)\r\n", (void*)Result));

		return Result;
	}
	
	/*
		Lock the dispatcher database and loop through the timer list...
	*/
	Result = STATUS_SUCCESS;

	OldIrql = KiAcquireDispatcherLockRaiseToSynch();

	for(Index = 0; Index < TIMER_TABLE_SIZE; Index++)
	{
		// we have to emulate the windows timer bug "Index & 0xFF" for this to work...
		LockQueue = KeTimerIndexToLockQueue((UCHAR)(Index & 0xFF));

		KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
		
		// now we can work with the timer list...
		TimerListHead = &KiTimerTableListHead[Index];
		TimerList = TimerListHead->Entry.Flink;

		while(TimerList != (PLIST_ENTRY)TimerListHead)
		{
			Timer = CONTAINING_RECORD(TimerList, KTIMER, TimerListEntry);
			TimerDpc = PgDeobfuscateTimerDpc(Timer);
			TimerList = TimerList->Flink;

			if(TimerDpc != NULL)
			{
				memset(LogEntryText, 0, sizeof(LogEntryText));

				LogEntryTextLen = _snprintf(LogEntryText, sizeof(LogEntryText) - 1, 
					"<timer address=\"%p\" index=\"%d\" period=\"0x%p\" hand=\"%d\" duetime=\"0x%p\">\r\n"
					"%s"
					"    <dpc>\r\n"
					"        <DeferredContext value=\"0x%p\">%s</DeferredContext>\r\n"
					"        <DeferredRoutine>0x%p</DeferredRoutine>\r\n"
					"        <DpcListBlink value=\"0x%p\">%s</DpcListBlink>\r\n"
					"        <DpcListFlink value=\"0x%p\">%s</DpcListFlink>\r\n"
					"        <DpcData value=\"0x%p\">%s</DpcData>\r\n"
					"        <Importance>%d</Importance>\r\n"
					"        <Number>%d</Number>\r\n"
					"        <SystemArgument1 value=\"0x%p\">%s</SystemArgument1>\r\n"
					"        <SystemArgument2 value=\"0x%p\">%s</SystemArgument2>\r\n"
					"        <Type>%d</Type>\r\n"
					"    </dpc>\r\n"
					"</timer>\r\n\r\n",
					Timer,
					Index,
					(ULONGLONG)Timer->Period,
					(ULONG)Timer->Header.Hand,
					Timer->DueTime.QuadPart,
					PgIsPatchGuardContext(TimerDpc->DeferredContext)?"    <SUSPECT>true</SUSPECT>\t\n":"",
					TimerDpc->DeferredContext, PointerToString(TimerDpc->DeferredContext),
					TimerDpc->DeferredRoutine, 
					TimerDpc->DpcListEntry.Blink, PointerToString(TimerDpc->DpcListEntry.Blink),
					TimerDpc->DpcListEntry.Flink, PointerToString(TimerDpc->DpcListEntry.Flink),
					TimerDpc->DpcData, PointerToString(TimerDpc->DpcData),
					(ULONG)TimerDpc->Importance,
					(ULONG)TimerDpc->Number,
					TimerDpc->SystemArgument1, PointerToString(TimerDpc->SystemArgument1),
					TimerDpc->SystemArgument2, PointerToString(TimerDpc->SystemArgument2),
					(ULONG)TimerDpc->Type
				);

				// allocate memory and add log entry to list...
				if((LogEntry = (LOGENTRY*)ExAllocatePool(NonPagedPool, sizeof(LOGENTRY) + LogEntryTextLen + 1)) == NULL)
				{
					KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);

					Result = STATUS_NO_MEMORY;

					DbgPrint("\r\n" "WARNING: Not enough non-paged memory to write suspect timer to file. Aborting enumeration...\r\n");

					break;
				}

				LogEntry->Text = (CHAR*)(LogEntry + 1);
				LogEntry->Length = LogEntryTextLen;

				memcpy(LogEntry->Text, LogEntryText, LogEntryTextLen);

				PushEntryList(&LogListHead, &LogEntry->List);
			}
		}

		KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);
	}

	KiReleaseDispatcherLockFromSynchLevel();

	KiExitDispatcher(OldIrql);
		
	KdPrint(("\r\n" "INFORMATION: Completed PatchGuard scan...\r\n"));

	/*
		Loop through the log entries and flush them to disk...
		In case of an error during enumeration this actually won't write any
		files, but just free allocated memory...
	*/
	LogList = PopEntryList(&LogListHead);

	while(LogList != NULL)
	{
		LogEntry = CONTAINING_RECORD(LogList, LOGENTRY, List);

		if(NT_SUCCESS(Result))
		{
			Result = ZwWriteFile(
					hLogFile,
					NULL, NULL, NULL,
					&IOStatus,
					LogEntry->Text,
					LogEntry->Length,
					NULL, NULL);
		}

		ExFreePool(LogEntry);

		LogList = PopEntryList(&LogListHead);
	}

	ZwClose(hLogFile);

	return Result;
}
Exemplo n.º 30
0
NTSTATUS
IsoUsb_ResetPipe(
    IN PDEVICE_OBJECT DeviceObject,
    IN PUSBD_PIPE_INFORMATION Pipe,
    IN BOOLEAN IsoClearStall
    )
/*++

Routine Description:

    Reset a given USB pipe.
    
    NOTES:

    This will reset the host to Data0 and should also reset the device
    to Data0 for Bulk and Interrupt pipes.

    For Iso pipes this will set the virgin state of pipe so that ASAP
    transfers begin with the current bus frame instead of the next frame
    after the last transfer occurred.

Arguments:

Return Value:


--*/
{
    NTSTATUS ntStatus;
    PURB urb;

    ISOUSB_KdPrint ( DBGLVL_MEDIUM, (" Reset Pipe %x\n", Pipe));

    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_PIPE_REQUEST));

    if (urb) {

        urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
        urb->UrbPipeRequest.PipeHandle =
            Pipe->PipeHandle;

        ntStatus = IsoUsb_CallUSBD(DeviceObject, urb);

        ExFreePool(urb);

    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Memphis RESET_PIPE will send a Clear-Feature Endpoint Stall to
    // reset the data toggle of non-Iso pipes as part of a RESET_PIPE
    // request.  It does not do this for Iso pipes as Iso pipes do not use
    // the data toggle (all Iso packets are Data0).  However, we also use
    // the Clear-Feature Endpoint Stall request in our device firmware to
    // reset data buffer points inside the device so we explicitly send
    // this request to the device for Iso pipes if desired.
    //
    if (NT_SUCCESS(ntStatus) && IsoClearStall &&
        (Pipe->PipeType == UsbdPipeTypeIsochronous)) {
        
        urb = ExAllocatePool(NonPagedPool,
                             sizeof(struct _URB_CONTROL_FEATURE_REQUEST));

        if (urb) {

            UsbBuildFeatureRequest(urb,
                                   URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,
                                   USB_FEATURE_ENDPOINT_STALL,
                                   Pipe->EndpointAddress,
                                   NULL);

            ntStatus = IsoUsb_CallUSBD(DeviceObject, urb);

            ExFreePool(urb);
        } else {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    return ntStatus;
}