Example #1
1
BOOLEAN
SampSetUpgradeFlag(
    )
/*++

Routine Description:

    This routine sets SAM upgrade flag is set. The upgrade
    flag is:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa
        UpgradeSam = REG_DWORD 1

    and the value will be deleted.


Arguments:


Return Value:

    TRUE - The flag was set

    FALSE - The flag was not set or the value was not present

--*/
{
    NTSTATUS NtStatus;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE KeyHandle;
    UCHAR Buffer[100];
    PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer;
    ULONG KeyValueLength = 100;
    ULONG ResultLength;
    PULONG UpgradeFlag;

    //
    // Open the Lsa key in the registry
    //

    RtlInitUnicodeString(
        &KeyName,
        SAMP_LSA_KEY_NAME
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL
        );

    NtStatus = NtOpenKey(
                &KeyHandle,
                KEY_SET_VALUE,
                &ObjectAttributes
                );

    if (!NT_SUCCESS(NtStatus)) {
        return(FALSE);
    }

    //
    // Query the Notification Packages value
    //

    RtlInitUnicodeString(
        &KeyName,
        L"UpgradeSam"
        );

    NtStatus = NtDeleteValueKey(
                    KeyHandle,
                    &KeyName
                    );

    NtClose(KeyHandle);


}
Example #2
0
_Use_decl_annotations_
NDIS_STATUS
FilterAttach(
    NDIS_HANDLE                     NdisFilterHandle,
    NDIS_HANDLE                     FilterDriverContext,
    PNDIS_FILTER_ATTACH_PARAMETERS  AttachParameters
    )
/*++

Routine Description:

    Filter attach routine.
    Create filter's context, allocate NetBufferLists and NetBuffer pools and any
    other resources, and read configuration if needed.

Arguments:

    NdisFilterHandle - Specify a handle identifying this instance of the filter. FilterAttach
                       should save this handle. It is a required  parameter in subsequent calls
                       to NdisFxxx functions.
    FilterDriverContext - Filter driver context passed to NdisFRegisterFilterDriver.

    AttachParameters - attach parameters

Return Value:

    NDIS_STATUS_SUCCESS: FilterAttach successfully allocated and initialize data structures
                         for this filter instance.
    NDIS_STATUS_RESOURCES: FilterAttach failed due to insufficient resources.
    NDIS_STATUS_FAILURE: FilterAttach could not set up this instance of this filter and it has called
                         NdisWriteErrorLogEntry with parameters specifying the reason for failure.

N.B.:  FILTER can use NdisRegisterDeviceEx to create a device, so the upper 
    layer can send Irps to the filter.

--*/
{
    PMS_FILTER              pFilter = NULL;
    NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;
    NTSTATUS                NtStatus;
    NDIS_FILTER_ATTRIBUTES  FilterAttributes;
    ULONG                   Size;
    COMPARTMENT_ID          OriginalCompartmentID;
    OBJECT_ATTRIBUTES       ObjectAttributes = {0};

    const ULONG RegKeyOffset = ARRAYSIZE(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\") - 1;
    DECLARE_CONST_UNICODE_STRING(RegKeyPath, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\otlwf\\Parameters\\NdisAdapters\\{00000000-0000-0000-0000-000000000000}");
    RtlCopyMemory(RegKeyPath.Buffer + RegKeyOffset, AttachParameters->BaseMiniportName->Buffer + 8, sizeof(L"{00000000-0000-0000-0000-000000000000}"));

    LogFuncEntry(DRIVER_DEFAULT);

    do
    {
        ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
        if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)
        {
            Status = NDIS_STATUS_INVALID_PARAMETER;
            break;
        }

        // Verify the media type is supported.  This is a last resort; the
        // the filter should never have been bound to an unsupported miniport
        // to begin with.
        if (AttachParameters->MiniportMediaType != NdisMediumIP)
        {
            LogError(DRIVER_DEFAULT, "Unsupported media type, 0x%x.", (ULONG)AttachParameters->MiniportMediaType);
            Status = NDIS_STATUS_INVALID_PARAMETER;
            break;
        }

        Size = sizeof(MS_FILTER) +  AttachParameters->BaseMiniportInstanceName->Length;

        pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);
        if (pFilter == NULL)
        {
            LogWarning(DRIVER_DEFAULT, "Failed to allocate context structure, 0x%x bytes", Size);
            Status = NDIS_STATUS_RESOURCES;
            break;
        }

        NdisZeroMemory(pFilter, sizeof(MS_FILTER));

        LogVerbose(DRIVER_DEFAULT, "Opening interface registry key %S", RegKeyPath.Buffer);

        InitializeObjectAttributes(
            &ObjectAttributes,
            (PUNICODE_STRING)&RegKeyPath,
            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
            NULL,
            NULL);

        // Open the registry key
        NtStatus = ZwOpenKey(&pFilter->InterfaceRegKey, KEY_ALL_ACCESS, &ObjectAttributes);
        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "ZwOpenKey failed to open %S, %!STATUS!", RegKeyPath.Buffer, NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        // Format of "\DEVICE\{5BA90C49-0D7E-455B-8D3B-614F6714A212}"
        AttachParameters->BaseMiniportName->Buffer += 8;
        AttachParameters->BaseMiniportName->Length -= 8 * sizeof(WCHAR);
        NtStatus = RtlGUIDFromString(AttachParameters->BaseMiniportName, &pFilter->InterfaceGuid);
        AttachParameters->BaseMiniportName->Buffer -= 8;
        AttachParameters->BaseMiniportName->Length += 8 * sizeof(WCHAR);
        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "Failed to convert FilterModuleGuidName to a GUID, %!STATUS!", NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        pFilter->InterfaceFriendlyName.Length = pFilter->InterfaceFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;
        pFilter->InterfaceFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));
        NdisMoveMemory(pFilter->InterfaceFriendlyName.Buffer,
                        AttachParameters->BaseMiniportInstanceName->Buffer,
                        pFilter->InterfaceFriendlyName.Length);

        pFilter->InterfaceIndex = AttachParameters->BaseMiniportIfIndex;
        pFilter->InterfaceLuid = AttachParameters->BaseMiniportNetLuid;
        pFilter->InterfaceCompartmentID = UNSPECIFIED_COMPARTMENT_ID;
        pFilter->FilterHandle = NdisFilterHandle;

        NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
        FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
        FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
        FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
        FilterAttributes.Flags = 0;

        NDIS_DECLARE_FILTER_MODULE_CONTEXT(MS_FILTER);
        Status = NdisFSetAttributes(NdisFilterHandle, pFilter, &FilterAttributes);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            LogError(DRIVER_DEFAULT, "Failed to set attributes, %!NDIS_STATUS!", Status);
            break;
        }

        // Filter initially in Paused state
        pFilter->State = FilterPaused;

        // Initialize rundowns to disabled with no active references
        pFilter->ExternalRefs.Count = EX_RUNDOWN_ACTIVE;
        pFilter->cmdRundown.Count = EX_RUNDOWN_ACTIVE;

        // Query the compartment ID for this interface to use for the IP stack
        pFilter->InterfaceCompartmentID = GetInterfaceCompartmentID(&pFilter->InterfaceLuid);
        LogVerbose(DRIVER_DEFAULT, "Interface %!GUID! is in Compartment %u", &pFilter->InterfaceGuid, (ULONG)pFilter->InterfaceCompartmentID);

        // Make sure we are in the right compartment
        (VOID)otLwfSetCompartment(pFilter, &OriginalCompartmentID);

        // Register for address changed notifications
        NtStatus = 
            NotifyUnicastIpAddressChange(
                AF_INET6,
                otLwfAddressChangeCallback,
                pFilter,
                FALSE,
                &pFilter->AddressChangeHandle
                );

        // Revert the compartment, now that we have the table
        otLwfRevertCompartment(OriginalCompartmentID);

        if (!NT_SUCCESS(NtStatus))
        {
            LogError(DRIVER_DEFAULT, "NotifyUnicastIpAddressChange failed, %!STATUS!", NtStatus);
            Status = NDIS_STATUS_FAILURE;
            break;
        }

        // Add Filter to global list of Thread Filters
        NdisAcquireSpinLock(&FilterListLock);
        InsertTailList(&FilterModuleList, &pFilter->FilterModuleLink);
        NdisReleaseSpinLock(&FilterListLock);

        LogVerbose(DRIVER_DEFAULT, "Created Filter: %p", pFilter);

    } while (FALSE);

    // Clean up on failure
    if (Status != NDIS_STATUS_SUCCESS)
    {
        if (pFilter != NULL)
        {
            if (pFilter->AddressChangeHandle != NULL)
            {
                CancelMibChangeNotify2(pFilter->AddressChangeHandle);
                pFilter->AddressChangeHandle = NULL;
            }

            NdisFreeMemory(pFilter, 0, 0);
        }
    }

    LogFuncExitNDIS(DRIVER_DEFAULT, Status);

    return Status;
}
Example #3
0
/*
* 函数说明:
*		初始化通讯
*
* 参数:
*		pFlt
*                           
* 返回值:
*		TRUE	成功
*		FALSE	失败
*
* 备注:
*
*/
BOOLEAN
	CComm::Init(
	__in PFLT_FILTER pFlt
	)
{
	BOOLEAN					bRet		= FALSE;

	CKrnlStr				PortName;

	NTSTATUS				ntStatus	= STATUS_UNSUCCESSFUL;
	PSECURITY_DESCRIPTOR	pSd			= NULL;
	OBJECT_ATTRIBUTES		Ob			= {0};

	CLog					Log;


	KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"begin");

	__try
	{
		if (!pFlt)
		{
			KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"input argument error");
			__leave;
		}

		if (CMinifilter::ms_pMfIns->CheckEnv(MINIFILTER_ENV_TYPE_FLT_FILTER) && ms_CommInfo.pSeverPort)
		{
			KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"already init");
			__leave;
		}

		if (!PortName.Set(g_lpCommPortName, wcslen(g_lpCommPortName)))
		{
			KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"PortName.Set failed");
			__leave;
		}

		ntStatus = FltBuildDefaultSecurityDescriptor(&pSd, FLT_PORT_ALL_ACCESS);
		if (!NT_SUCCESS(ntStatus))
		{
			KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"FltBuildDefaultSecurityDescriptor failed. (%x)",
				ntStatus);

			__leave;
		}

		InitializeObjectAttributes(
			&Ob,
			PortName.Get(),
			OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
			NULL,
			pSd
			);

		ntStatus = FltCreateCommunicationPort(
			pFlt,
			&ms_CommInfo.pSeverPort,
			&Ob,
			NULL,
			(PFLT_CONNECT_NOTIFY)CommKmConnectNotify,
			(PFLT_DISCONNECT_NOTIFY)CommKmDisconnectNotify,
			(PFLT_MESSAGE_NOTIFY)CommKmMessageNotify,
			1
			);
		if (!NT_SUCCESS(ntStatus))
		{
			KdPrintKrnl(LOG_PRINTF_LEVEL_ERROR, LOG_RECORED_LEVEL_NEED, L"FltCreateCommunicationPort failed. (%x)",
				ntStatus);

			__leave;
		}

		bRet = TRUE;
	}
	__finally
	{
		if (pSd)
		{
			FltFreeSecurityDescriptor(pSd);
			pSd = NULL;
		}

		if (!bRet)
		{
			if (ms_CommInfo.pSeverPort)
			{
				FltCloseCommunicationPort(ms_CommInfo.pSeverPort);
				ms_CommInfo.pSeverPort = NULL;
			}
		}
	}
	
	KdPrintKrnl(LOG_PRINTF_LEVEL_INFO, LOG_RECORED_LEVEL_NEED, L"end");

	return bRet;
}
Example #4
0
BOOLEAN
ProcessLocaleRegistry(PGENERIC_LIST List)
{
    PGENERIC_LIST_ENTRY Entry;
    PWCHAR LanguageId;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;

    HANDLE KeyHandle;
    NTSTATUS Status;

    Entry = GetCurrentListEntry(List);
    if (Entry == NULL)
        return FALSE;

    LanguageId = (PWCHAR)GetListEntryUserData(Entry);
    if (LanguageId == NULL)
        return FALSE;

    /* Skip first 4 zeroes */
    if (wcslen(LanguageId) >= 4)
        LanguageId += 4;

    /* Open the NLS language key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language");

    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status =  NtOpenKey(&KeyHandle,
                        KEY_SET_VALUE,
                        &ObjectAttributes);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    /* Set default language */
    RtlInitUnicodeString(&ValueName,
                         L"Default");
    Status = NtSetValueKey(KeyHandle,
                           &ValueName,
                           0,
                           REG_SZ,
                           (PVOID)LanguageId,
                           (wcslen(LanguageId) + 1) * sizeof(WCHAR));
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
        NtClose(KeyHandle);
        return FALSE;
    }

    /* Set install language */
    RtlInitUnicodeString(&ValueName,
                         L"InstallLanguage");
    Status = NtSetValueKey (KeyHandle,
                            &ValueName,
                            0,
                            REG_SZ,
                            (PVOID)LanguageId,
                            (wcslen(LanguageId) + 1) * sizeof(WCHAR));
    NtClose(KeyHandle);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    return TRUE;
}
Example #5
0
BOOLEAN
obtest( void )
{
    ULONG i;
    HANDLE Handles[ 2 ];
    NTSTATUS Status;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectTypeAName, "ObjectTypeA" );
    RtlInitString( &ObjectTypeBName, "ObjectTypeB" );

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.ValidAccessMask = -1;

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = TRUE;
    ObjectTypeInitializer.DumpProcedure = DumpAProc;
    ObjectTypeInitializer.OpenProcedure = OpenAProc;
    ObjectTypeInitializer.CloseProcedure = CloseAProc;
    ObjectTypeInitializer.DeleteProcedure = DeleteAProc;
    ObjectTypeInitializer.ParseProcedure = ParseAProc;
    ObCreateObjectType(
        &ObjectTypeAName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeA
        );

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = FALSE;
    ObjectTypeInitializer.GenericMapping = MyGenericMapping;
    ObjectTypeInitializer.DumpProcedure = DumpBProc;
    ObjectTypeInitializer.OpenProcedure = NULL;
    ObjectTypeInitializer.CloseProcedure = NULL;
    ObjectTypeInitializer.DeleteProcedure = DeleteBProc;
    ObjectTypeInitializer.ParseProcedure = NULL;
    ObCreateObjectType(
        &ObjectTypeBName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeB
        );

    ObpDumpTypes( NULL );

    RtlInitString( &DirectoryName, "\\MyObjects" );
    InitializeObjectAttributes( &DirectoryObjA,
                                &DirectoryName,
                                OBJ_PERMANENT |
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    NtCreateDirectoryObject( &DirectoryHandle,
                             0,
                             &DirectoryObjA
                           );
    NtClose( DirectoryHandle );

    RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" );
    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA
        );

    ObjectA = (POBJECTTYPEA)ObjectBodyA;
    ObjectA->TypeALength = sizeof( *ObjectA );
    for (i=0; i<4; i++) {
        ObjectA->Stuff[i] = i+1;
        }
    KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeB,
        &ObjectBObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEB ),
        0L,
        0L,
        (PVOID *)&ObjectBodyB
        );

    ObjectB = (POBJECTTYPEB)ObjectBodyB;
    ObjectB->TypeBLength = sizeof( *ObjectB );
    for (i=0; i<16; i++) {
        ObjectB->Stuff[i] = i+1;
        }
    KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L );

    Status = ObInsertObject(
        ObjectBodyA,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA,
        &ObjectHandleA1
        );

    DbgPrint( "Status: %lx  ObjectBodyA: %lx  ObjectHandleA1: %lx\n",
             Status, ObjectBodyA, ObjectHandleA1
           );

    Status = ObInsertObject(
        ObjectBodyB,
        SYNCHRONIZE | 0x1,
        NULL,
        1,
        &ObjectBodyB,
        &ObjectHandleB1
        );

    DbgPrint( "Status: %lx  ObjectBodyB: %lx  ObjectHandleB1: %lx\n",
             Status, ObjectBodyB, ObjectHandleB1
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_OPENIF,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA1
        );


    Status = ObInsertObject(
        ObjectBodyA1,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA2,
        &ObjectHandleA2
        );

    DbgPrint( "Status: %lx  ObjectBodyA1: %lx  ObjectBodyA2: %lx  ObjectHandleA2: %lx\n",
             Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );
    NtClose( ObjectHandleA2 );
    ObDereferenceObject( ObjectBodyA2 );    // ObInsertObject,ObjectPointerBias

    NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL );
    Handles[ 0 ] = ObjectHandleA1;
    Handles[ 1 ] = ObjectHandleB1;
    NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByPointer(
        ObjectBodyA,
        0L,
        ObjectTypeA,
        KernelMode
        );

    ObReferenceObjectByPointer(
        ObjectBodyB,
        0L,
        ObjectTypeB,
        KernelMode
        );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" );
    RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" );
    ObReferenceObjectByName(
        &ObjectAPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectBodyA
        );

    ObReferenceObjectByName(
        &ObjectBPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectBodyB
        );

    DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectBodyA );

    DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObInsertObject,ObjectPointerBias
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByPointer
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByName
    ObDereferenceObject( ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectAObjA,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectHandleA2
        );

    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectBObjA,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectHandleB2
        );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectHandleA2 );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA2,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB2,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObOpenObjectByPointer(
        ObjectBodyA,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        &ObjectHandleA1
        );

    ObOpenObjectByPointer(
        ObjectBodyB,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        &ObjectHandleB1
        );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA,
            ObjectHandleA1 );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB,
            ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    NtClose( ObjectHandleA2 );
    NtClose( ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    TestFunction = NULL;

    return( TRUE );
}
Example #6
0
/* 
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 *
 *
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
 */
NTSTATUS
DriverEntry( IN PDRIVER_OBJECT theDriverObject,
             IN PUNICODE_STRING theRegistryPath )

{
NTSTATUS              Status; 
PSECURITY_DESCRIPTOR  SecurityDescriptor;
OBJECT_ATTRIBUTES     ObjectAttributes;
UNICODE_STRING        uPortName;


    // Open the registry and read in all the setting we will use in kernel mode
    EnumerateRegistryValues( theRegistryPath );

   // DDK : "...Add itself to the global list of registered minifilters and to provide 
   //        the Filter Manager with a list of callback functions and other information 
   //        about the minifilter."
   Status = FltRegisterFilter( theDriverObject,
                               &cfsd_FilterRegistration,
                               &gFilterPointer );

    if ( NT_SUCCESS( Status ) )
    {

#if ENABLE_USER_INTERFACE

     Status  = FltBuildDefaultSecurityDescriptor( &SecurityDescriptor,
                                                  FLT_PORT_ALL_ACCESS );

     if ( NT_SUCCESS( Status ) ) 
     {

      RtlInitUnicodeString( &uPortName, USER_COMMUNICATION_PORT_NAME );

      InitializeObjectAttributes( &ObjectAttributes,
                                  &uPortName,
                                  OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                  NULL,
                                  SecurityDescriptor );

        Status = FltCreateCommunicationPort( gFilterPointer,                 // Filter
                                             &gUserModeConnection.ServerPort,// *ServerPort
                                             &ObjectAttributes,              // ObjectAttributes
                                             NULL,                           // ServerPortCookie
                                             cfsd_UserModeConnect,           // ConnectNotifyCallback
                                             cfsd_UserModeDisconnect,        // DisconnectNotifyCallback
                                             cfsd_UserModeCommunication,     // MessageNotifyCallback
                                             1 );                            // MaxConnections

        FltFreeSecurityDescriptor( SecurityDescriptor );

        // If we failed to create a communications port then we are going to fail the driver
        if ( !NT_SUCCESS( Status ) ) 
        {

 KdPrint( (PRINT_TAG "Failed FltCreateCommunicationPort() with NTSTATUS 0x%x\n",Status ) );

         // Release our hidden data memory
         ExFreePoolWithTag( gFileData, 'parC' );

         return Status;
        }

 DBG_PRINT( DbgOutput, DBG_USERMODE, (PRINT_TAG_USERMODE "Created communication server port 0x%X for usermode access\n", gUserModeConnection.ServerPort ));

     }

#endif // End #if ENABLE_USER_INTERFACE

     // DDK : "...Notifies the Filter Manager that the minifilter is ready to 
     //        begin attaching to volumes and filtering I/O requests"
     Status = FltStartFiltering( gFilterPointer );

     if ( !NT_SUCCESS( Status )) 
     {

#if ENABLE_USER_INTERFACE
      FltCloseCommunicationPort( gUserModeConnection.ServerPort );
#endif // End #if ENABLE_USER_INTERFACE

      // If we failed FltStartFiltering() then we unregister ourself with the Filter Manager 
      // so that we no longer recieve calls to process I/O operations.
      FltUnregisterFilter( gFilterPointer );

      // Release our hidden data memory
      ExFreePoolWithTag( gFileData, 'parC' );
     }
    }

 return Status;
}
Example #7
0
static BOOLEAN
IsAcpiComputer(VOID)
{
   UNICODE_STRING MultiKeyPathU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter");
   UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
   UNICODE_STRING AcpiBiosIdentifier = RTL_CONSTANT_STRING(L"ACPI BIOS");
   OBJECT_ATTRIBUTES ObjectAttributes;
   PKEY_BASIC_INFORMATION pDeviceInformation = NULL;
   ULONG DeviceInfoLength = sizeof(KEY_BASIC_INFORMATION) + 50 * sizeof(WCHAR);
   PKEY_VALUE_PARTIAL_INFORMATION pValueInformation = NULL;
   ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
   ULONG RequiredSize;
   ULONG IndexDevice = 0;
   UNICODE_STRING DeviceName, ValueName;
   HANDLE hDevicesKey = NULL;
   HANDLE hDeviceKey = NULL;
   NTSTATUS Status;
   BOOLEAN ret = FALSE;

   InitializeObjectAttributes(&ObjectAttributes, &MultiKeyPathU, OBJ_CASE_INSENSITIVE, NULL, NULL);
   Status = NtOpenKey(&hDevicesKey, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
   if (!NT_SUCCESS(Status))
   {
      DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status);
      goto cleanup;
   }

   pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength);
   if (!pDeviceInformation)
   {
      DPRINT("RtlAllocateHeap() failed\n");
      Status = STATUS_NO_MEMORY;
      goto cleanup;
   }

   pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength);
   if (!pDeviceInformation)
   {
      DPRINT("RtlAllocateHeap() failed\n");
      Status = STATUS_NO_MEMORY;
      goto cleanup;
   }

   while (TRUE)
   {
      Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
      if (Status == STATUS_NO_MORE_ENTRIES)
         break;
      else if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
      {
         RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation);
         DeviceInfoLength = RequiredSize;
         pDeviceInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, DeviceInfoLength);
         if (!pDeviceInformation)
         {
            DPRINT("RtlAllocateHeap() failed\n");
            Status = STATUS_NO_MEMORY;
            goto cleanup;
         }
         Status = NtEnumerateKey(hDevicesKey, IndexDevice, KeyBasicInformation, pDeviceInformation, DeviceInfoLength, &RequiredSize);
      }
      if (!NT_SUCCESS(Status))
      {
         DPRINT("NtEnumerateKey() failed with status 0x%08lx\n", Status);
         goto cleanup;
      }
      IndexDevice++;

      /* Open device key */
      DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
      DeviceName.Buffer = pDeviceInformation->Name;
      InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, hDevicesKey, NULL);
      Status = NtOpenKey(
         &hDeviceKey,
         KEY_QUERY_VALUE,
         &ObjectAttributes);
      if (!NT_SUCCESS(Status))
      {
         DPRINT("NtOpenKey() failed with status 0x%08lx\n", Status);
         goto cleanup;
      }

      /* Read identifier */
      Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
      if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
      {
         RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation);
         ValueInfoLength = RequiredSize;
         pValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueInfoLength);
         if (!pValueInformation)
         {
            DPRINT("RtlAllocateHeap() failed\n");
            Status = STATUS_NO_MEMORY;
            goto cleanup;
         }
         Status = NtQueryValueKey(hDeviceKey, &IdentifierU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
      }
      if (!NT_SUCCESS(Status))
      {
         DPRINT("NtQueryValueKey() failed with status 0x%08lx\n", Status);
         goto nextdevice;
      }
      else if (pValueInformation->Type != REG_SZ)
      {
         DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
         goto nextdevice;
      }

      ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength;
      ValueName.Buffer = (PWCHAR)pValueInformation->Data;
      if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
         ValueName.Length -= sizeof(WCHAR);
      if (RtlCompareUnicodeString(&ValueName, &AcpiBiosIdentifier, FALSE) == 0)
      {
         DPRINT("Found ACPI BIOS\n");
         ret = TRUE;
         goto cleanup;
      }

nextdevice:
      NtClose(hDeviceKey);
      hDeviceKey = NULL;
   }

cleanup:
   if (pDeviceInformation)
      RtlFreeHeap(RtlGetProcessHeap(), 0, pDeviceInformation);
   if (pValueInformation)
      RtlFreeHeap(RtlGetProcessHeap(), 0, pValueInformation);
   if (hDevicesKey)
      NtClose(hDevicesKey);
   if (hDeviceKey)
      NtClose(hDeviceKey);
   return ret;
}
Example #8
0
int __cdecl main(int argc, char *argv[])
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { FI_ARG_HELP, L"h", NoArgumentType },
        { FI_ARG_ACTION, L"a", MandatoryArgumentType },
        { FI_ARG_NATIVE, L"N", NoArgumentType },
        { FI_ARG_PATTERN, L"p", MandatoryArgumentType },
        { FI_ARG_CASESENSITIVE, L"C", NoArgumentType },
        { FI_ARG_OUTPUT, L"o", MandatoryArgumentType },
        { FI_ARG_FORCE, L"f", NoArgumentType },
        { FI_ARG_LENGTH, L"L", MandatoryArgumentType }
    };
    PH_STRINGREF commandLine;
    NTSTATUS status = STATUS_SUCCESS;

    if (!NT_SUCCESS(PhInitializePhLibEx(0, 0, 0)))
        return 1;

    PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);

    if (!PhParseCommandLine(
        &commandLine,
        options,
        sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
        PH_COMMAND_LINE_IGNORE_FIRST_PART,
        FiCommandLineCallback,
        NULL
        ) || FiArgHelp)
    {
        FiPrintHelp();
        return 0;
    }

    if (!FiArgFileName && (
        FiArgAction &&
        PhEqualString2(FiArgAction, L"dir", TRUE)
        ))
    {
        FiArgFileName = PhCreateStringFromUnicodeString(&NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath);
    }

    if (!FiArgAction)
    {
        FiPrintHelp();
        return 1;
    }
    else if (PhEqualString2(FiArgAction, L"map", TRUE))
    {
        WCHAR deviceNameBuffer[7] = L"\\??\\ :";
        ULONG i;
        WCHAR targetNameBuffer[0x100];
        UNICODE_STRING targetName;

        targetName.Buffer = targetNameBuffer;
        targetName.MaximumLength = sizeof(targetNameBuffer);

        for (i = 0; i < 26; i++)
        {
            HANDLE linkHandle;
            OBJECT_ATTRIBUTES oa;
            UNICODE_STRING deviceName;

            deviceNameBuffer[4] = (WCHAR)('A' + i);
            deviceName.Buffer = deviceNameBuffer;
            deviceName.Length = 6 * sizeof(WCHAR);

            InitializeObjectAttributes(
                &oa,
                &deviceName,
                OBJ_CASE_INSENSITIVE,
                NULL,
                NULL
                );

            if (NT_SUCCESS(NtOpenSymbolicLinkObject(
                &linkHandle,
                SYMBOLIC_LINK_QUERY,
                &oa
                )))
            {
                if (NT_SUCCESS(NtQuerySymbolicLinkObject(
                    linkHandle,
                    &targetName,
                    NULL
                    )))
                {
                    wprintf(L"%c: %.*s\n", 'A' + i, targetName.Length / 2, targetName.Buffer);
                }

                NtClose(linkHandle);
            }
        }
    }
    else if (!FiArgFileName)
    {
        wprintf(L"Error: file name missing.\n");
        FiPrintHelp();
        return 1;
    }
    else if (PhEqualString2(FiArgAction, L"hash", TRUE))
    {
        HANDLE fileHandle;
        LARGE_INTEGER fileSize;
        IO_STATUS_BLOCK isb;
        ULONG mode;

        if (!FiArgOutput)
            mode = HASH_MD5;
        else if (PhEqualString2(FiArgOutput, L"md5", TRUE))
            mode = HASH_MD5;
        else if (PhEqualString2(FiArgOutput, L"sha1", TRUE))
            mode = HASH_SHA1;
        else if (PhEqualString2(FiArgOutput, L"crc32", TRUE))
            mode = HASH_CRC32;
        else
        {
            wprintf(L"Invalid hash algorithm. Possibilities: md5, sha1, crc32\n");
            return 1;
        }

        if (FiCreateFile(
            &fileHandle,
            FILE_GENERIC_READ,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY
            ))
        {
            if (NT_SUCCESS(status = PhGetFileSize(fileHandle, &fileSize)))
            {
                MD5_CTX md5Context;
                A_SHA_CTX shaContext;
                ULONG crc;
                UCHAR buffer[PAGE_SIZE * 4];
                ULONG64 bytesRemaining;

                bytesRemaining = fileSize.QuadPart;

                switch (mode)
                {
                case HASH_MD5:
                    MD5Init(&md5Context);
                    break;
                case HASH_SHA1:
                    A_SHAInit(&shaContext);
                    break;
                case HASH_CRC32:
                    crc = 0;
                    break;
                }

                while (bytesRemaining)
                {
                    status = NtReadFile(
                        fileHandle,
                        NULL,
                        NULL,
                        NULL,
                        &isb,
                        buffer,
                        sizeof(buffer),
                        NULL,
                        NULL
                        );

                    if (!NT_SUCCESS(status))
                        break;

                    switch (mode)
                    {
                    case HASH_MD5:
                        MD5Update(&md5Context, buffer, (ULONG)isb.Information);
                        break;
                    case HASH_SHA1:
                        A_SHAUpdate(&shaContext, buffer, (ULONG)isb.Information);
                        break;
                    case HASH_CRC32:
                        crc = PhCrc32(crc, buffer, isb.Information);
                        break;
                    }

                    bytesRemaining -= (ULONG)isb.Information;
                }

                if (status == STATUS_END_OF_FILE)
                    status = STATUS_SUCCESS;

                switch (mode)
                {
                case HASH_MD5:
                    {
                        MD5Final(&md5Context);
                        wprintf(L"%s", PhBufferToHexString(md5Context.digest, 16)->Buffer);
                    }
                    break;
                case HASH_SHA1:
                    {
                        UCHAR hash[20];

                        A_SHAFinal(&shaContext, hash);
                        wprintf(L"%s", PhBufferToHexString(hash, 20)->Buffer);
                    }
                    break;
                case HASH_CRC32:
                    {
                        wprintf(L"%08x", crc);
                    }
                    break;
                }

                if (!NT_SUCCESS(status))
                    wprintf(L"Warning: I/O error encountered: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }

        if (!NT_SUCCESS(status))
        {
            wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
            return 1;
        }
    }
    else if (PhEqualString2(FiArgAction, L"execute", TRUE))
    {
        if (FiArgNative)
        {
            if (!NT_SUCCESS(status = PhCreateProcess(
                FiFormatFileName(FiArgFileName)->Buffer,
                FiArgOutput ? &FiArgOutput->sr : NULL,
                NULL,
                NULL,
                NULL,
                0,
                NULL,
                NULL,
                NULL,
                NULL
                )))
            {
                wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
                return 1;
            }
        }
        else
        {
            if (!NT_SUCCESS(status = PhCreateProcessWin32(
                FiArgFileName->Buffer,
                PhGetString(FiArgOutput),
                NULL,
                NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer,
                PH_CREATE_PROCESS_NEW_CONSOLE,
                NULL,
                NULL,
                NULL
                )))
            {
                wprintf(L"Error: %s\n", PhGetNtMessage(status)->Buffer);
                return 1;
            }
        }
    }
    else if (PhEqualString2(FiArgAction, L"del", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            DELETE | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            FILE_DISPOSITION_INFORMATION dispositionInfo;
            IO_STATUS_BLOCK isb;

            dispositionInfo.DeleteFile = TRUE;
            if (!NT_SUCCESS(status = NtSetInformationFile(fileHandle, &isb, &dispositionInfo,
                sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation)))
            {
                wprintf(L"Error deleting file: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"touch", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN_IF,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"mkdir", TRUE))
    {
        HANDLE fileHandle;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            FILE_ATTRIBUTE_DIRECTORY,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_CREATE,
            FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"rename", TRUE))
    {
        HANDLE fileHandle;
        PPH_STRING newFileName;

        if (!FiArgOutput)
        {
            wprintf(L"Error: new file name missing.\n");
            FiPrintHelp();
            return 1;
        }

        newFileName = FiFormatFileName(FiArgOutput);

        if (FiCreateFile(
            &fileHandle,
            DELETE | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            PFILE_RENAME_INFORMATION renameInfo;
            ULONG renameInfoSize;
            IO_STATUS_BLOCK isb;

            renameInfoSize = FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) + (ULONG)newFileName->Length;
            renameInfo = PhAllocate(renameInfoSize);
            renameInfo->ReplaceIfExists = FiArgForce;
            renameInfo->RootDirectory = NULL;
            renameInfo->FileNameLength = (ULONG)newFileName->Length;
            memcpy(renameInfo->FileName, newFileName->Buffer, newFileName->Length);

            status = NtSetInformationFile(fileHandle, &isb, renameInfo, renameInfoSize, FileRenameInformation);
            PhFree(renameInfo);

            if (!NT_SUCCESS(status))
            {
                wprintf(L"Error renaming file: %s\n", PhGetNtMessage(status)->Buffer);
            }

            NtClose(fileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"copy", TRUE))
    {
        HANDLE fileHandle;
        HANDLE outFileHandle;
        LARGE_INTEGER fileSize;
        FILE_BASIC_INFORMATION basicInfo;

        if (!FiArgOutput)
        {
            wprintf(L"Error: output file name missing.\n");
            FiPrintHelp();
            return 1;
        }

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | FILE_READ_DATA | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT
            ) && FiCreateFile(
            &outFileHandle,
            FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA | SYNCHRONIZE,
            FiArgOutput,
            0,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            !FiArgForce ? FILE_CREATE : FILE_OVERWRITE_IF,
            FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
#define COPY_BUFFER_SIZE 0x10000
            IO_STATUS_BLOCK isb;
            PVOID buffer;
            ULONG64 bytesToCopy = FiArgLength;

            if (NT_SUCCESS(PhGetFileSize(fileHandle, &fileSize)))
            {
                PhSetFileSize(outFileHandle, &fileSize);
            }

            buffer = PhAllocatePage(COPY_BUFFER_SIZE, NULL);

            if (!buffer)
            {
                wprintf(L"Error allocating buffer.\n");
                return 1;
            }

            while (bytesToCopy)
            {
                status = NtReadFile(
                    fileHandle,
                    NULL,
                    NULL,
                    NULL,
                    &isb,
                    buffer,
                    bytesToCopy >= COPY_BUFFER_SIZE ? COPY_BUFFER_SIZE : (ULONG)bytesToCopy,
                    NULL,
                    NULL
                    );

                if (status == STATUS_END_OF_FILE)
                {
                    break;
                }
                else if (!NT_SUCCESS(status))
                {
                    wprintf(L"Error reading from file: %s\n", PhGetNtMessage(status)->Buffer);
                    break;
                }

                status = NtWriteFile(
                    outFileHandle,
                    NULL,
                    NULL,
                    NULL,
                    &isb,
                    buffer,
                    (ULONG)isb.Information, // number of bytes read
                    NULL,
                    NULL
                    );

                if (!NT_SUCCESS(status))
                {
                    wprintf(L"Error writing to output file: %s\n", PhGetNtMessage(status)->Buffer);
                    break;
                }

                bytesToCopy -= (ULONG)isb.Information;
            }

            PhFreePage(buffer);

            // Copy basic attributes over.
            if (NT_SUCCESS(NtQueryInformationFile(
                fileHandle,
                &isb,
                &basicInfo,
                sizeof(FILE_BASIC_INFORMATION),
                FileBasicInformation
                )))
            {
                NtSetInformationFile(
                    outFileHandle,
                    &isb,
                    &basicInfo,
                    sizeof(FILE_BASIC_INFORMATION),
                    FileBasicInformation
                    );
            }

            NtClose(fileHandle);
            NtClose(outFileHandle);
        }
    }
    else if (PhEqualString2(FiArgAction, L"dir", TRUE))
    {
        HANDLE fileHandle;
        UNICODE_STRING pattern;
        PPH_STRING totalSize, totalAllocSize;

        if (FiCreateFile(
            &fileHandle,
            FILE_LIST_DIRECTORY | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            FipDirFileCount = 0;
            FipDirDirCount = 0;
            FipDirTotalSize = 0;
            FipDirTotalAllocSize = 0;

            if (FiArgPattern)
                PhStringRefToUnicodeString(&FiArgPattern->sr, &pattern);

            PhEnumDirectoryFile(
                fileHandle,
                FiArgPattern ? &pattern : NULL,
                FipEnumDirectoryFileForDir,
                NULL
                );
            NtClose(fileHandle);

            totalSize = PhFormatUInt64(FipDirTotalSize, TRUE);
            totalAllocSize = PhFormatUInt64(FipDirTotalAllocSize, TRUE);

            wprintf(
                L"%12I64u file(s)  %11s bytes\n"
                L"%12I64u dir(s)   %11s bytes allocated\n",
                FipDirFileCount,
                totalSize->Buffer,
                FipDirDirCount,
                totalAllocSize->Buffer
                );

            PhDereferenceObject(totalSize);
            PhDereferenceObject(totalAllocSize);
        }
    }
    else if (PhEqualString2(FiArgAction, L"streams", TRUE))
    {
        HANDLE fileHandle;
        PVOID streams;
        PFILE_STREAM_INFORMATION stream;

        if (FiCreateFile(
            &fileHandle,
            FILE_READ_ATTRIBUTES | SYNCHRONIZE,
            FiArgFileName,
            0,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            FILE_OPEN,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
            ))
        {
            if (NT_SUCCESS(PhEnumFileStreams(fileHandle, &streams)))
            {
                stream = PH_FIRST_STREAM(streams);

                while (stream)
                {
                    PPH_STRING size, allocationSize;

                    size = PhFormatUInt64(stream->StreamSize.QuadPart, TRUE);
                    allocationSize = PhFormatUInt64(stream->StreamAllocationSize.QuadPart, TRUE);

                    wprintf(
                        L"%11s %11s %.*s\n",
                        size->Buffer,
                        allocationSize->Buffer,
                        stream->StreamNameLength / 2,
                        stream->StreamName
                        );

                    PhDereferenceObject(size);
                    PhDereferenceObject(allocationSize);

                    stream = PH_NEXT_STREAM(stream);
                }
            }

            NtClose(fileHandle);
        }
    }
    else
    {
        wprintf(L"Error: invalid action \"%s\".\n", FiArgAction->Buffer);
        FiPrintHelp();
        return 1;
    }
}
Example #9
0
//@@@@@@@@@@@@@@@@@@@@@@@@
// IRQL = passive level
//@@@@@@@@@@@@@@@@@@@@@@@@@
extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT  pDriverObject, IN PUNICODE_STRING RegistryPath )
{	
	NTSTATUS Status = {0};
	
	DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n");
 		
	/////////////////////////////////////////////////////////////////////////////////////////
	// Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) 
	/////////////////////////////////////////////////////////////////////////////////////////
	
	// For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which
	// we are hooking except for those we are interested in modifying.
	for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
		pDriverObject->MajorFunction[i] = DispatchPassDown;
	DbgPrint("Filled dispatch table with generic pass down routine...\n");

	//Explicitly fill in the IRP's we want to hook
	pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
	
	//Go ahead and hook the keyboard now
	HookKeyboard(pDriverObject);
	DbgPrint("Hooked IRP_MJ_READ routine...\n");

	//Set up our worker thread to handle file writes of the scan codes extracted from the 
	//read IRPs
	InitThreadKeyLogger(pDriverObject);

	//Initialize the linked list that will serve as a queue to hold the captured keyboard scan codes
	PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; 
	InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);

	//Initialize the lock for the linked list queue
	KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);

	//Initialize the work queue semaphore
	KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0 , MAXLONG);

	//Create the log file
	IO_STATUS_BLOCK file_status;
	OBJECT_ATTRIBUTES obj_attrib;
	CCHAR		 ntNameFile[64] = "\\DosDevices\\c:\\klog.txt";
    STRING		 ntNameString;
	UNICODE_STRING uFileName;
    RtlInitAnsiString( &ntNameString, ntNameFile);
    RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE );
	InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
	Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status,
							NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);
	RtlFreeUnicodeString(&uFileName);

	if (Status != STATUS_SUCCESS)
	{
		DbgPrint("Failed to create log file...\n");
		DbgPrint("File Status = %x\n",file_status);
	}
	else
	{
		DbgPrint("Successfully created log file...\n");
		DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile);
	}

	// Set the DriverUnload procedure
	pDriverObject->DriverUnload = Unload;
	DbgPrint("Set DriverUnload function pointer...\n");
	DbgPrint("Exiting Driver Entry......\n");
	return STATUS_SUCCESS;
}
Example #10
0
NTSTATUS
LpxTdiOpenConnection (
	OUT PHANDLE					ConnectionFileHandle, 
	OUT	PFILE_OBJECT			*ConnectionFileObject,
	IN PVOID					ConnectionContext
	)
{
	HANDLE						connectionFileHandle; 
	PFILE_OBJECT				connectionFileObject;

    UNICODE_STRING				nameString;
    OBJECT_ATTRIBUTES			objectAttributes;
	UCHAR						eaFullBuffer[CONNECTION_EA_BUFFER_LENGTH];
	PFILE_FULL_EA_INFORMATION	eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer;
	INT							i;
	IO_STATUS_BLOCK				ioStatusBlock;
    NTSTATUS					status;
    

    LtDebugPrint (3, ("[LpxTdi] LpxTdiOpenConnection:  Entered\n"));

	//
	// Init object attributes
	//

    RtlInitUnicodeString (&nameString, TRANSPORT_NAME);
    InitializeObjectAttributes (
        &objectAttributes,
        &nameString,
        0,
        NULL,
        NULL
		);

	
	RtlZeroMemory(eaBuffer, CONNECTION_EA_BUFFER_LENGTH);
    eaBuffer->NextEntryOffset	= 0;
    eaBuffer->Flags				= 0;
    eaBuffer->EaNameLength		= TDI_CONNECTION_CONTEXT_LENGTH;
	eaBuffer->EaValueLength		= sizeof (PVOID);

    for (i=0;i<(int)eaBuffer->EaNameLength;i++) {
        eaBuffer->EaName[i] = TdiConnectionContext[i];
    }
    
    RtlMoveMemory (
        &eaBuffer->EaName[TDI_CONNECTION_CONTEXT_LENGTH+1],
        &ConnectionContext,
        sizeof (PVOID)
		);

	status = ZwCreateFile(
				&connectionFileHandle,
				GENERIC_READ,
				&objectAttributes,
				&ioStatusBlock,
				NULL,
				FILE_ATTRIBUTE_NORMAL,
				0,
				0,
				0,
				eaBuffer,
				CONNECTION_EA_BUFFER_LENGTH
				);

    if (!NT_SUCCESS(status)) {
        LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection:  FAILURE, NtCreateFile returned status code=%x\n", status));
		*ConnectionFileHandle = NULL;
		*ConnectionFileObject = NULL;
        return status;
    }

    status = ioStatusBlock.Status;

    if (!NT_SUCCESS(status)) {
        LtDebugPrint (0, ("[LpxTdi] TdiOpenConnection:  FAILURE, IoStatusBlock.Status contains status code=%x\n", status));
		*ConnectionFileHandle = NULL;
		*ConnectionFileObject = NULL;
		return status;
    }

    status = ObReferenceObjectByHandle (
                connectionFileHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &connectionFileObject,
                NULL
				);

    if (!NT_SUCCESS(status)) {
        LtDebugPrint(0, ("[LpxTdi] TdiOpenConnection:  ObReferenceObjectByHandle() FAILED %x\n", status));
		ZwClose(connectionFileHandle);
		*ConnectionFileHandle = NULL;
		*ConnectionFileObject = NULL;
        return status;
    }
	 
	*ConnectionFileHandle = connectionFileHandle;
	*ConnectionFileObject = connectionFileObject;

	LtDebugPrint (3, ("[LpxTdi] LpxOpenConnection:  returning\n"));

    return status;
} /* LpxOpenConnection */
Example #11
0
BOOLEAN FiCreateFile(
    _Out_ PHANDLE FileHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_ PPH_STRING FileName,
    _In_opt_ ULONG FileAttributes,
    _In_ ULONG ShareAccess,
    _In_ ULONG CreateDisposition,
    _In_opt_ ULONG Options
    )
{
    NTSTATUS status;
    HANDLE fileHandle;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK isb;
    PPH_STRING fileName;
    UNICODE_STRING fileNameUs;

    if (!FileAttributes)
        FileAttributes = FILE_ATTRIBUTE_NORMAL;
    if (!Options)
        Options = FILE_SYNCHRONOUS_IO_NONALERT;

    // Not needed, because we handle Win32 paths anyway.
    //if (!(FiArgNative))
    //{
    //    status = PhCreateFileWin32(
    //        FileHandle,
    //        FileName->Buffer,
    //        DesiredAccess,
    //        FileAttributes,
    //        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    //        CreateDisposition,
    //        Options
    //        );

    //    if (!NT_SUCCESS(status))
    //    {
    //        wprintf(L"Error creating/opening file: %s\n", PhGetNtMessage(status)->Buffer);
    //        return FALSE;
    //    }

    //    return TRUE;
    //}

    fileName = FiFormatFileName(FileName);

    if (!PhStringRefToUnicodeString(&fileName->sr, &fileNameUs))
    {
        PhDereferenceObject(fileName);
        return FALSE;
    }

    InitializeObjectAttributes(
        &oa,
        &fileNameUs,
        (!FiArgCaseSensitive ? OBJ_CASE_INSENSITIVE : 0),
        NULL,
        NULL
        );

    status = NtCreateFile(
        &fileHandle,
        DesiredAccess,
        &oa,
        &isb,
        NULL,
        FileAttributes,
        ShareAccess,
        CreateDisposition,
        Options,
        NULL,
        0
        );

    if (!NT_SUCCESS(status))
    {
        wprintf(L"Error creating/opening file: %s\n", PhGetNtMessage(status)->Buffer);
        return FALSE;
    }

    *FileHandle = fileHandle;

    return TRUE;
}
Example #12
0
NTSTATUS
LpxTdiOpenAddress(
	OUT	PHANDLE				AddressFileHandle,
	OUT	PFILE_OBJECT		*AddressFileObject,
	IN	PTDI_ADDRESS_LPX	Address
	)
{
	HANDLE						addressFileHandle; 
	PFILE_OBJECT				addressFileObject;

    UNICODE_STRING				nameString;
    OBJECT_ATTRIBUTES			objectAttributes;
	UCHAR						eaFullBuffer[ADDRESS_EA_BUFFER_LENGTH];
	PFILE_FULL_EA_INFORMATION	eaBuffer = (PFILE_FULL_EA_INFORMATION)eaFullBuffer;
	PTRANSPORT_ADDRESS			transportAddress;
    PTA_ADDRESS					taAddress;
	PTDI_ADDRESS_LPX			lpxAddress;
	INT							i;
	IO_STATUS_BLOCK				ioStatusBlock;
    NTSTATUS					status;

    LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress:  Entered\n"));

	//
	// Init object attributes
	//

    RtlInitUnicodeString (&nameString, TRANSPORT_NAME);
    InitializeObjectAttributes (
        &objectAttributes,
        &nameString,
        0,
        NULL,
        NULL
		);

	RtlZeroMemory(eaBuffer, ADDRESS_EA_BUFFER_LENGTH);
    eaBuffer->NextEntryOffset	= 0;
    eaBuffer->Flags				= 0;
    eaBuffer->EaNameLength		= TDI_TRANSPORT_ADDRESS_LENGTH;
	eaBuffer->EaValueLength		= FIELD_OFFSET(TRANSPORT_ADDRESS, Address)
									+ FIELD_OFFSET(TA_ADDRESS, Address)
									+ TDI_ADDRESS_LENGTH_LPX;

    for (i=0;i<(int)eaBuffer->EaNameLength;i++) {
        eaBuffer->EaName[i] = TdiTransportAddress[i];
    }

	transportAddress = (PTRANSPORT_ADDRESS)&eaBuffer->EaName[eaBuffer->EaNameLength+1];
	transportAddress->TAAddressCount = 1;

    taAddress = (PTA_ADDRESS)transportAddress->Address;
    taAddress->AddressType		= TDI_ADDRESS_TYPE_LPX;
    taAddress->AddressLength	= TDI_ADDRESS_LENGTH_LPX;

    lpxAddress = (PTDI_ADDRESS_LPX)taAddress->Address;

	RtlCopyMemory(
		lpxAddress,
		Address,
		sizeof(TDI_ADDRESS_LPX)
		);

	//
	// Open Address File
	//
	status = ZwCreateFile(
				&addressFileHandle,
				GENERIC_READ,
				&objectAttributes,
				&ioStatusBlock,
				NULL,
				FILE_ATTRIBUTE_NORMAL,
				0,
				0,
				0,
				eaBuffer,
				ADDRESS_EA_BUFFER_LENGTH 
				);
	
	if (!NT_SUCCESS(status)) {
	    LtDebugPrint (0,("TdiOpenAddress:  FAILURE, NtCreateFile returned status code=%x.\n", status));
		*AddressFileHandle = NULL;
		*AddressFileObject = NULL;
		return status;
	}

    status = ioStatusBlock.Status;

    if (!NT_SUCCESS(status)) {
        LtDebugPrint (0, ("TdiOpenAddress:  FAILURE, IoStatusBlock.Status contains status code=%x\n", status));
		*AddressFileHandle = NULL;
		*AddressFileObject = NULL;
		return status;
    }

    status = ObReferenceObjectByHandle (
                addressFileHandle,
                0L,
                NULL,
                KernelMode,
                (PVOID *) &addressFileObject,
                NULL
				);

    if (!NT_SUCCESS(status)) {
        LtDebugPrint(0,("\n****** Send Test:  FAILED on open of server Connection: %x ******\n", status));
		ZwClose(addressFileHandle);
		*AddressFileHandle = NULL;
		*AddressFileObject = NULL;
        return status;
    }
    
	*AddressFileHandle = addressFileHandle;
	*AddressFileObject = addressFileObject;

	LtDebugPrint (3, ("[LpxTdi] TdiOpenAddress:  returning\n"));

	return status;
}
Example #13
0
NTSTATUS
SampCleanup18471(
    )
/*++

Routine Description:

    Cleans up the transaction log left by fixing bug 18471.  This routine
    builds a transaction with all the keys in the log and then commits
    the transaction

Arguments:

    None.

Return Value:

    Status codes from the NT registry APIs and NT RXact APIs

--*/
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE RootKey = NULL;
    HANDLE AliasKey = NULL;
    UCHAR Buffer[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)];
    UCHAR Buffer2[sizeof(KEY_BASIC_INFORMATION) + 15 * sizeof(WCHAR)];
    UNICODE_STRING KeyName;
    WCHAR KeyBuffer[100];
    PKEY_BASIC_INFORMATION BasicInfo = (PKEY_BASIC_INFORMATION) Buffer;
    PKEY_BASIC_INFORMATION BasicInfo2 = (PKEY_BASIC_INFORMATION) Buffer2;
    ULONG BasicInfoLength;
    ULONG Index, Index2;

    //
    // Open the 18471 key in the registry
    //

    RtlInitUnicodeString(
        &KeyName,
        SAMP_FIX_18471_KEY_NAME
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL
        );

    Status = NtOpenKey(
                &RootKey,
                KEY_READ | DELETE,
                &ObjectAttributes
                );

    if (!NT_SUCCESS(Status)) {

        //
        // If the error was that the key did not exist, then there
        // is nothing to cleanup, so return success.
        //

        if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
            return(STATUS_SUCCESS);
        }
        return(Status);
    }

    //
    // Create a transaction to add all the keys to delete to
    //

    Status = SampAcquireWriteLock();
    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }

    SampSetTransactionDomain(0);
    SampTransactionWithinDomain = FALSE;

    //
    // Now enumerate all the subkeys of the root 18471 key
    //

    Index = 0;
    do
    {

        Status = NtEnumerateKey(
                    RootKey,
                    Index,
                    KeyBasicInformation,
                    BasicInfo,
                    sizeof(Buffer),
                    &BasicInfoLength
                    );
        //
        //
        // Check if this is the RXACT key. If it is, we don't want
        // to add it to the delete log.
        //
        // Otherwise open this key and enumerate all the subkeys of it.
        //

        if (NT_SUCCESS(Status) &&
            ((BasicInfo->NameLength != RTLP_RXACT_KEY_NAME_SIZE) ||
                memcmp(
                    BasicInfo->Name,
                    RTLP_RXACT_KEY_NAME,
                    RTLP_RXACT_KEY_NAME_SIZE
                    ) ) ) {

            KeyName.Buffer = BasicInfo->Name;
            KeyName.Length = (USHORT) BasicInfo->NameLength;
            KeyName.MaximumLength = KeyName.Length;

            InitializeObjectAttributes(
                &ObjectAttributes,
                &KeyName,
                OBJ_CASE_INSENSITIVE,
                RootKey,
                NULL
                );

            //
            // Open the key for the alias rid.  This really should
            // succeed
            //

            Status = NtOpenKey(
                        &AliasKey,
                        KEY_READ,
                        &ObjectAttributes
                        );
            if (!NT_SUCCESS(Status)) {
                break;
            }

            //
            // Enumerate all the subkeys (the alias members) and add them
            // to the transaction
            //

            Index2 = 0;
            do
            {
                Status = NtEnumerateKey(
                            AliasKey,
                            Index2,
                            KeyBasicInformation,
                            BasicInfo2,
                            sizeof(Buffer2),
                            &BasicInfoLength
                            );
                if (NT_SUCCESS(Status)) {

                    //
                    // Build the name of this key from the alias rid and the
                    // member rid
                    //

                    KeyName.Buffer = KeyBuffer;
                    KeyName.MaximumLength = sizeof(KeyBuffer);

                    SampBuild18471CleanupKey(
                        &KeyName,
                        BasicInfo->Name,
                        BasicInfo->NameLength,
                        BasicInfo2->Name,
                        BasicInfo2->NameLength
                        );

                    Status = RtlAddActionToRXact(
                                SampRXactContext,
                                RtlRXactOperationDelete,
                                &KeyName,
                                0,
                                NULL,
                                0
                                );


                }
                Index2++;

            } while (NT_SUCCESS(Status));

            NtClose(AliasKey);
            AliasKey = NULL;

            //
            // If we suffered a serious error, get out of here now
            //

            if (!NT_SUCCESS(Status)) {
                if (Status != STATUS_NO_MORE_ENTRIES) {
                    break;
                } else {
                    Status = STATUS_SUCCESS;
                }
            }

            //
            // Add the alias RID key to the RXact now - we need to add it
            // after deleting all the children
            //

            KeyName.Buffer = KeyBuffer;
            KeyName.MaximumLength = sizeof(KeyBuffer);
            SampBuild18471CleanupKey(
                &KeyName,
                BasicInfo->Name,
                BasicInfo->NameLength,
                NULL,
                0
                );


            Status = RtlAddActionToRXact(
                        SampRXactContext,
                        RtlRXactOperationDelete,
                        &KeyName,
                        0,
                        NULL,
                        0
                        );

        }

        Index++;
    } while (NT_SUCCESS(Status));

    if (Status == STATUS_NO_MORE_ENTRIES) {
        Status = STATUS_SUCCESS;
    }

    if (!NT_SUCCESS(Status)) {
        goto Cleanup;
    }


    RtlInitUnicodeString(
        &KeyName,
        SAMP_FIX_18471_SHORT_KEY_NAME
        );

    Status = RtlAddActionToRXact(
                SampRXactContext,
                RtlRXactOperationDelete,
                &KeyName,
                0,
                NULL,
                0
                );

    if (NT_SUCCESS(Status)) {

        //
        // Write the new server revision to indicate that this
        // upgrade has been performed
        //

        ULONG Revision = SAMP_SERVER_REVISION;
        PSAMP_OBJECT ServerContext;

        //
        // We need to read the fixed attributes of the server objects.
        // Create a context to do that.
        //

        ServerContext = SampCreateContext( SampServerObjectType, TRUE );

        if ( ServerContext != NULL ) {

            ServerContext->RootKey = SampKey;

            Status = SampSetFixedAttributes(
                        ServerContext,
                        &Revision
                        );
            if (NT_SUCCESS(Status)) {
                Status = SampStoreObjectAttributes(
                            ServerContext,
                            TRUE
                            );
            }

            SampDeleteContext( ServerContext );
        } else {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }


    //
    // Apply the RXACT and delete the remaining keys.
    //

Cleanup:

    //
    // Cleanup any floating bits from above.
    //

    if (NT_SUCCESS(Status)) {
        Status = SampReleaseWriteLock( TRUE );
    } else {
        (VOID) SampReleaseWriteLock( FALSE );
    }

    if (RootKey != NULL) {
        NtClose(RootKey);
    }

    ASSERT(AliasKey == NULL);


    return(Status);

}
Example #14
0
NTSTATUS
SampCheckMemberUpgradedFor18471(
    IN ULONG AliasRid,
    IN ULONG MemberRid
    )
/*++

Routine Description:

    This routine checks if the SAM upgrade flag is set. The upgrade
    flag is:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa
        UpgradeSam = REG_DWORD 1


Arguments:


Return Value:

    TRUE - The flag was set

    FALSE - The flag was not set or the value was not present

--*/
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE KeyHandle;
    NTSTATUS Status;
    WCHAR KeyName[100];
    WCHAR AliasName[15]; // big enough for 4 billion
    UNICODE_STRING KeyNameString;
    UNICODE_STRING AliasString;


    //
    // Build the full key name.  It is of the form:
    // "fix18471\alias_rid\member_rid"
    //

    wcscpy(
        KeyName,
        SAMP_FIX_18471_KEY_NAME L"\\"
        );

    AliasString.Buffer = AliasName;
    AliasString.MaximumLength = sizeof(AliasName);
    Status = RtlIntegerToUnicodeString(
                AliasRid,
                16,
                &AliasString
                );
    ASSERT(NT_SUCCESS(Status));

    wcscat(
        KeyName,
        AliasString.Buffer
        );

    wcscat(
        KeyName,
        L"\\"
        );

    AliasString.MaximumLength = sizeof(AliasName);
    Status = RtlIntegerToUnicodeString(
                MemberRid,
                16,
                &AliasString
                );
    ASSERT(NT_SUCCESS(Status));

    wcscat(
        KeyName,
        AliasString.Buffer
        );

    RtlInitUnicodeString(
        &KeyNameString,
        KeyName
        );


    //
    // Open the member  key in the registry
    //


    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyNameString,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL
        );

    Status = NtOpenKey(
                &KeyHandle,
                KEY_READ,
                &ObjectAttributes
                );

    NtClose(KeyHandle);
    return(Status);

}
Example #15
0
struct file *filp_open(const char *name, int flags, int mode, int *err)
{
	struct file *fp = NULL;

    NTSTATUS            Status;

    OBJECT_ATTRIBUTES   ObjectAttributes;
    HANDLE              FileHandle;
    IO_STATUS_BLOCK     IoStatus;
    ACCESS_MASK         DesiredAccess;
    ULONG               CreateDisposition;
    ULONG               ShareAccess;
    ULONG               CreateOptions;

    USHORT              NameLength = 0;
    USHORT              PrefixLength = 0;

    UNICODE_STRING      UnicodeName;
    PWCHAR              UnicodeString = NULL;

    ANSI_STRING         AnsiName;
    PUCHAR              AnsiString = NULL;

    /* Analyze the flags settings */
    if (cfs_is_flag_set(flags, O_WRONLY)) {
        DesiredAccess = (GENERIC_WRITE | SYNCHRONIZE);
        ShareAccess = 0;
    }  else if (cfs_is_flag_set(flags, O_RDWR)) {
        DesiredAccess = (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE);
        ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE;
    } else {
        DesiredAccess = (GENERIC_READ | SYNCHRONIZE);
        ShareAccess = FILE_SHARE_READ;
    }

    if (cfs_is_flag_set(flags, O_CREAT)) {
        if (cfs_is_flag_set(flags, O_EXCL)) {
            CreateDisposition = FILE_CREATE;
        } else {
            CreateDisposition = FILE_OPEN_IF;
        }
    } else {
        CreateDisposition = FILE_OPEN;
    }

    if (cfs_is_flag_set(flags, O_TRUNC)) {
        if (cfs_is_flag_set(flags, O_EXCL)) {
            CreateDisposition = FILE_OVERWRITE;
        } else {
            CreateDisposition = FILE_OVERWRITE_IF;
        }
    }

    CreateOptions = 0;

    if (cfs_is_flag_set(flags, O_DIRECTORY)) {
        cfs_set_flag(CreateOptions,  FILE_DIRECTORY_FILE);
    }

    if (cfs_is_flag_set(flags, O_SYNC)) {
         cfs_set_flag(CreateOptions, FILE_WRITE_THROUGH);
    }

    if (cfs_is_flag_set(flags, O_DIRECT)) {
         cfs_set_flag(CreateOptions, FILE_NO_INTERMEDIATE_BUFFERING);
    }

    /* Initialize the unicode path name for the specified file */
    NameLength = (USHORT)strlen(name);

	/* Check file & path name */
	if (name[0] != '\\') {
		if (NameLength < 1 || name[1] != ':' ||
		    !is_drv_letter_valid(name[0])) {
			/* invalid file path name */
			return ERR_PTR(-EINVAL);
		}
		PrefixLength = (USHORT)strlen(dos_file_prefix[0]);
	} else {
		int i, j;
		for (i = 0; i < 3 && dos_file_prefix[i] != NULL; i++) {
			j = strlen(dos_file_prefix[i]);
			if (NameLength > j &&
			    _strnicmp(dos_file_prefix[i], name, j) == 0)
				break;
		}
		if (i >= 3)
			return ERR_PTR(-EINVAL);
	}

	AnsiString = kmalloc(sizeof(CHAR) * (NameLength + PrefixLength + 1),
				__GFP_ZERO);
	if (NULL == AnsiString)
		return ERR_PTR(-ENOMEM);

	UnicodeString =
		kmalloc(sizeof(WCHAR) * (NameLength + PrefixLength + 1),
			  __GFP_ZERO);
	if (NULL == UnicodeString) {
		kfree(AnsiString);
		return ERR_PTR(-ENOMEM);
	}

    if (PrefixLength) {
        RtlCopyMemory(&AnsiString[0], dos_file_prefix[0], PrefixLength);
    }

    RtlCopyMemory(&AnsiString[PrefixLength], name, NameLength);
    NameLength += PrefixLength;

    AnsiName.MaximumLength = NameLength + 1;
    AnsiName.Length = NameLength;
    AnsiName.Buffer = AnsiString;

    UnicodeName.MaximumLength = (NameLength + 1) * sizeof(WCHAR);
    UnicodeName.Length = 0;
    UnicodeName.Buffer = (PWSTR)UnicodeString;

    RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);

    /* Setup the object attributes structure for the file. */
    InitializeObjectAttributes(
            &ObjectAttributes,
            &UnicodeName,
            OBJ_CASE_INSENSITIVE |
            OBJ_KERNEL_HANDLE,
            NULL,
            NULL );

    /* Now to open or create the file now */
    Status = ZwCreateFile(
            &FileHandle,
            DesiredAccess,
            &ObjectAttributes,
            &IoStatus,
            0,
            FILE_ATTRIBUTE_NORMAL,
            ShareAccess,
            CreateDisposition,
            CreateOptions,
            NULL,
            0 );

	/* Check the returned status of IoStatus... */
	if (!NT_SUCCESS(IoStatus.Status)) {
		kfree(UnicodeString);
		kfree(AnsiString);
		return ERR_PTR(cfs_error_code(IoStatus.Status));
	}

	/* Allocate the file_t: libcfs file object */
	fp = kmalloc(sizeof(*fp) + NameLength, __GFP_ZERO);

	if (NULL == fp) {
		Status = ZwClose(FileHandle);
		ASSERT(NT_SUCCESS(Status));
		kfree(UnicodeString);
		kfree(AnsiString);
		return ERR_PTR(-ENOMEM);
	}

    fp->f_handle = FileHandle;
    strcpy(fp->f_name, name);
    fp->f_flags = flags;
    fp->f_mode  = (mode_t)mode;
    fp->f_count = 1;

	/* free the memory of temporary name strings */
	kfree(UnicodeString);
	kfree(AnsiString);

	return fp;
}
Example #16
0
NTSTATUS 
DraidStart(
	PDRAID_GLOBALS DraidGlobals
) {
	NTSTATUS		status;
	OBJECT_ATTRIBUTES  objectAttributes;
#if 0
	TDI_CLIENT_INTERFACE_INFO   info;
	UNICODE_STRING              clientName;
#endif

	KDPrintM(DBG_LURN_INFO, ("Starting\n"));
	
	InitializeListHead(&DraidGlobals->ArbiterList);
	KeInitializeSpinLock(&DraidGlobals->ArbiterListSpinlock);
	InitializeListHead(&DraidGlobals->ClientList);
	KeInitializeSpinLock(&DraidGlobals->ClientListSpinlock);
	KeInitializeEvent(&DraidGlobals->DraidExitEvent, NotificationEvent, FALSE);	
	KeInitializeEvent(&DraidGlobals->NetChangedEvent, NotificationEvent, FALSE);		

	InitializeListHead(&DraidGlobals->ListenContextList);
	KeInitializeSpinLock(&DraidGlobals->ListenContextSpinlock);

	InitializeObjectAttributes(
		&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

	g_DraidGlobals = DraidGlobals;

	status = PsCreateSystemThread(
		&DraidGlobals->DraidThreadHandle,
		THREAD_ALL_ACCESS,
		&objectAttributes,
		NULL,
		NULL,
		DraidListenerThreadProc,
		DraidGlobals
		);
	if(!NT_SUCCESS(status)) {
		ASSERT(FALSE);
	
		DraidGlobals->DraidThreadHandle = NULL;
		DraidGlobals->DraidThreadObject = NULL;
		return STATUS_UNSUCCESSFUL;
	}

	status = ObReferenceObjectByHandle(
			DraidGlobals->DraidThreadHandle,
			FILE_READ_DATA,
			NULL,
			KernelMode,
			&DraidGlobals->DraidThreadObject,
			NULL
		);
	if(!NT_SUCCESS(status)) {
		ASSERT(FALSE);
		DraidGlobals->DraidThreadObject = NULL;
		DraidGlobals->DraidThreadHandle = NULL;
		return STATUS_UNSUCCESSFUL;
	}
	
	return STATUS_SUCCESS;
}
Example #17
0
/*
 @implemented
*/
NTSTATUS
NTAPI
RtlCreateUserThread(IN HANDLE ProcessHandle,
                    IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
                    IN BOOLEAN CreateSuspended,
                    IN ULONG StackZeroBits OPTIONAL,
                    IN SIZE_T StackReserve OPTIONAL,
                    IN SIZE_T StackCommit OPTIONAL,
                    IN PTHREAD_START_ROUTINE StartAddress,
                    IN PVOID Parameter OPTIONAL,
                    OUT PHANDLE ThreadHandle OPTIONAL,
                    OUT PCLIENT_ID ClientId OPTIONAL)
{
    NTSTATUS Status;
    HANDLE Handle;
    CLIENT_ID ThreadCid;
    INITIAL_TEB InitialTeb;
    OBJECT_ATTRIBUTES ObjectAttributes;
    CONTEXT Context;

    /* First, we'll create the Stack */
    Status = RtlpCreateUserStack(ProcessHandle,
                                 StackReserve,
                                 StackCommit,
                                 StackZeroBits,
                                 &InitialTeb);
    if (!NT_SUCCESS(Status)) return Status;

    /* Next, we'll set up the Initial Context */
    RtlInitializeContext(ProcessHandle,
                         &Context,
                         Parameter,
                         StartAddress,
                         InitialTeb.StackBase);

    /* We are now ready to create the Kernel Thread Object */
    InitializeObjectAttributes(&ObjectAttributes,
                               NULL,
                               0,
                               NULL,
                               SecurityDescriptor);
    Status = ZwCreateThread(&Handle,
                            THREAD_ALL_ACCESS,
                            &ObjectAttributes,
                            ProcessHandle,
                            &ThreadCid,
                            &Context,
                            &InitialTeb,
                            CreateSuspended);
    if (!NT_SUCCESS(Status))
    {
        /* Free the stack */
        RtlpFreeUserStack(ProcessHandle, &InitialTeb);
    }
    else
    {
        /* Return thread data */
        if (ThreadHandle)
            *ThreadHandle = Handle;
        else
            NtClose(Handle);
        if (ClientId) *ClientId = ThreadCid;
    }

    /* Return success or the previous failure */
    return Status;
}
Example #18
0
//
// Start reception thread to handle registration request from client.
//
NTSTATUS
DraidAcceptConnection(
	PDRAID_GLOBALS DraidGlobals,
	PDRAID_LISTEN_CONTEXT ListenContext
) {
	PDRAID_REMOTE_CLIENT_CONNECTION Connection;
	HANDLE			ConFileHandle;
	PFILE_OBJECT		ConFileObject;
	LPX_ADDRESS	RemoteAddr;
	NTSTATUS	status;
	OBJECT_ATTRIBUTES objectAttributes;
	HANDLE		ThreadHandle;
	
	if (ListenContext->TdiListenContext.Status != STATUS_SUCCESS) {
		// Failed to accept connection. Maybe NIC is disabled. This context will be handled by DraidStopListenAddr
		KDPrintM(DBG_LURN_INFO, ("Failed to listen. Maybe network is down.\n"));	
		return STATUS_UNSUCCESSFUL;
	}

	//
	// Get information about new connection and prepare for new listening.
	//
	ConFileHandle = ListenContext->ListenFileHandle;
	ConFileObject = ListenContext->ListenFileObject;
	RtlCopyMemory(&RemoteAddr, &ListenContext->TdiListenContext.RemoteAddress, sizeof(LPX_ADDRESS));
	
	ListenContext->TdiListenContext.Irp = NULL;
	ListenContext->ListenFileHandle = NULL;
	ListenContext->ListenFileObject = NULL;

	KDPrintM(DBG_LURN_INFO, 
		("Connected from %02X:%02X:%02X:%02X:%02X:%02X 0x%4X\n",
						RemoteAddr.Node[0], RemoteAddr.Node[1],
						RemoteAddr.Node[2], RemoteAddr.Node[3],
						RemoteAddr.Node[4], RemoteAddr.Node[5],
						NTOHS(RemoteAddr.Port)
	));

	status = DraidListenConnection(ListenContext);
	if (!NT_SUCCESS(status)) {
		KDPrintM(DBG_LURN_INFO, ("Failed to listen again\n"));		
		ASSERT(FALSE);
		// Continue anyway even if anothre listening is failure
	}
	
	//
	// Now we can Handle accpeted connection.
	//
	Connection = ExAllocatePoolWithTag(NonPagedPool, 
		sizeof(DRAID_REMOTE_CLIENT_CONNECTION), DRAID_REMOTE_CLIENT_CHANNEL_POOL_TAG);

	if (!Connection) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	RtlZeroMemory(Connection, sizeof(DRAID_REMOTE_CLIENT_CONNECTION));
	Connection->ConnectionFileHandle = ConFileHandle;
	Connection->ConnectionFileObject = ConFileObject;
	RtlCopyMemory(&Connection->RemoteAddr, &RemoteAddr, sizeof(LPX_ADDRESS));

	// Start reception thread.
	InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

	ASSERT(KeGetCurrentIrql() ==  PASSIVE_LEVEL);
	
	status = PsCreateSystemThread(
		&ThreadHandle,
		THREAD_ALL_ACCESS,
		&objectAttributes,
		NULL,
		NULL,
		DraidReceptionThreadProc,
		(PVOID) Connection
		);

	if(!NT_SUCCESS(status))
	{
		KDPrintM(DBG_LURN_ERROR, ("Reception thread creation failedPsCreateSystemThread FAIL %x\n", status));
		ExFreePoolWithTag(Connection, DRAID_REMOTE_CLIENT_CHANNEL_POOL_TAG);
		return status;
	}

	ZwClose(ThreadHandle);  // Reception thread will be exited by itself. Close now.

	InterlockedIncrement(&DraidGlobals->ReceptionThreadCount);

	return STATUS_SUCCESS;
}
Example #19
0
static BOOLEAN
GetComputerIdentifier(PWSTR Identifier,
                      ULONG IdentifierLength)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    LPCWSTR ComputerIdentifier;
    HANDLE ProcessorsKey;
    PKEY_FULL_INFORMATION pFullInfo;
    ULONG Size, SizeNeeded;
    NTSTATUS Status;

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

    Size = sizeof(KEY_FULL_INFORMATION);
    pFullInfo = (PKEY_FULL_INFORMATION)RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
    if (!pFullInfo)
    {
        DPRINT("RtlAllocateHeap() failed\n");
        return FALSE;
    }

    /* Open the processors key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenKey(&ProcessorsKey,
                       KEY_QUERY_VALUE ,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("NtOpenKey() failed (Status 0x%lx)\n", Status);
        RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
        return FALSE;
    }

    /* Get number of subkeys */
    Status = NtQueryKey(
        ProcessorsKey,
        KeyFullInformation,
        pFullInfo,
        Size,
        &Size);
    NtClose(ProcessorsKey);

    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
    {
        DPRINT("NtQueryKey() failed (Status 0x%lx)\n", Status);
        RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
        return FALSE;
    }

    /* Find computer identifier */
    if (pFullInfo->SubKeys == 0)
    {
        /* Something strange happened. No processor detected */
        RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);
        return FALSE;
    }

    if (IsAcpiComputer())
    {
        if (pFullInfo->SubKeys == 1)
        {
            /* Computer is mono-CPU */
            ComputerIdentifier = L"ACPI UP";
        }
        else
        {
            /* Computer is multi-CPUs */
            ComputerIdentifier = L"ACPI MP";
        }
    }
    else
    {
        if (pFullInfo->SubKeys == 1)
        {
            /* Computer is mono-CPU */
            ComputerIdentifier = L"PC UP";
        }
        else
        {
            /* Computer is multi-CPUs */
            ComputerIdentifier = L"PC MP";
        }
    }

    RtlFreeHeap(RtlGetProcessHeap(), 0, pFullInfo);

    /* Copy computer identifier to return buffer */
    SizeNeeded = (wcslen(ComputerIdentifier) + 1) * sizeof(WCHAR);
    if (SizeNeeded > IdentifierLength)
        return FALSE;

    RtlCopyMemory(Identifier, ComputerIdentifier, SizeNeeded);

    return TRUE;
}
Example #20
0
NTSTATUS
LogfCreate(PLOGFILE* LogFile,
           PCWSTR    LogName,
           PUNICODE_STRING FileName,
           ULONG     MaxSize,
           ULONG     Retention,
           BOOLEAN   Permanent,
           BOOLEAN   Backup)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStdInfo;
    PLOGFILE pLogFile;
    SIZE_T LogNameLen;
    BOOLEAN CreateNew;

    pLogFile = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pLogFile));
    if (!pLogFile)
    {
        DPRINT1("Cannot allocate heap!\n");
        return STATUS_NO_MEMORY;
    }

    LogNameLen = (LogName ? wcslen(LogName) : 0) + 1;
    pLogFile->LogName = RtlAllocateHeap(GetProcessHeap(),
                                        HEAP_ZERO_MEMORY,
                                        LogNameLen * sizeof(WCHAR));
    if (pLogFile->LogName == NULL)
    {
        DPRINT1("Cannot allocate heap\n");
        Status = STATUS_NO_MEMORY;
        goto Quit;
    }

    if (LogName)
        StringCchCopyW(pLogFile->LogName, LogNameLen, LogName);

    InitializeObjectAttributes(&ObjectAttributes,
                               FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    DPRINT1("Going to create or open %wZ\n", FileName);
    Status = NtCreateFile(&pLogFile->FileHandle,
                          Backup ? (GENERIC_READ | SYNCHRONIZE)
                                 : (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE),
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ,
                          Backup ? FILE_OPEN : FILE_OPEN_IF,
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Cannot create file `%wZ' (Status 0x%08lx)\n", FileName, Status);
        goto Quit;
    }

    CreateNew = (IoStatusBlock.Information == FILE_CREATED);
    DPRINT1("%wZ %s successfully\n", FileName, CreateNew ? "created" : "opened");

    /*
     * Retrieve the log file size and check whether the file is not too large;
     * this log format only supports files of theoretical size < 0xFFFFFFFF .
     *
     * As it happens that, on Windows (and ReactOS), retrieving the End-Of-File
     * information using NtQueryInformationFile with the FileEndOfFileInformation
     * class is invalid (who knows why...), use instead the FileStandardInformation
     * class, and the EndOfFile member of the returned FILE_STANDARD_INFORMATION
     * structure will give the desired information.
     */
    Status = NtQueryInformationFile(pLogFile->FileHandle,
                                    &IoStatusBlock,
                                    &FileStdInfo,
                                    sizeof(FileStdInfo),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("EventLog: NtQueryInformationFile failed (Status 0x%08lx)\n", Status);
        goto Quit;
    }
    if (FileStdInfo.EndOfFile.HighPart != 0)
    {
        DPRINT1("EventLog: Log `%wZ' is too large.\n", FileName);
        Status = STATUS_EVENTLOG_FILE_CORRUPT; // STATUS_FILE_TOO_LARGE;
        goto Quit;
    }

    DPRINT("Initializing LogFile `%S'\n", pLogFile->LogName);

    Status = ElfCreateFile(&pLogFile->LogFile,
                           FileName,
                           FileStdInfo.EndOfFile.LowPart,
                           MaxSize,
                           Retention,
                           CreateNew,
                           Backup,
                           LogfpAlloc,
                           LogfpFree,
                           LogfpSetFileSize,
                           LogfpWriteFile,
                           LogfpReadFile,
                           LogfpFlushFile);
    if (!NT_SUCCESS(Status))
        goto Quit;

    pLogFile->Permanent = Permanent;

    RtlInitializeResource(&pLogFile->Lock);

    LogfListAddItem(pLogFile);

Quit:
    if (!NT_SUCCESS(Status))
    {
        if (pLogFile->FileHandle != NULL)
            NtClose(pLogFile->FileHandle);

        if (pLogFile->LogName)
            RtlFreeHeap(GetProcessHeap(), 0, pLogFile->LogName);

        RtlFreeHeap(GetProcessHeap(), 0, pLogFile);
    }
    else
    {
        *LogFile = pLogFile;
    }

    return Status;
}
Example #21
0
static BOOLEAN
GetDisplayIdentifier(PWSTR Identifier,
    ULONG IdentifierLength)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING KeyName;
    WCHAR Buffer[32];
    HANDLE BusKey;
    HANDLE BusInstanceKey;
    HANDLE ControllerKey;
    HANDLE ControllerInstanceKey;
    ULONG BusInstance;
    ULONG ControllerInstance;
    ULONG BufferLength;
    ULONG ReturnedLength;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
    NTSTATUS Status;

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

    /* Open the bus key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\HARDWARE\\Description\\System\\MultifunctionAdapter");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenKey(&BusKey,
                       KEY_ENUMERATE_SUB_KEYS,
                       &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
        return FALSE;
    }

    BusInstance = 0;
    while (TRUE)
    {
        swprintf(Buffer, L"%lu", BusInstance);
        RtlInitUnicodeString(&KeyName,
                             Buffer);
        InitializeObjectAttributes(&ObjectAttributes,
                                   &KeyName,
                                   OBJ_CASE_INSENSITIVE,
                                   BusKey,
                                   NULL);

        Status = NtOpenKey(&BusInstanceKey,
                           KEY_ENUMERATE_SUB_KEYS,
                           &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
            NtClose(BusKey);
            return FALSE;
        }

        /* Open the controller type key */
        RtlInitUnicodeString(&KeyName,
                             L"DisplayController");
        InitializeObjectAttributes(&ObjectAttributes,
                                   &KeyName,
                                   OBJ_CASE_INSENSITIVE,
                                   BusInstanceKey,
                                   NULL);

        Status = NtOpenKey(&ControllerKey,
                           KEY_ENUMERATE_SUB_KEYS,
                           &ObjectAttributes);
        if (NT_SUCCESS(Status))
        {
            ControllerInstance = 0;

            while (TRUE)
            {
                /* Open the pointer controller instance key */
                swprintf(Buffer, L"%lu", ControllerInstance);
                RtlInitUnicodeString(&KeyName,
                                     Buffer);
                InitializeObjectAttributes(&ObjectAttributes,
                                           &KeyName,
                                           OBJ_CASE_INSENSITIVE,
                                           ControllerKey,
                                           NULL);

                Status = NtOpenKey(&ControllerInstanceKey,
                                   KEY_QUERY_VALUE,
                                   &ObjectAttributes);
                if (!NT_SUCCESS(Status))
                {
                    DPRINT("NtOpenKey() failed (Status %lx)\n", Status);
                    NtClose(ControllerKey);
                    NtClose(BusInstanceKey);
                    NtClose(BusKey);
                    return FALSE;
                }

                /* Get controller identifier */
                RtlInitUnicodeString(&KeyName,
                                     L"Identifier");

                BufferLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
                               256 * sizeof(WCHAR);
                ValueInfo = (KEY_VALUE_PARTIAL_INFORMATION*) RtlAllocateHeap(RtlGetProcessHeap(),
                                                                             0,
                                                                             BufferLength);
                if (ValueInfo == NULL)
                {
                    DPRINT("RtlAllocateHeap() failed\n");
                    NtClose(ControllerInstanceKey);
                    NtClose(ControllerKey);
                    NtClose(BusInstanceKey);
                    NtClose(BusKey);
                    return FALSE;
                }

                Status = NtQueryValueKey(ControllerInstanceKey,
                                         &KeyName,
                                         KeyValuePartialInformation,
                                         ValueInfo,
                                         BufferLength,
                                         &ReturnedLength);
                if (NT_SUCCESS(Status))
                {
                    DPRINT("Identifier: %S\n", (PWSTR)ValueInfo->Data);

                    BufferLength = min(ValueInfo->DataLength / sizeof(WCHAR), IdentifierLength);
                    RtlCopyMemory (Identifier,
                                   ValueInfo->Data,
                                   BufferLength * sizeof(WCHAR));
                    Identifier[BufferLength] = 0;

                    RtlFreeHeap(RtlGetProcessHeap(),
                                0,
                                ValueInfo);

                    NtClose(ControllerInstanceKey);
                    NtClose(ControllerKey);
                    NtClose(BusInstanceKey);
                    NtClose(BusKey);
                    return TRUE;
                }

                NtClose(ControllerInstanceKey);

                ControllerInstance++;
            }

            NtClose(ControllerKey);
        }

        NtClose(BusInstanceKey);

        BusInstance++;
    }

    NtClose(BusKey);

    return FALSE;
}
Example #22
0
PFILEVIEW
NTAPI
EngLoadModuleEx(
    LPWSTR pwsz,
    ULONG cjSizeOfModule,
    FLONG fl)
{
    PFILEVIEW pFileView = NULL;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE hRootDir;
    UNICODE_STRING ustrFileName;
    IO_STATUS_BLOCK IoStatusBlock;
    FILE_BASIC_INFORMATION FileInformation;
    HANDLE hFile;
    NTSTATUS Status;
    LARGE_INTEGER liSize;

    if (fl & FVF_FONTFILE)
    {
        pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG');
    }
    else
    {
        pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg');
    }

    /* Check for success */
    if (!pFileView) return NULL;

    /* Check if the file is relative to system32 */
    if (fl & FVF_SYSTEMROOT)
    {
        hRootDir = ghSystem32Directory;
    }
    else
    {
        hRootDir = ghRootDirectory;
    }

    /* Initialize unicode string and object attributes */
    RtlInitUnicodeString(&ustrFileName, pwsz);
    InitializeObjectAttributes(&ObjectAttributes,
                               &ustrFileName,
                               OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
                               hRootDir,
                               NULL);

    /* Now open the file */
    Status = ZwCreateFile(&hFile,
                          FILE_READ_DATA,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OPEN,
                          FILE_NON_DIRECTORY_FILE,
                          NULL,
                          0);

    Status = ZwQueryInformationFile(hFile,
                                    &IoStatusBlock,
                                    &FileInformation,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (NT_SUCCESS(Status))
    {
        pFileView->LastWriteTime = FileInformation.LastWriteTime;
    }

    /* Create a section from the file */
    liSize.QuadPart = cjSizeOfModule;
    Status = MmCreateSection(&pFileView->pSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &liSize,
                             fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE,
                             SEC_COMMIT,
                             hFile,
                             NULL);

    /* Close the file handle */
    ZwClose(hFile);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to create a section Status=0x%x\n", Status);
        EngFreeMem(pFileView);
        return NULL;
    }


    pFileView->pvKView = NULL;
    pFileView->pvViewFD = NULL;
    pFileView->cjView = 0;

    return pFileView;
}
Example #23
0
BOOL
GetDllList(VOID)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Attributes;
    BOOL bRet = FALSE;
    BOOL bLoad;
    HANDLE hKey = NULL;
    DWORD dwSize;
    PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = NULL;

    UNICODE_STRING szKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
    UNICODE_STRING szLoadName = RTL_CONSTANT_STRING(L"LoadAppInit_DLLs");
    UNICODE_STRING szDllsName = RTL_CONSTANT_STRING(L"AppInit_DLLs");

    InitializeObjectAttributes(&Attributes, &szKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    Status = NtOpenKey(&hKey, KEY_READ, &Attributes);
    if (NT_SUCCESS(Status))
    {
        dwSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD);
        kvpInfo = HeapAlloc(GetProcessHeap(), 0, dwSize);
        if (!kvpInfo)
            goto end;

        Status = NtQueryValueKey(hKey,
                                 &szLoadName,
                                 KeyValuePartialInformation,
                                 kvpInfo,
                                 dwSize,
                                 &dwSize);
        if (!NT_SUCCESS(Status))
            goto end;

        RtlMoveMemory(&bLoad,
                      kvpInfo->Data,
                      kvpInfo->DataLength);

        HeapFree(GetProcessHeap(), 0, kvpInfo);
        kvpInfo = NULL;

        if (bLoad)
        {
            Status = NtQueryValueKey(hKey,
                                     &szDllsName,
                                     KeyValuePartialInformation,
                                     NULL,
                                     0,
                                     &dwSize);
            if (Status != STATUS_BUFFER_TOO_SMALL)
                goto end;

            kvpInfo = HeapAlloc(GetProcessHeap(), 0, dwSize);
            if (!kvpInfo)
                goto end;

            Status = NtQueryValueKey(hKey,
                                     &szDllsName,
                                     KeyValuePartialInformation,
                                     kvpInfo,
                                     dwSize,
                                     &dwSize);
            if (NT_SUCCESS(Status))
            {
                LPWSTR lpBuffer = (LPWSTR)kvpInfo->Data;
                if (*lpBuffer != UNICODE_NULL)
                {
                    INT bytesToCopy, nullPos;

                    bytesToCopy = min(kvpInfo->DataLength, KEY_LENGTH * sizeof(WCHAR));

                    if (bytesToCopy != 0)
                    {
                        RtlMoveMemory(szAppInit,
                                      kvpInfo->Data,
                                      bytesToCopy);

                        nullPos = (bytesToCopy / sizeof(WCHAR)) - 1;

                        /* ensure string is terminated */
                        szAppInit[nullPos] = UNICODE_NULL;

                        bRet = TRUE;
                    }
                }
            }
        }
    }

end:
    if (hKey)
        NtClose(hKey);

    if (kvpInfo)
        HeapFree(GetProcessHeap(), 0, kvpInfo);

    return bRet;
}
Example #24
0
INT WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ PWSTR lpCmdLine,
    _In_ INT nCmdShow
    )
{
    LONG result;
#ifdef DEBUG
    PHP_BASE_THREAD_DBG dbg;
#endif
    HANDLE currentTokenHandle;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
#ifndef DEBUG
    SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#endif

    PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress;

    if (!NT_SUCCESS(PhInitializePhLib()))
        return 1;
    if (!PhInitializeAppSystem())
        return 1;

    PhInitializeCommonControls();

    currentTokenHandle = PhGetOwnTokenAttributes().TokenHandle;

    if (currentTokenHandle)
    {
        PTOKEN_USER tokenUser;

        if (NT_SUCCESS(PhGetTokenUser(currentTokenHandle, &tokenUser)))
        {
            PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL);
            PhFree(tokenUser);
        }
    }

    PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL);

    // There has been a report of the above call failing.
    if (!PhLocalSystemName)
        PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM");

    PhApplicationFileName = PhGetApplicationFileName();
    PhApplicationDirectory = PhGetApplicationDirectory();

    // Just in case
    if (!PhApplicationFileName)
        PhApplicationFileName = PhCreateString(L"ProcessHacker.exe");
    if (!PhApplicationDirectory)
        PhApplicationDirectory = PhReferenceEmptyString();

    PhpProcessStartupParameters();
    PhSettingsInitialization();
    PhpEnablePrivileges();

    if (PhStartupParameters.RunAsServiceMode)
    {
        RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode));
    }

    PhpInitializeSettings();

    // Activate a previous instance if required.
    if (PhGetIntegerSetting(L"AllowOnlyOneInstance") &&
        !PhStartupParameters.NewInstance &&
        !PhStartupParameters.ShowOptions &&
        !PhStartupParameters.CommandMode &&
        !PhStartupParameters.PhSvc)
    {
        PhActivatePreviousInstance();
    }

    if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64())
        PhInitializeKph();

    if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction)
    {
        NTSTATUS status;

        status = PhCommandModeStart();

        if (!NT_SUCCESS(status) && !PhStartupParameters.Silent)
        {
            PhShowStatus(NULL, L"Unable to execute the command", status, 0);
        }

        RtlExitUserProcess(status);
    }

#ifdef DEBUG
    dbg.ClientId = NtCurrentTeb()->ClientId;
    dbg.StartAddress = wWinMain;
    dbg.Parameter = NULL;
    InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry);
    TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg);
#endif

    PhInitializeAutoPool(&BaseAutoPool);

    PhEmInitialization();
    PhGuiSupportInitialization();
    PhTreeNewInitialization();
    PhGraphControlInitialization();
    PhHexEditInitialization();
    PhColorBoxInitialization();

    PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON);
    PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON);
    PhLargeIconSize.X = GetSystemMetrics(SM_CXICON);
    PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON);

    if (PhStartupParameters.ShowOptions)
    {
        // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker.
        PhShowOptionsDialog(PhStartupParameters.WindowHandle);
        RtlExitUserProcess(STATUS_SUCCESS);
    }

#ifndef DEBUG
    if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc)
    {
        PhShowWarning(
            NULL,
            L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. "
            L"Most features will not work correctly.\n\n"
            L"Please run the 64-bit version of Process Hacker instead."
            );
    }
#endif

    PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins;

    if (PhPluginsEnabled)
    {
        PhPluginsInitialization();
        PhLoadPlugins();
    }

    if (PhStartupParameters.PhSvc)
    {
        MSG message;

        // Turn the feedback cursor off.
        PostMessage(NULL, WM_NULL, 0, 0);
        GetMessage(&message, NULL, 0, 0);

        RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL));
    }

    // Create a mutant for the installer.
    {
        HANDLE mutantHandle;
        OBJECT_ATTRIBUTES oa;
        UNICODE_STRING mutantName;

        RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant");
        InitializeObjectAttributes(
            &oa,
            &mutantName,
            0,
            NULL,
            NULL
            );

        NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE);
    }

    // Set priority.
    {
        PROCESS_PRIORITY_CLASS priorityClass;

        priorityClass.Foreground = FALSE;
        priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;

        if (PhStartupParameters.PriorityClass != 0)
            priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass;

        NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS));
    }

    if (!PhMainWndInitialization(nCmdShow))
    {
        PhShowError(NULL, L"Unable to initialize the main window.");
        return 1;
    }

    PhDrainAutoPool(&BaseAutoPool);

    result = PhMainMessageLoop();
    RtlExitUserProcess(result);
}
Example #25
0
// This function is even more a hack
// It will remove the dll from the Debug manager
// but vs.net does not unload the symbols (don't know why)
// The dll can be loaded again after unloading.
// This function leaks memory.
void DllLoader::UnloadSymbols()
{
#ifdef ENABLE_SYMBOL_UNLOADING
  ANSI_STRING name;
  OBJECT_ATTRIBUTES attributes;
  RtlInitAnsiString(&name, GetName());
  InitializeObjectAttributes(&attributes, &name, OBJ_CASE_INSENSITIVE, NULL);

  // Try to unload the symbols from vs.net debugger
  DbgUnLoadImageSymbols(&name, (ULONG)hModule, 0xFFFFFFFF);

  LPVOID pBaseAddress=GetXbdmBaseAddress();

  if (pBaseAddress)
  {
    CoffLoader dllxbdm;
    if (dllxbdm.ParseHeaders(pBaseAddress))
    {
      int offset=GetDmiOffset(dllxbdm.WindowsHeader->CheckSum);

      if (offset==0)
      {
        CLog::Log(LOGDEBUG,"DllLoader: Unable to unload symbols for %s. No offset for xbdm.dll with checksum 0x%08X found", GetName(), dllxbdm.WindowsHeader->CheckSum);
        return;
      }

      try
      {
        std::wstring strNameW;
        g_charsetConverter.utf8ToW(GetName(), strNameW);

        // Get the address of the global struct g_dmi
        // It is located inside the xbdm.dll and
        // get the LoadedModuleList member (here the entry var)
        // of the structure.
        LPBYTE g_dmi=((LPBYTE)pBaseAddress)+offset;
        LIST_ENTRY* entry=(LIST_ENTRY*)(g_dmi+4);

        //  Search for the dll we are unloading...
        while (entry)
        {
          std::wstring baseName=(wchar_t*)((LDR_DATA_TABLE_ENTRY*)entry)->BaseDllName.Buffer;
          if (baseName == strNameW)
          {
            // ...and remove it from the LoadedModuleList and free its memory.
            LIST_ENTRY* back=entry->Blink;
            LIST_ENTRY* front=entry->Flink;
            back->Flink=front;
            front->Blink=back;
            DmFreePool(entry);
            break;
          }

          entry=entry->Flink;
        }
      }
      catch(...)
      {
        CLog::Log(LOGDEBUG,"DllLoader: Unloading symbols for %s failed with an exception.", GetName());
      }
    }
  }
  else
    CLog::Log(LOGDEBUG,"DllLoader: Can't unload symbols for %s. xbdm.dll is needed and not loaded", GetName());
#endif
}
DualErr	
DuplicateProcessToken(PGPUInt32 procId, PHANDLE pDupedToken)
{
	CLIENT_ID			clientId;
	DualErr				derr;
	HANDLE				procHandle, token;
	NTSTATUS			status;
	OBJECT_ATTRIBUTES	objAttribs;
	PGPBoolean			openedProcess, openedToken;

	openedProcess = openedToken = FALSE;

	pgpAssertAddrValid(pDupedToken, HANDLE);

	InitializeObjectAttributes(&objAttribs, NULL, 0, NULL, NULL);

	clientId.UniqueThread = NULL;
	clientId.UniqueProcess = (PVOID) procId;

	// Open a handle to the process.
	status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &objAttribs, 
		&clientId);

	if (!NT_SUCCESS(status))
	{
		derr = DualErr(kPGDMinorError_ZwOpenProcessFailed, status);
	}

	openedProcess = derr.IsntError();

	// Open a handle to the process token.
	if (derr.IsntError())
	{
		status = ZwOpenProcessToken(procHandle, TOKEN_ALL_ACCESS, &token);

		if (!NT_SUCCESS(status))
		{
			derr = DualErr(kPGDMinorError_ZwOpenProcessTokenFailed, status);
		}

		openedToken = derr.IsntError();
	}

	// Duplicate the token.
	if (derr.IsntError())
	{
		SECURITY_QUALITY_OF_SERVICE SQOS;

		SQOS.Length = sizeof(SQOS);
		SQOS.ImpersonationLevel = SecurityImpersonation;
		SQOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
		SQOS.EffectiveOnly = FALSE;

		objAttribs.SecurityQualityOfService = (PVOID) &SQOS;

		status = ZwDuplicateToken(token, TOKEN_QUERY | TOKEN_IMPERSONATE, 
			&objAttribs, SecurityAnonymous, TokenImpersonation, pDupedToken);

		if (!NT_SUCCESS(status))
		{
			derr = DualErr(kPGDMinorError_ZwDuplicateTokenFailed, status);
		}
	}

	if (openedToken)
		ZwClose(token);

	if (openedProcess)
		ZwClose(procHandle);

	return derr;
}
Example #27
0
NTSTATUS KphHashFile(
    __in PUNICODE_STRING FileName,
    __out PVOID *Hash,
    __out PULONG HashSize
    )
{
    NTSTATUS status;
    BCRYPT_ALG_HANDLE hashAlgHandle = NULL;
    ULONG querySize;
    ULONG hashObjectSize;
    ULONG hashSize;
    PVOID hashObject = NULL;
    PVOID hash = NULL;
    BCRYPT_HASH_HANDLE hashHandle = NULL;
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iosb;
    HANDLE fileHandle = NULL;
    FILE_STANDARD_INFORMATION standardInfo;
    ULONG remainingBytes;
    ULONG bytesToRead;
    PVOID buffer = NULL;

    PAGED_CODE();

    // Open the hash algorithm and allocate memory for the hash object.

    if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, KPH_HASH_ALGORITHM, NULL, 0)))
        goto CleanupExit;
    if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH,
        (PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0)))
    {
        goto CleanupExit;
    }
    if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize,
        sizeof(ULONG), &querySize, 0)))
    {
        goto CleanupExit;
    }

    if (!(hashObject = ExAllocatePoolWithTag(PagedPool, hashObjectSize, 'vhpK')))
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto CleanupExit;
    }
    if (!(hash = ExAllocatePoolWithTag(PagedPool, hashSize, 'vhpK')))
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto CleanupExit;
    }

    if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize,
        NULL, 0, 0)))
    {
        goto CleanupExit;
    }

    // Open the file and compute the hash.

    InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL);

    if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes,
        &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN,
        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
    {
        goto CleanupExit;
    }

    if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo,
        sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)))
    {
        goto CleanupExit;
    }

    if (standardInfo.EndOfFile.QuadPart <= 0)
    {
        status = STATUS_UNSUCCESSFUL;
        goto CleanupExit;
    }
    if (standardInfo.EndOfFile.QuadPart > FILE_MAX_SIZE)
    {
        status = STATUS_FILE_TOO_LARGE;
        goto CleanupExit;
    }

    if (!(buffer = ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'vhpK')))
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto CleanupExit;
    }

    remainingBytes = (ULONG)standardInfo.EndOfFile.QuadPart;

    while (remainingBytes != 0)
    {
        bytesToRead = FILE_BUFFER_SIZE;
        if (bytesToRead > remainingBytes)
            bytesToRead = remainingBytes;

        if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, bytesToRead,
            NULL, NULL)))
        {
            goto CleanupExit;
        }
        if ((ULONG)iosb.Information != bytesToRead)
        {
            status = STATUS_INTERNAL_ERROR;
            goto CleanupExit;
        }

        if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, bytesToRead, 0)))
            goto CleanupExit;

        remainingBytes -= bytesToRead;
    }

    if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0)))
        goto CleanupExit;

    if (NT_SUCCESS(status))
    {
        *Hash = hash;
        *HashSize = hashSize;

        hash = NULL; // Don't free this in the cleanup section
    }

CleanupExit:
    if (buffer)
        ExFreePoolWithTag(buffer, 'vhpK');
    if (fileHandle)
        ZwClose(fileHandle);
    if (hashHandle)
        BCryptDestroyHash(hashHandle);
    if (hash)
        ExFreePoolWithTag(hash, 'vhpK');
    if (hashObject)
        ExFreePoolWithTag(hashObject, 'vhpK');
    if (hashAlgHandle)
        BCryptCloseAlgorithmProvider(hashAlgHandle, 0);

    return status;
}
Example #28
0
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
                     IN PUNICODE_STRING RegistryPath)
/*++

Routine Description:

    This routine is called when the driver is loaded by NT.

Arguments:

    DriverObject - Pointer to driver object created by system.
    RegistryPath - Pointer to the name of the services node for this driver.

Return Value:

    The function value is the final status from the initialization operation.

--*/
{
	
	
    NTSTATUS        ntStatus;
    PVOID           BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL;
    UNICODE_STRING  uszDriverString;
    
    UNICODE_STRING  uszProcessEventString;
	UNICODE_STRING	uszThreadEventString;
    PDEVICE_OBJECT  pDeviceObject;
	HANDLE reg=0;
	OBJECT_ATTRIBUTES oa;

	UNICODE_STRING temp; 
	char wbuf[100]; 
	WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs;
	ULONG cr4reg;

	
	
	criticalSection csTest;

	
	KernelCodeStepping=0;
	

	

	this_cs=getCS();
	this_ss=getSS();
	this_ds=getDS();
	this_es=getES();
	this_fs=getFS();
	this_gs=getGS();	

	DbgPrint("DBK loading...");
#ifdef TOBESIGNED
	DbgPrint("Signed version");
#endif

	
	//lame antiviruses and more lamer users that keep crying rootkit virus....
	temp.Buffer=(PWCH)wbuf;
	temp.Length=0;
	temp.MaximumLength=100;
	
	RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable 
	RtlAppendUnicodeToString(&temp, L"Service");
	RtlAppendUnicodeToString(&temp, L"Descriptor");
	RtlAppendUnicodeToString(&temp, L"Table");
	
	KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp);         

	DbgPrint("Loading driver\n");
	if (RegistryPath)
	{	
		DbgPrint("Registry path = %S\n", RegistryPath->Buffer);

		InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL);
		ntStatus=ZwOpenKey(&reg,KEY_QUERY_VALUE,&oa);
		if (ntStatus == STATUS_SUCCESS)
		{
			UNICODE_STRING A,B,C,D;
			PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD;
			ULONG ActualSize;

			DbgPrint("Opened the key\n");

			BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);
			BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100);

			bufA=BufDriverString;
			bufB=BufDeviceString;
			bufC=BufProcessEventString;
			bufD=BufThreadEventString;

			RtlInitUnicodeString(&A, L"A");
			RtlInitUnicodeString(&B, L"B");
			RtlInitUnicodeString(&C, L"C");
			RtlInitUnicodeString(&D, L"D");

			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);
			if (ntStatus == STATUS_SUCCESS)
				ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize);

			if (ntStatus == STATUS_SUCCESS)
			{
				DbgPrint("Read ok\n");
				RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data);
				RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data);
				RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data);
				RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data);

				DbgPrint("DriverString=%S\n",uszDriverString.Buffer);
				DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer);
				DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer);
				DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer);
			}
			else
			{
				ExFreePool(bufA);
				ExFreePool(bufB);
				ExFreePool(bufC);
				ExFreePool(bufD);

				DbgPrint("Failed reading the value\n");
				ZwClose(reg);
				return STATUS_UNSUCCESSFUL;;
			}

		}
		else
		{
			DbgPrint("Failed opening the key\n");
			return STATUS_UNSUCCESSFUL;;
		}
	}
	else
	  loadedbydbvm=TRUE;

	ntStatus = STATUS_SUCCESS;


	


	if (!loadedbydbvm)
	{

		// Point uszDriverString at the driver name
#ifndef CETC
		
		
		// Create and initialize device object
		ntStatus = IoCreateDevice(DriverObject,
								  0,
								  &uszDriverString,
								  FILE_DEVICE_UNKNOWN,
								  0,
								  FALSE,
								  &pDeviceObject);

		if(ntStatus != STATUS_SUCCESS)
		{
			DbgPrint("IoCreateDevice failed\n");
			ExFreePool(BufDriverString);
			ExFreePool(BufDeviceString);
			ExFreePool(BufProcessEventString);
			ExFreePool(BufThreadEventString);

			
			if (reg)
			  ZwClose(reg);

			return ntStatus;
		}

		// Point uszDeviceString at the device name
		
		// Create symbolic link to the user-visible name
		ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);

		if(ntStatus != STATUS_SUCCESS)
		{
			DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus);
			// Delete device object if not successful
			IoDeleteDevice(pDeviceObject);

			ExFreePool(BufDriverString);
			ExFreePool(BufDeviceString);
			ExFreePool(BufProcessEventString);
			ExFreePool(BufThreadEventString);
			

			if (reg)
			  ZwClose(reg);

			return ntStatus;
		}

#endif
	}

	//when loaded by dbvm driver object is 'valid' so store the function addresses


	DbgPrint("DriverObject=%p\n", DriverObject);

    // Load structure to point to IRP handlers...
    DriverObject->DriverUnload                         = UnloadDriver;
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchClose;	

	if (loadedbydbvm)
		DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM;		
	else
		DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;



	//Processlist init
#ifndef CETC

	ProcessEventCount=0;
	KeInitializeSpinLock(&ProcesslistSL);
#endif

	CreateProcessNotifyRoutineEnabled=FALSE;

	//threadlist init
	ThreadEventCount=0;
	
	BufferSize=0;
	processlist=NULL;

#ifndef AMD64
    //determine if PAE is used
	cr4reg=(ULONG)getCR4();

	if ((cr4reg & 0x20)==0x20)
	{
		PTESize=8; //pae
		PAGE_SIZE_LARGE=0x200000;
		MAX_PDE_POS=0xC0604000;
		MAX_PTE_POS=0xC07FFFF8;

		
	}
	else
	{
		PTESize=4;
		PAGE_SIZE_LARGE=0x400000;
		MAX_PDE_POS=0xC0301000;
		MAX_PTE_POS=0xC03FFFFC;
	}
#else
	PTESize=8; //pae
	PAGE_SIZE_LARGE=0x200000;
	MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL;
	MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL;
#endif

#ifdef CETC
	DbgPrint("Going to initialice CETC\n");
	InitializeCETC();
#endif


    //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen

	DbgPrint("Initializing debugger\n");
	debugger_initialize();


	// Return success (don't do the devicestring, I need it for unload)
	DbgPrint("Cleaning up initialization buffers\n");
	if (BufDriverString)
	{
		ExFreePool(BufDriverString);
		BufDriverString=NULL;
	}

	if (BufProcessEventString)
	{
		ExFreePool(BufProcessEventString);
		BufProcessEventString=NULL;
	}

	if (BufThreadEventString)
	{
		ExFreePool(BufThreadEventString);
		BufThreadEventString=NULL;
	}

	if (reg)
	{
		ZwClose(reg); 
		reg=0;
	}

	

	//fetch cpu info
	{
		DWORD r[4];
		DWORD a;

		__cpuid(r,0);
		DbgPrint("cpuid.0: r[1]=%x", r[1]);
		if (r[1]==0x756e6547) //GenuineIntel
		{

			__cpuid(r,1);

			a=r[0];
			
			cpu_stepping=a & 0xf;
			cpu_model=(a >> 4) & 0xf;
			cpu_familyID=(a >> 8) & 0xf;
			cpu_type=(a >> 12) & 0x3;
			cpu_ext_modelID=(a >> 16) & 0xf;
			cpu_ext_familyID=(a >> 20) & 0xff;

			cpu_model=cpu_model + (cpu_ext_modelID << 4);
			cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4);

			if ((r[2]<<9) & 1)
			{
				DbgPrint("Intel cpu. IA32_FEATURE_CONTROL MSR=%x", readMSR(0x3a));		
			}
			else
			{
				DbgPrint("Intel cpu without IA32_FEATURE_CONTROL MSR");		
			}

			vmx_init_dovmcall(1);
			setup_APIC_BASE(); //for ultimap

		}
		else
		{
Example #29
0
NTSTATUS
NTAPI
CreateBaseAcls(OUT PACL* Dacl,
               OUT PACL* RestrictedDacl)
{
    PSID SystemSid, WorldSid, RestrictedSid;
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
    NTSTATUS Status;
#if 0 // Unused code
    UCHAR KeyValueBuffer[0x40];
    PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
    UNICODE_STRING KeyName;
    ULONG ProtectionMode = 0;
#endif
    ULONG AclLength;
#if 0 // Unused code
    ULONG ResultLength;
    HANDLE hKey;
    OBJECT_ATTRIBUTES ObjectAttributes;

    /* Open the Session Manager Key */
    RtlInitUnicodeString(&KeyName, SM_REG_KEY);
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* Read the key value */
        RtlInitUnicodeString(&KeyName, L"ProtectionMode");
        Status = NtQueryValueKey(hKey,
                                 &KeyName,
                                 KeyValuePartialInformation,
                                 KeyValueBuffer,
                                 sizeof(KeyValueBuffer),
                                 &ResultLength);

        /* Make sure it's what we expect it to be */
        KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
        if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
            (*(PULONG)KeyValuePartialInfo->Data))
        {
            /* Save the Protection Mode */
            ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
        }

        /* Close the handle */
        NtClose(hKey);
    }
#endif

    /* Allocate the System SID */
    Status = RtlAllocateAndInitializeSid(&NtAuthority,
                                         1, SECURITY_LOCAL_SYSTEM_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &SystemSid);
    ASSERT(NT_SUCCESS(Status));

    /* Allocate the World SID */
    Status = RtlAllocateAndInitializeSid(&WorldAuthority,
                                         1, SECURITY_WORLD_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &WorldSid);
    ASSERT(NT_SUCCESS(Status));

    /* Allocate the restricted SID */
    Status = RtlAllocateAndInitializeSid(&NtAuthority,
                                         1, SECURITY_RESTRICTED_CODE_RID,
                                         0, 0, 0, 0, 0, 0, 0,
                                         &RestrictedSid);
    ASSERT(NT_SUCCESS(Status));

    /* Allocate one ACL with 3 ACEs each for one SID */
    AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
                    RtlLengthSid(SystemSid) +
                    RtlLengthSid(WorldSid)  +
                    RtlLengthSid(RestrictedSid);
    *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
    ASSERT(*Dacl != NULL);

    /* Set the correct header fields */
    Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
    ASSERT(NT_SUCCESS(Status));

    /* Give the appropriate rights to each SID */
    /* FIXME: Should check SessionId/ProtectionMode */
    Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
    ASSERT(NT_SUCCESS(Status));
    Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
    ASSERT(NT_SUCCESS(Status));
    Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
    ASSERT(NT_SUCCESS(Status));

    /* Now allocate the restricted DACL */
    *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
    ASSERT(*RestrictedDacl != NULL);

    /* Initialize it */
    Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
    ASSERT(NT_SUCCESS(Status));

    /* And add the same ACEs as before */
    /* FIXME: Not really fully correct */
    Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
    ASSERT(NT_SUCCESS(Status));
    Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
    ASSERT(NT_SUCCESS(Status));
    Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
    ASSERT(NT_SUCCESS(Status));

    /* The SIDs are captured, can free them now */
    RtlFreeSid(RestrictedSid);
    RtlFreeSid(WorldSid);
    RtlFreeSid(SystemSid);
    return Status;
}
Example #30
0
BOOLEAN
SampUpgradeFlagSet(
    )
/*++

Routine Description:

    This routine checks if the SAM upgrade flag is set. The upgrade
    flag is:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa
        UpgradeSam = REG_DWORD 1


Arguments:


Return Value:

    TRUE - The flag was set

    FALSE - The flag was not set or the value was not present

--*/
{
    NTSTATUS NtStatus;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE KeyHandle;
    UCHAR Buffer[100];
    PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) Buffer;
    ULONG KeyValueLength = 100;
    ULONG ResultLength;
    PULONG UpgradeFlag;

    //
    // Open the Lsa key in the registry
    //

    RtlInitUnicodeString(
        &KeyName,
        SAMP_LSA_KEY_NAME
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        OBJ_CASE_INSENSITIVE,
        0,
        NULL
        );

    NtStatus = NtOpenKey(
                &KeyHandle,
                KEY_READ,
                &ObjectAttributes
                );

    if (!NT_SUCCESS(NtStatus)) {
        return(FALSE);
    }

    //
    // Query the Notification Packages value
    //

    RtlInitUnicodeString(
        &KeyName,
        L"UpgradeSam"
        );

    NtStatus = NtQueryValueKey(
                    KeyHandle,
                    &KeyName,
                    KeyValuePartialInformation,
                    KeyValueInformation,
                    KeyValueLength,
                    &ResultLength
                    );

    NtClose(KeyHandle);

    if (!NT_SUCCESS(NtStatus)) {

        return(FALSE);
    }

    //
    // Check that the data is the correct size and type - a ULONG.
    //

    if ((KeyValueInformation->DataLength < sizeof(ULONG)) ||
        (KeyValueInformation->Type != REG_DWORD)) {

        return(FALSE);
    }

    //
    // Check the flag.
    //

    UpgradeFlag = (PULONG) KeyValueInformation->Data;

    if (*UpgradeFlag == 1) {
        return(TRUE);
    }

    return(FALSE);


}