Beispiel #1
0
NTSTATUS
DrDeleteAllKeys(
		HANDLE			ParentKey
){
	NTSTATUS	status;

	status = DrDeleteAllSubKeys(ParentKey);
	if(!NT_SUCCESS(status)) {
		return status;
	}
	status = ZwDeleteKey(ParentKey);

	return status;
}
Beispiel #2
0
NTSTATUS
RegistryDeleteSubKey(
    IN  PHANDLE         Key,
    IN  PCHAR           Name
    )
{
    ANSI_STRING         Ansi;
    UNICODE_STRING      Unicode;
    HANDLE              SubKey;
    NTSTATUS            status;

    RtlInitAnsiString(&Ansi, Name);

    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
    if (!NT_SUCCESS(status))
        goto fail1;

    status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
    if (!NT_SUCCESS(status))
        goto fail2;

    status = ZwDeleteKey(SubKey);
    if (!NT_SUCCESS(status))
        goto fail3;

    ZwClose(SubKey);

    RtlFreeUnicodeString(&Unicode);

    return STATUS_SUCCESS;

fail3:
    ZwClose(SubKey);

fail2:
    RtlFreeUnicodeString(&Unicode);

fail1:
    return status;
}
Beispiel #3
0
void RegDeleteKey(LPWSTR KeyName)
{
	OBJECT_ATTRIBUTES objectAttributes;
	UNICODE_STRING usKeyName;
	NTSTATUS ntStatus;
	HANDLE hRegister;
	RtlInitUnicodeString( &usKeyName, KeyName);
	InitializeObjectAttributes(&objectAttributes,
	                           &usKeyName,
	                           OBJ_CASE_INSENSITIVE,//对大小写敏感
	                           NULL,
	                           NULL );
	ntStatus = ZwOpenKey( &hRegister, KEY_ALL_ACCESS, &objectAttributes);
	if (NT_SUCCESS(ntStatus))
	{
		ntStatus = ZwDeleteKey(hRegister);
		ZwClose(hRegister);
		DbgPrint("ZwDeleteKey success!\n");
	}
	else
	{
		DbgPrint("ZwDeleteKey failed!\n");
	}
}
Beispiel #4
0
BOOLEAN RemoveModule(void)
{
	UNICODE_STRING usKeyName, usServiceName;
	ANSI_STRING asServiceName;
	BOOLEAN fRet = TRUE;
	HANDLE hKey;
	OBJECT_ATTRIBUTES objAttr;
	NTSTATUS status;
	IO_STATUS_BLOCK ioStatusBlock;
	UNICODE_STRING usServicesKey;
	UNICODE_STRING usEnumKeyName;

	RtlInitUnicodeString(&usServicesKey, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
	RtlInitUnicodeString(&usEnumKeyName, L"\\Enum");
	RtlInitUnicodeString(&usKeyName, NULL);

	DBGOUT(("ServiceName ANSI: %s", g_ServiceName));
	RtlInitAnsiString(&asServiceName, g_ServiceName);
	status = RtlAnsiStringToUnicodeString(&usServiceName, &asServiceName, TRUE);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in  RtlAnsiStringToUnicodeString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	DBGOUT(("ServiceName UNICODE: %S", usServiceName.Buffer));
	// Remove our registry entries
	usKeyName.MaximumLength = usServicesKey.Length + usServiceName.Length + usEnumKeyName.Length + sizeof(WCHAR);
	usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG);
	RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
	DBGOUT(("KeyName Length: %d", usKeyName.MaximumLength));

	RtlCopyUnicodeString(&usKeyName, &usServicesKey);
	status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = RtlAppendUnicodeStringToString(&usKeyName, &usEnumKeyName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL);

	DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer));
#ifdef ENABLE_ANTIDETECTION
	status = s_fnZwOpenKey(&hKey, DELETE, &objAttr);
#else
	status = ZwOpenKey(&hKey, DELETE, &objAttr);
#endif
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwDeleteKey(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	// Remove our root key entry now
	RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
	RtlCopyUnicodeString(&usKeyName, &usServicesKey);
	status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
		fRet = FALSE;
		goto end;
	}

	InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL);
	DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer));
#ifdef ENABLE_ANTIDETECTION
	status = s_fnZwOpenKey(&hKey, DELETE, &objAttr);
#else
	status = ZwOpenKey(&hKey, DELETE, &objAttr);
#endif
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwDeleteKey(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status));
		fRet = FALSE;
		goto end;
	}

	if(!_wcsnicmp(g_ImagePath.Buffer, L"system32", 8)) {
		UNICODE_STRING usSysRoot;
		RtlInitUnicodeString(&usSysRoot, L"\\SystemRoot\\");
		// Prepend \SystemRoot\ to the string
		ExFreePool(usKeyName.Buffer);
		usKeyName.MaximumLength = usSysRoot.Length + g_ImagePath.Length + sizeof(WCHAR);
		usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG);
		RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength);
		RtlCopyUnicodeString(&usKeyName, &usSysRoot);
		status = RtlAppendUnicodeStringToString(&usKeyName, &g_ImagePath);
		if(!NT_SUCCESS(status)) {
			DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status));
			fRet = FALSE;
			goto end;
		}

		InitializeObjectAttributes(&objAttr, &usKeyName,  OBJ_CASE_INSENSITIVE, NULL, NULL);
	} else {
		// Use whatever was there
		InitializeObjectAttributes(&objAttr, &g_ImagePath,  OBJ_CASE_INSENSITIVE, NULL, NULL);
	}
	// Remove our file
	DBGOUT(("Removing file %S", objAttr.ObjectName->Buffer));

	status = ZwCreateFile(&hKey, DELETE, &objAttr, &ioStatusBlock, (PLARGE_INTEGER)NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_DELETE_ON_CLOSE, 0, 0);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwCreateFile %08x!", status));
		fRet = FALSE;
		goto end;
	}

	status = ZwClose(hKey);
	if(!NT_SUCCESS(status)) {
		DBGOUT(("RemoveModule: Unable to ZwClose File %08x!", status));
		fRet = FALSE;
		goto end;
	}

end:
	RtlFreeUnicodeString(&usServiceName);
	ExFreePool(usKeyName.Buffer);
	return fRet;
}
Beispiel #5
0
void otPlatSettingsWipe(otInstance *otCtx)
{
    NT_ASSERT(otCtx);
    PMS_FILTER pFilter = otCtxToFilter(otCtx);

    LogFuncEntry(DRIVER_DEFAULT);

    // Delete all subkeys of 'OpenThread'
    if (pFilter->otSettingsRegKey)
    {
        NTSTATUS status = STATUS_SUCCESS;
        ULONG index = 0;
        UCHAR keyInfo[sizeof(KEY_BASIC_INFORMATION) + 64];

        while (status == STATUS_SUCCESS)
        {
            ULONG size = sizeof(keyInfo);
            status =
                ZwEnumerateKey(
                    pFilter->otSettingsRegKey,
                    index,
                    KeyBasicInformation,
                    keyInfo,
                    size,
                    &size);

            bool deleted = false;
            if (NT_SUCCESS(status))
            {
                HANDLE subKey = NULL;
                OBJECT_ATTRIBUTES attributes;
                PKEY_BASIC_INFORMATION pKeyInfo = (PKEY_BASIC_INFORMATION)keyInfo;

                UNICODE_STRING subKeyName = 
                {
                    (USHORT)pKeyInfo->NameLength,
                    (USHORT)pKeyInfo->NameLength,
                    pKeyInfo->Name
                };

                InitializeObjectAttributes(
                    &attributes,
                    &subKeyName,
                    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                    pFilter->otSettingsRegKey,
                    NULL);

                // Open the sub key
                status =
                    ZwOpenKey(
                        &subKey,
                        KEY_ALL_ACCESS,
                        &attributes);

                if (NT_SUCCESS(status))
                {
                    // Delete the key
                    status = ZwDeleteKey(subKey);
                    if (!NT_SUCCESS(status))
                    {
                        LogError(DRIVER_DEFAULT, "ZwDeleteKey for subkey failed, %!STATUS!", status);
                    }
                    else
                    {
                        deleted = true;
                    }

                    // Close handle
                    ZwClose(subKey);
                }
                else
                {
                    LogError(DRIVER_DEFAULT, "ZwOpenKey for subkey failed, %!STATUS!", status);
                }
            }

            // Only increment index if we didn't delete
            if (!deleted)
            {
                index++;
            }
        }
    }

    LogFuncExit(DRIVER_DEFAULT);
}
Beispiel #6
0
NTSTATUS FilterDeleteSetting(_In_ PMS_FILTER pFilter, uint16_t aKey, int aIndex)
{
    HANDLE regKey = NULL;
    OBJECT_ATTRIBUTES attributes;
    DECLARE_UNICODE_STRING_SIZE(Name, 20);

    // Convert 'aKey' to a string
    RtlIntegerToUnicodeString((ULONG)aKey, 16, &Name);

    InitializeObjectAttributes(
        &attributes,
        &Name,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        pFilter->otSettingsRegKey,
        NULL);

    // Open the registry key
    NTSTATUS status =
        ZwOpenKey(
            &regKey,
            KEY_ALL_ACCESS,
            &attributes);

    if (!NT_SUCCESS(status))
    {
        // Key doesn't exist
        goto error;
    }

    // If 'aIndex' is -1 then delete the whole key, otherwise delete the individual value
    if (aIndex == -1)
    {
        // Delete the registry key
        status = ZwDeleteKey(regKey);
    }
    else
    {
        UCHAR KeyInfoBuffer[128] = { 0 };
        PKEY_FULL_INFORMATION pKeyInfo = (PKEY_FULL_INFORMATION)KeyInfoBuffer;
        ULONG KeyInfoLength = sizeof(KeyInfoBuffer);

        // When deleting an individual value, since order doesn't matter, we will actually
        // copy the last value over the one being deleted and then delete the last value; so
        // we maintain a contiguous list of numbered values

        // Query the number of values
        // Note: Can't use helper function because we already have the key open
        status =
            ZwQueryKey(
                regKey,
                KeyValueFullInformation,
                pKeyInfo,
                KeyInfoLength,
                &KeyInfoLength);

        if (!NT_SUCCESS(status))
        {
            LogError(DRIVER_DEFAULT, "ZwQueryKey for %S value failed, %!STATUS!", Name.Buffer, status);
            goto error;
        }

        if ((ULONG)aIndex >= pKeyInfo->Values)
        {
            // Attempt to delete beyond the end of the list
            status = STATUS_OBJECT_NAME_NOT_FOUND;
            goto error;
        }
        else if (pKeyInfo->Values == 1)
        {
            // Deleting the only value on the key, go ahead and delete the entire key
            status = ZwDeleteKey(regKey);
        }
        else if (pKeyInfo->Values - 1 != (ULONG)aIndex)
        {
            // We aren't deleting the last value so we need to copy the last value
            // over this one, and then delete the last one.

            PKEY_VALUE_PARTIAL_INFORMATION pValueInfo = NULL;
            ULONG ValueInfoLength = 0;

            // Convert pKeyInfo->Values-1 to a string
            RtlIntegerToUnicodeString(pKeyInfo->Values - 1, 16, &Name);

            // Query the key data buffer size
            status = ZwQueryValueKey(
                regKey,
                &Name,
                KeyValuePartialInformation,
                pValueInfo,
                0,
                &ValueInfoLength);

            NT_ASSERT(status != STATUS_SUCCESS);
            if (status != STATUS_BUFFER_TOO_SMALL)
            {
                LogVerbose(DRIVER_DEFAULT, "ZwQueryValueKey for %S value failed, %!STATUS!", Name.Buffer, status);
                goto error;
            }

            pValueInfo = FILTER_ALLOC_MEM(pFilter->FilterHandle, ValueInfoLength);
            if (pValueInfo == NULL)
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
                goto error;
            }

            // Query the data buffer
            status = ZwQueryValueKey(
                regKey,
                &Name,
                KeyValuePartialInformation,
                pValueInfo,
                ValueInfoLength,
                &ValueInfoLength);

            if (!NT_SUCCESS(status))
            {
                LogError(DRIVER_DEFAULT, "ZwQueryValueKey for %S value failed, %!STATUS!", Name.Buffer, status);
                goto cleanup;
            }

            // Delete the registry value
            status =
                ZwDeleteValueKey(
                    regKey,
                    &Name);

            if (!NT_SUCCESS(status))
            {
                LogError(DRIVER_DEFAULT, "ZwDeleteValueKey for %S value failed, %!STATUS!", Name.Buffer, status);
                goto cleanup;
            }

            // Convert 'aIndex' to a string
            RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name);

            // Write the data to the registry key we are deleting
            status =
                ZwSetValueKey(
                    regKey,
                    &Name,
                    0,
                    REG_BINARY,
                    (PVOID)pValueInfo->Data,
                    pValueInfo->DataLength);

            if (!NT_SUCCESS(status))
            {
                LogError(DRIVER_DEFAULT, "ZwSetValueKey for %S value failed, %!STATUS!", Name.Buffer, status);
                goto cleanup;
            }

        cleanup:

            if (pValueInfo) FILTER_FREE_MEM(pValueInfo);
        }
        else
        {
            // Deleting the last value in the list (but not the only value)
            // Just delete the value directly. No need to copy any others.

            // Convert 'aIndex' to a string
            RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name);

            // Delete the registry value
            status =
                ZwDeleteValueKey(
                    regKey,
                    &Name);
        }
    }

error:

    if (regKey) ZwClose(regKey);

    return status;
}
Beispiel #7
0
VOID
DeleteTestKeys(
    )
/*++


--*/
{
    NTSTATUS Status;
    UNICODE_STRING KeyPath;
    OBJECT_ATTRIBUTES KeyAttributes;
    HANDLE RootKey = NULL;
    HANDLE ChildKey = NULL;

    //
    // Check if the root key can be opened. If it can be opened, a previous
    // run must have not completed cleanly. Delete the key and recreate the 
    // root key.
    //

    RtlInitUnicodeString(&KeyPath, ROOT_KEY_ABS_PATH);
    InitializeObjectAttributes(&KeyAttributes,
                               &KeyPath,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwOpenKey(&RootKey,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
        return;
    } else if (!NT_SUCCESS(Status)) {
        ErrorPrint("Opening root key fails with unexpected status %x.", Status);
    }

    RtlInitUnicodeString(&KeyPath, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &KeyPath,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               RootKey,
                               NULL);

    Status = ZwOpenKey(&ChildKey,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (NT_SUCCESS(Status)) {
        ZwDeleteKey(ChildKey);
        ZwClose(ChildKey);
        ChildKey = NULL;
    } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("Opening %S key fails with unexpected status %x.", 
                   KEY_NAME,
                   Status);
    }

    RtlInitUnicodeString(&KeyPath, NOT_MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &KeyPath,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               RootKey,
                               NULL);

    Status = ZwOpenKey(&ChildKey,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (NT_SUCCESS(Status)) {
        ZwDeleteKey(ChildKey);
        ZwClose(ChildKey);
        ChildKey = NULL;
    } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("Opening %S key fails with unexpected status %x.", 
                   NOT_MODIFIED_KEY_NAME,
                   Status);
    }

    RtlInitUnicodeString(&KeyPath, MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &KeyPath,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               RootKey,
                               NULL);

    Status = ZwOpenKey(&ChildKey,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (NT_SUCCESS(Status)) {
        ZwDeleteKey(ChildKey);
        ZwClose(ChildKey);
        ChildKey = NULL;
    } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("Opening %S key fails with unexpected status %x.", 
                   MODIFIED_KEY_NAME,
                   Status);
    }

    ZwDeleteKey(RootKey);
    ZwClose(RootKey);

    return;

}
Beispiel #8
0
BOOLEAN
PreNotificationBypassSample(
    )
/*++

Routine Description:

    This sample shows how to bypass a registry operation so that the CM does
    not process the operation. Unlike block, an operation that is bypassed
    is still considered successful so the callback must provide the caller
    with what the CM would have provided.

    A key and a value are created. However both operations are bypassed by the
    callback so that the key and value actually created have different names
    than would is expected.
    
Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    DWORD ValueData = 0; 
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Pre-Notification Bypass Sample ====");

    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_PRE_NOTIFICATION_BYPASS,
                                        CALLBACK_ALTITUDE);
    if (CallbackCtx == NULL) {
        goto Exit;
    }

    //
    // Register the callback
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;
    
    //
    // Create a key and set a value. Both should succeed
    //

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey failed. Status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(!NT_SUCCESS(Status)) {
        ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    
    //
    // Check that a key with the expected name KEY_NAME cannot be found 
    // but a key with the "modified" name can be found. 
    //

    if (Key != NULL) {
        ZwClose(Key);
    }

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);
    
    Status = ZwOpenKey(&Key,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("ZwOpenKey on key returned unexpected status: 0x%x", Status);
        if (Key != NULL) {
            ZwDeleteKey(Key);
            ZwClose(Key);
            Key = NULL;
        }
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwOpenKey(&Key,
                       KEY_ALL_ACCESS,
                       &KeyAttributes);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwOpenKey on modified key path failed. Status: 0x%x", Status);
        Success = FALSE;
    }
        

    //
    // Do the same check by trying to delete a value with VALUE_NAME and
    // with the "modified" name. 
    //

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwDeleteValueKey(g_RootKey, &Name);

    if (Status != STATUS_OBJECT_NAME_NOT_FOUND) {
        ErrorPrint("ZwDeleteValueKey on original value returned unexpected status: 0x%x", 
                   Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, MODIFIED_VALUE_NAME);
    Status = ZwDeleteValueKey(g_RootKey, &Name);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwDeleteValueKey on modified value failed. Status: 0x%x", 
                   Status);
        Success = FALSE;
    }

  Exit:

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (Success) {
        InfoPrint("Pre-Notification Bypass Sample succeeded.");
    } else {
        ErrorPrint("Pre-Notification Bypass Sample FAILED.");
    }

    return Success;
}
Beispiel #9
0
static
NTSTATUS
NTAPI
RXactpCommit(
    PRXACT_CONTEXT Context)
{
    PRXACT_DATA Data;
    PRXACT_ACTION Action;
    NTSTATUS Status, TmpStatus;
    HANDLE KeyHandle;
    ULONG i;

    Data = Context->Data;

    /* The first action record starts after the data header */
    Action = (PRXACT_ACTION)(Data + 1);

    /* Loop all recorded actions */
    for (i = 0; i < Data->ActionCount; i++)
    {
        /* Translate relative offsets to actual pointers */
        Action->KeyName.Buffer = (PWSTR)((PUCHAR)Data + (ULONG_PTR)Action->KeyName.Buffer);
        Action->ValueName.Buffer = (PWSTR)((PUCHAR)Data + (ULONG_PTR)Action->ValueName.Buffer);
        Action->ValueData = (PUCHAR)Data + (ULONG_PTR)Action->ValueData;

        /* Check what kind of action this is */
        if (Action->Type == RXactDeleteKey)
        {
            /* This is a delete action. Check if we can use a handle */
            if ((Action->KeyHandle != INVALID_HANDLE_VALUE) && Context->CanUseHandles)
            {
                /* Delete the key by the given handle */
                Status = ZwDeleteKey(Action->KeyHandle);
                if (!NT_SUCCESS(Status))
                {
                    return Status;
                }
            }
            else
            {
                /* We cannot use a handle, open the key first by it's name */
                Status = RXactpOpenTargetKey(Context->RootDirectory,
                                             RXactDeleteKey,
                                             &Action->KeyName,
                                             &KeyHandle);
                if (NT_SUCCESS(Status))
                {
                    Status = ZwDeleteKey(KeyHandle);
                    TmpStatus = NtClose(KeyHandle);
                    ASSERT(NT_SUCCESS(TmpStatus));
                    if (!NT_SUCCESS(Status))
                    {
                        return Status;
                    }
                }
                else
                {
                    /* Failed to open the key, it's ok, if it was not found */
                    if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
                        return Status;
                }
            }
        }
        else if (Action->Type == RXactSetValueKey)
        {
            /* This is a set action. Check if we can use a handle */
            if ((Action->KeyHandle != INVALID_HANDLE_VALUE) && Context->CanUseHandles)
            {
                /* Set the key value using the given key handle */
                Status = ZwSetValueKey(Action->KeyHandle,
                                       &Action->ValueName,
                                       0,
                                       Action->ValueType,
                                       Action->ValueData,
                                       Action->ValueDataSize);
                if (!NT_SUCCESS(Status))
                {
                    return Status;
                }
            }
            else
            {
                /* We cannot use a handle, open the key first by it's name */
                Status = RXactpOpenTargetKey(Context->RootDirectory,
                                             RXactSetValueKey,
                                             &Action->KeyName,
                                             &KeyHandle);
                if (!NT_SUCCESS(Status))
                {
                    return Status;
                }

                /* Set the key value */
                Status = ZwSetValueKey(KeyHandle,
                                       &Action->ValueName,
                                       0,
                                       Action->ValueType,
                                       Action->ValueData,
                                       Action->ValueDataSize);

                TmpStatus = NtClose(KeyHandle);
                ASSERT(NT_SUCCESS(TmpStatus));

                if (!NT_SUCCESS(Status))
                {
                    return Status;
                }
            }
        }
        else
        {
            ASSERT(FALSE);
            return STATUS_INVALID_PARAMETER;
        }

        /* Go to the next action record */
        Action = (PRXACT_ACTION)((PUCHAR)Action + Action->Size);
    }

    return STATUS_SUCCESS;
}
Beispiel #10
0
NTSTATUS
DrDeleteAllSubKeys(
		HANDLE				ParentKey
	) {

	NTSTATUS					status;
	PKEY_BASIC_INFORMATION		keyInfo;
	ULONG						outLength;
	ULONG						idxKey;
	OBJECT_ATTRIBUTES			objectAttributes;
	UNICODE_STRING				objectName;
	HANDLE						childKey;

	keyInfo = (PKEY_BASIC_INFORMATION)ExAllocatePoolWithTag(PagedPool, 512, DEVREG_POOTAG_KEYINFO);
	if(!keyInfo) {
		KDPrint(1, ("ExAllocatePoolWithTag(KEY_BASIC_INFORMATION) failed.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = STATUS_SUCCESS;
	for(idxKey = 0 ; idxKey < DEVREG_MAX_REGISTRY_KEY; idxKey ++) {
		status = ZwEnumerateKey(
						ParentKey,
						idxKey,
						KeyBasicInformation,
						keyInfo,
						512,
						&outLength
						);

		if(status == STATUS_NO_MORE_ENTRIES) {
			KDPrint(1, ("No more entries.\n"));
			status = STATUS_SUCCESS;
			break;
		}
		if(status != STATUS_SUCCESS) {
			ASSERT(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL);
			KDPrint(1, ("ZwEnumerateKey() failed. NTSTATUS:%08lx\n", status));
			ExFreePool(keyInfo);
			return STATUS_SUCCESS;
		}


		//
		//	Open a sub key
		//
		objectName.Length = objectName.MaximumLength = (USHORT)keyInfo->NameLength;
		objectName.Buffer = keyInfo->Name;
		InitializeObjectAttributes(		&objectAttributes,
										&objectName,
										OBJ_KERNEL_HANDLE,
										ParentKey,
										NULL
								);
		status = ZwOpenKey(&childKey, KEY_ALL_ACCESS, &objectAttributes);
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("ZwOpenKey() failed. NTSTATUS:%08lx\n", status));
			continue;
		}

		//
		//	Delete all subkeys
		//
		status = DrDeleteAllSubKeys(childKey);
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("Recursive DrDeleteAllSubKeys() failed. NTSTATUS:%08lx\n", status));
			ZwClose(childKey);
			continue;
		}

		//
		//	Delete NDAS device instance.
		//
		status = ZwDeleteKey(childKey);
#if DBG
		if(!NT_SUCCESS(status)) {
			KDPrint(1, ("ZwDeleteKey() failed. NTSTATUS:%08lx\n", status));
		}
#endif
		ZwClose(childKey);

		//
		//	One key was deleted, decrement key index.
		//

		idxKey--;

	}

	ExFreePool(keyInfo);
	return STATUS_SUCCESS;
}
BOOLEAN 
MultipleAltitudeBlockDuringPreSample(
    )
/*++

Routine Description:

    This sample features a stack of three callbacks at different altitudes and
    demonstrates what happens when middle callback blocks an operation
    in the pre-notification phase. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{

    PCALLBACK_CONTEXT CallbackCtxHigh = NULL;
    PCALLBACK_CONTEXT CallbackCtxMid = NULL;
    PCALLBACK_CONTEXT CallbackCtxLow = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Multiple Altitude Block During Pre Sample ====");

    //
    // Create callback contexts for the 3 callbacks.
    // The high and low callbacks will only monitor how many notifications
    // they receive.
    //
    
    CallbackCtxHigh = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                            CALLBACK_HIGH_ALTITUDE);
    CallbackCtxMid = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_BLOCK_DURING_PRE,
                                           CALLBACK_ALTITUDE);
    CallbackCtxLow = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                           CALLBACK_LOW_ALTITUDE);

    if ((CallbackCtxHigh == NULL) ||
        (CallbackCtxMid == NULL) ||
        (CallbackCtxLow == NULL)) {
        goto Exit;
    }

    //
    // Register the callbacks
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxHigh->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxHigh,
                                  &CallbackCtxHigh->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxMid->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxMid,
                                  &CallbackCtxMid->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxLow->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxLow,
                                  &CallbackCtxLow->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Do a create key operation which will be blocked by the middle
    // callback and fail with STATUS_ACCESS_DENIED
    //
    
    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    
    //
    // Unregister the callbacks
    //

    Status = CmUnRegisterCallback(CallbackCtxHigh->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }

    Status = CmUnRegisterCallback(CallbackCtxMid->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }

    Status = CmUnRegisterCallback(CallbackCtxLow->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
    }


    //
    // Verify that the highest alitude callback receives a pre and a post 
    // notification. It receives a post notification because it returned 
    // STATUS_SUCCESS in the pre-notification so it is guaranteed to get a 
    // post notification.
    //
    
    if ((CallbackCtxHigh->PreNotificationCount != 1) ||
        (CallbackCtxHigh->PostNotificationCount != 1)) {
        ErrorPrint("High Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("High Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxHigh->PreNotificationCount,
                   CallbackCtxHigh->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the middle callback receives only a pre notification.
    // It does not get a post notification because it return a non-success
    // value in the pre-notification phase.
    //
    
    if ((CallbackCtxMid->PreNotificationCount != 1) ||
        (CallbackCtxMid->PostNotificationCount != 0)) {
        ErrorPrint("Mid Callback should have seen 1 pre and 0 post notifications.");
        ErrorPrint("Mid Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxMid->PreNotificationCount,
                   CallbackCtxMid->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the lowest callback receives no notifications.
    // Once the middle callback blocks, no callbacks at lower altitudes are
    // notified.
    //
    
    if ((CallbackCtxLow->PreNotificationCount != 0) ||
        (CallbackCtxLow->PostNotificationCount != 0)) {
        ErrorPrint("Low Callback should have seen 0 pre and 0 post notifications.");
        ErrorPrint("Low Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxLow->PreNotificationCount,
                   CallbackCtxLow->PostNotificationCount);
        Success = FALSE;
    }

  Exit:

    if (Success) {
        InfoPrint("Multiple Altitude Block During Pre Sample succeeded.");
    } else {
        ErrorPrint("Multiple Altitude Block During Pre Sample FAILED.");
    }

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtxHigh != NULL) {
        ExFreePoolWithTag(CallbackCtxHigh, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxMid != NULL) {
        ExFreePoolWithTag(CallbackCtxMid, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxLow != NULL) {
        ExFreePoolWithTag(CallbackCtxLow, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;
}
BOOLEAN 
MultipleAltitudeInternalInvocationSample(
    )
/*++

Routine Description:

    This sample features a stack of 3 callbacks at different altitudes and
    demonstrates what happens when the middle callback invokes a registry
    operation. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtxHigh = NULL;
    PCALLBACK_CONTEXT CallbackCtxMid = NULL;
    PCALLBACK_CONTEXT CallbackCtxLow = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    BOOLEAN Success = FALSE;
    

    InfoPrint("");
    InfoPrint("=== Multiple Altitude Internal Invocation Sample ====");

    //
    // Create callback contexts for the 3 callbacks.
    // The high and low callbacks will only monitor how many notifications
    // they receive.
    //
    
    CallbackCtxHigh = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                            CALLBACK_HIGH_ALTITUDE);
    CallbackCtxMid = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_INTERNAL_INVOCATION,
                                           CALLBACK_ALTITUDE);
    CallbackCtxLow = CreateCallbackContext(CALLBACK_MODE_MULTIPLE_ALTITUDE_MONITOR,
                                           CALLBACK_LOW_ALTITUDE);

    if ((CallbackCtxHigh == NULL) ||
        (CallbackCtxMid == NULL) ||
        (CallbackCtxLow == NULL)) {
        goto Exit;
    }

    //
    // Register the callbacks
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxHigh->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxHigh,
                                  &CallbackCtxHigh->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxMid->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxMid,
                                  &CallbackCtxMid->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtxLow->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtxLow,
                                  &CallbackCtxLow->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Create a key. When the middle callback receives the pre-notification
    // and the post-notification for this create it will perform an open key 
    // and a close key operation.
    //
    
    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callbacks
    //

    Status = CmUnRegisterCallback(CallbackCtxHigh->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    Status = CmUnRegisterCallback(CallbackCtxMid->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

    Status = CmUnRegisterCallback(CallbackCtxLow->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Verify the highest altitude callback receives one pre and one post
    // notification. This callback does not get notifications for the 
    // registry operations called by the middle callback.
    //
    
    if ((CallbackCtxHigh->PreNotificationCount != 1) ||
        (CallbackCtxHigh->PostNotificationCount != 1)) {
        ErrorPrint("High Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("High Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxHigh->PreNotificationCount,
                   CallbackCtxHigh->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the middle callback receives one pre and one post notification.
    // This callback does not get notifications for the registry operations 
    // that it calls.
    //
    
    if ((CallbackCtxMid->PreNotificationCount != 1) ||
        (CallbackCtxMid->PostNotificationCount != 1)) {
        ErrorPrint("Mid Callback should have seen 1 pre and 1 post notifications.");
        ErrorPrint("Mid Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxMid->PreNotificationCount,
                   CallbackCtxMid->PostNotificationCount);
        Success = FALSE;
    }

    //
    // Verify the lowest callback receives 5 pre-notifications and 5
    // post-notifications. This callback receives 1 pre and 1 post from the 
    // original create key operation. It also receives 2 pre and 2 post for
    // the open key and close key operations called by the middle callback 
    // during the pre phase of the create key and then 2 pre and 2 post again
    // for the calls in the post phase of the create key.
    //
    
    if ((CallbackCtxLow->PreNotificationCount != 5) ||
        (CallbackCtxLow->PostNotificationCount != 5)) {
        ErrorPrint("Low Callback should have seen 5 pre and 5 post notifications.");
        ErrorPrint("Low Callback actually saw %d pre and %d post notifications.",
                   CallbackCtxLow->PreNotificationCount,
                   CallbackCtxLow->PostNotificationCount);
        Success = FALSE;
    }

  Exit:
    
    if (Success) {
        InfoPrint("Multiple Altitude Internal Invocation Sample succeeded.");
    } else {
        ErrorPrint("Multiple Altitude Internal Invocation Sample FAILED.");
    }

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (CallbackCtxHigh != NULL) {
        ExFreePoolWithTag(CallbackCtxHigh, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxMid != NULL) {
        ExFreePoolWithTag(CallbackCtxMid, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (CallbackCtxLow != NULL) {
        ExFreePoolWithTag(CallbackCtxLow, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;
}
Beispiel #13
0
VOID
SoundCleanup(
    IN   PGLOBAL_DEVICE_INFO pGDI
)
/*++

Routine Description:

    Clean up all resources allocated by our initialization

Arguments:

    pGDI - Pointer to global data

Return Value:

    NONE

--*/
{

    PGLOBAL_DEVICE_INFO NextGDI;
    PGLOBAL_DEVICE_INFO FirstGDI;
    PDRIVER_OBJECT      DriverObject;

    FirstGDI = pGDI;

    for (;;) {
        NextGDI = pGDI->Next;

        //
        //  Free the synth device
        //

        SynthCleanup(&pGDI->Synth);

        //
        //  Reset MPU401 if any
        //

        if (pGDI->Hw.MPU401.PortBase != NULL) {
            //
            //  Just in case
            //
            READ_PORT_UCHAR(pGDI->Hw.MPU401.PortBase + MPU401_REG_DATA);
            MPU401Write(pGDI->Hw.MPU401.PortBase, TRUE, MPU401_CMD_RESET);
        }
        //
        // Free our interrupt
        //
        if (pGDI->WaveInfo.Interrupt) {
            IoDisconnectInterrupt(pGDI->WaveInfo.Interrupt);
        }

        //
        // Free our DMA Buffer
        //
        SoundFreeCommonBuffer(&pGDI->WaveInfo.DMABuf);

        //
        //  Unregister shutdown notification
        //
        if (pGDI->ShutdownRegistered) {
            IoUnregisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]);
        }

        //
        // Free our I/O Ports
        //
        if (pGDI->MemType == 0) {
            if (pGDI->Hw.PortBase != NULL) {

                MmUnmapIoSpace(pGDI->Hw.PortBase, NUMBER_OF_SOUND_PORTS);
            }
            if (pGDI->Hw.MPU401.PortBase != NULL) {

                MmUnmapIoSpace(pGDI->Hw.MPU401.PortBase, NUMBER_OF_MPU401_PORTS);
            }
#ifdef SB_CD
            if (pGDI->Hw.SBCDBase != NULL) {

                MmUnmapIoSpace(pGDI->Hw.SBCDBase, 6);
            }
#endif // SB_CD
        }

        //
        // Free device name
        //
        if (pGDI->RegistryPathName) {
            HANDLE hKey;

            //
            //  Free devices key
            //
            if (NT_SUCCESS(SoundOpenDevicesKey(pGDI->RegistryPathName, &hKey))) {
                ZwDeleteKey(hKey);
                ZwClose(hKey);
            }

            ExFreePool(pGDI->RegistryPathName);
        }

        //
        // Save driver object
        //

        DriverObject = pGDI->DriverObject;

        //
        // Free the Pool
        //
        ExFreePool(pGDI);

        if (NextGDI == FirstGDI) {
            break;
        } else {
            pGDI = NextGDI;
        }
    }

    //
    //  Free all devices for this driver.  This will free everything for
    //  every card.
    //

    if (DriverObject != NULL) {
        while (DriverObject->DeviceObject != NULL) {

            /*
            **  Undeclare resources used by device and
            **  delete the device object and associated data
            */

            SoundFreeDevice(DriverObject->DeviceObject);
        }
    }
}
Beispiel #14
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersSubKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
NTSTATUS  DriverParametersSubKeyDelete(
    WDFDRIVER  Driver,
    DtString*  pKeyName)
{
    NTSTATUS  NtStatus = STATUS_SUCCESS;
    DtStringChar*  pRegistryPath;
    DtString  RegistryPath;
    DtString  FullKeyName;
    UInt  PathLength;
    HANDLE  hKey;
    OBJECT_ATTRIBUTES  ObjectAttributes;
    KEY_BASIC_INFORMATION*  pKeyInfo;
    ULONG  Size;
    ULONG  ResultSize;
    Int  Index;
    
    DT_STRING_DECL(ParamItemName, "\\Parameters\\");

    DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL);

    // Build the full path
    pRegistryPath = WdfDriverGetRegistryPath(Driver);
    PathLength = wcslen(pRegistryPath); 

    DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength);

    // Allocate struct for key information result
    Size = sizeof(KEY_BASIC_INFORMATION)+100;
    pKeyInfo = DtMemAllocPool(DtPoolNonPaged, Size, SAL_TAG);
    if (pKeyInfo == NULL)
        return STATUS_NO_MEMORY;

    // Allocate a new DtString buffer for the complete path inclusive a '\0' character
    // and extra '\\'
    if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+
                                                  DtStringGetStringLength(&ParamItemName)+
                                                  DtStringGetStringLength(pKeyName)+
                                                  100+1+1)))
    {
        DtMemFreePool(pKeyInfo, SAL_TAG);
        return STATUS_NO_MEMORY;
    }

    DtStringAppendDtString(&FullKeyName, &RegistryPath);
    DtStringAppendDtString(&FullKeyName, &ParamItemName);
    DtStringAppendDtString(&FullKeyName, pKeyName);

    // Initialize key to open
    InitializeObjectAttributes(&ObjectAttributes, &FullKeyName, OBJ_KERNEL_HANDLE, NULL,
                                                                                    NULL);
    
    NtStatus = ZwOpenKey(&hKey, KEY_ENUMERATE_SUB_KEYS , &ObjectAttributes);
    
    if (NT_SUCCESS(NtStatus)) 
    {
        Index = 0;
        NtStatus = STATUS_SUCCESS;
        // Enumerate all keys
        while (NtStatus != STATUS_NO_MORE_ENTRIES)
        {
            NtStatus = ZwEnumerateKey(hKey, Index, KeyBasicInformation, pKeyInfo, Size,
                                                                             &ResultSize);
            if (NT_SUCCESS(NtStatus))
            {
                DtString SubKey;

                // Build key to delete
                pKeyInfo->Name[pKeyInfo->NameLength/2] = L'\0';
                DT_STRING_INIT_CONST(SubKey, pKeyInfo->Name, ((USHORT)pKeyInfo->NameLength/2));

                DtStringClear(&FullKeyName);
                DtStringAppendDtString(&FullKeyName, pKeyName);
                DtStringAppendChars(&FullKeyName, "\\");
                DtStringAppendDtString(&FullKeyName, &SubKey);
                
                DtDbgOut(MAX, SAL, "Delete SubKey %S.", FullKeyName.Buffer);
                NtStatus = DriverParametersKeyDelete(Driver, &FullKeyName);
                if (!NT_SUCCESS(NtStatus))
                    DtDbgOut(ERR, SAL, "Error deleting SubKey %S. Error: %x", 
                                                            FullKeyName.Buffer, NtStatus);
            }
            // In case deletion failed, skip this entry
            if (!NT_SUCCESS(NtStatus)) 
                Index++;
        }
        NtStatus = ZwDeleteKey(hKey);
        ZwClose(hKey);
    }
    DtMemFreePool(pKeyInfo, SAL_TAG);
    DtStringFree(&FullKeyName);
    return NtStatus;
}
BOOLEAN
SetCallContextSample(
    )
/*++

Routine Description:

    This sample shows how a registry callback can associate a context
    with a registry operation during the pre-notification phase so that it
    is available in the post-notification phase. 

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    DWORD ValueData = 0;
    BOOLEAN Success = FALSE;
    

    InfoPrint("");
    InfoPrint("=== Set Operation Context Sample ====");

    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_SET_CALL_CONTEXT,
                                         CALLBACK_ALTITUDE);

    if (CallbackCtx == NULL) {
        goto Exit;
    }
    
    //
    // Register callback with the context
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;

    //
    // Create a key and set a value.
    //

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey failed. Status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(!NT_SUCCESS(Status)) {
        ErrorPrint("ZwSetValue failed. Status 0x%x", Status);
        Success = FALSE;
    }

    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Check that the callback records 2 in OperationContextCount.
    // The count should be incremented once in the post-notification for the
    // create key and once for the set value.
    //

    if (CallbackCtx->NotificationWithContextCount != 2) {
        ErrorPrint("Callback OperationWithContextCount expected 2, got %d",
                   CallbackCtx->NotificationWithContextCount);
        Success = FALSE;
    }

  Exit:
    
    if (Success == TRUE) {
        InfoPrint("Set Call Context sample succeeded.");
    } else {
        ErrorPrint("Set Call Context sample FAILED.");
    }

    //
    // Clean up
    //
    
    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    return Success;

}
Beispiel #16
0
NTSTATUS DeleteKey(HANDLE hKey) {
	return ZwDeleteKey(hKey);
}
Beispiel #17
0
NTSTATUS 
DoCallbackSamples(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp
    )
/*++

Routine Description:

    This routine creates the root test key and then invokes the sample.
    It records the results of each sample in an array that it returns to
    the usermode program.

Arguments:

    DeviceObject - The device object receiving the request.

    Irp - The request packet.
    
Return Value:

    NTSTATUS

--*/
{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpStack;
    ULONG OutputBufferLength;
    PDO_KERNELMODE_SAMPLES_OUTPUT Output;
    UNICODE_STRING KeyPath;
    OBJECT_ATTRIBUTES KeyAttributes;

    UNREFERENCED_PARAMETER(DeviceObject);

    //
    // Get the output buffer from the irp and check it is as large as expected.
    //
    
    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    if (OutputBufferLength < sizeof (DO_KERNELMODE_SAMPLES_OUTPUT)) {
        Status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    Output = (PDO_KERNELMODE_SAMPLES_OUTPUT) Irp->AssociatedIrp.SystemBuffer;

    //
    // Clean up test keys in case the sample terminated uncleanly.
    //

    DeleteTestKeys();

    //
    // Create the root key and the modified root key
    //
    
    RtlInitUnicodeString(&KeyPath, ROOT_KEY_ABS_PATH);
    InitializeObjectAttributes(&KeyAttributes,
                               &KeyPath,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwCreateKey(&g_RootKey,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateKey failed. Status 0x%x", Status);
        return Status;
    }

    //
    // Call each demo and record the results in the Output->SampleResults
    // array
    //

    Output->SampleResults[KERNELMODE_SAMPLE_PRE_NOTIFICATION_BLOCK] =
        PreNotificationBlockSample();

    Output->SampleResults[KERNELMODE_SAMPLE_PRE_NOTIFICATION_BYPASS] =
        PreNotificationBypassSample();

    Output->SampleResults[KERNELMODE_SAMPLE_POST_NOTIFICATION_OVERRIDE_SUCCESS] =
        PostNotificationOverrideSuccessSample();

    Output->SampleResults[KERNELMODE_SAMPLE_POST_NOTIFICATION_OVERRIDE_ERROR] =
        PostNotificationOverrideErrorSample();

    Output->SampleResults[KERNELMODE_SAMPLE_TRANSACTION_ENLIST] =
        TransactionEnlistSample();

    Output->SampleResults[KERNELMODE_SAMPLE_TRANSACTION_REPLAY] =
        TransactionReplaySample();

    Output->SampleResults[KERNELMODE_SAMPLE_SET_CALL_CONTEXT] =
        SetObjectContextSample();

    Output->SampleResults[KERNELMODE_SAMPLE_SET_OBJECT_CONTEXT] =
        SetCallContextSample();

    Output->SampleResults[KERNELMODE_SAMPLE_MULTIPLE_ALTITUDE_BLOCK_DURING_PRE] =
        MultipleAltitudeBlockDuringPreSample();

    Output->SampleResults[KERNELMODE_SAMPLE_MULTIPLE_ALTITUDE_INTERNAL_INVOCATION] =
        MultipleAltitudeInternalInvocationSample();

    Output->SampleResults[KERNELMODE_SAMPLE_VERSION_CREATE_OPEN_V1] =
        CreateOpenV1Sample();

    Irp->IoStatus.Information = sizeof(DO_KERNELMODE_SAMPLES_OUTPUT);

  Exit:

    if (g_RootKey) {
        ZwDeleteKey(g_RootKey);
        ZwClose(g_RootKey);
    }

    InfoPrint("");
    InfoPrint("Kernel Mode Samples End");
    InfoPrint("");
    
    return Status;
}
Beispiel #18
0
NTSTATUS
NTAPI
RtlInitializeRXact(
    HANDLE RootDirectory,
    BOOLEAN Commit,
    PRXACT_CONTEXT *OutContext)
{
    NTSTATUS Status, TmpStatus;
    PRXACT_CONTEXT Context;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    KEY_VALUE_BASIC_INFORMATION KeyValueBasicInfo;
    UNICODE_STRING ValueName;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    RXACT_INFO TransactionInfo;
    ULONG Disposition;
    ULONG ValueType;
    ULONG ValueDataLength;
    ULONG Length;
    HANDLE KeyHandle;

    /* Open or create the 'RXACT' key in the root directory */
    RtlInitUnicodeString(&KeyName, L"RXACT");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
                               RootDirectory,
                               NULL);
    Status = ZwCreateKey(&KeyHandle,
                         KEY_READ | KEY_WRITE | DELETE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         0,
                         &Disposition);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Allocate a new context */
    Context = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Context));
    *OutContext = Context;
    if (Context == NULL)
    {
        TmpStatus = ZwDeleteKey(KeyHandle);
        ASSERT(NT_SUCCESS(TmpStatus));

        TmpStatus = NtClose(KeyHandle);
        ASSERT(NT_SUCCESS(TmpStatus));

        return STATUS_NO_MEMORY;
    }

    /* Initialize the context */
    RXactInitializeContext(Context, RootDirectory, KeyHandle);

    /* Check if we created a new key */
    if (Disposition == REG_CREATED_NEW_KEY)
    {
        /* The key is new, set the default value */
        TransactionInfo.Revision = 1;
        RtlInitUnicodeString(&ValueName, NULL);
        Status = ZwSetValueKey(KeyHandle,
                               &ValueName,
                               0,
                               REG_NONE,
                               &TransactionInfo,
                               sizeof(TransactionInfo));
        if (!NT_SUCCESS(Status))
        {
            TmpStatus = ZwDeleteKey(KeyHandle);
            ASSERT(NT_SUCCESS(TmpStatus));

            TmpStatus = NtClose(KeyHandle);
            ASSERT(NT_SUCCESS(TmpStatus));

            RtlFreeHeap(RtlGetProcessHeap(), 0, *OutContext);
            return Status;
        }

        return STATUS_RXACT_STATE_CREATED;
    }
    else
    {
        /* The key exited, get the default key value */
        ValueDataLength = sizeof(TransactionInfo);
        Status = RtlpNtQueryValueKey(KeyHandle,
                                     &ValueType,
                                     &TransactionInfo,
                                     &ValueDataLength,
                                     0);
        if (!NT_SUCCESS(Status))
        {
            TmpStatus = NtClose(KeyHandle);
            ASSERT(NT_SUCCESS(TmpStatus));
            RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
            return Status;
        }

        /* Check if the value date is valid */
        if ((ValueDataLength != sizeof(TransactionInfo)) ||
                (TransactionInfo.Revision != 1))
        {
            TmpStatus = NtClose(KeyHandle);
            ASSERT(NT_SUCCESS(TmpStatus));
            RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
            return STATUS_UNKNOWN_REVISION;
        }

        /* Query the 'Log' key value */
        RtlInitUnicodeString(&ValueName, L"Log");
        Status = ZwQueryValueKey(KeyHandle,
                                 &ValueName,
                                 KeyValueBasicInformation,
                                 &KeyValueBasicInfo,
                                 sizeof(KeyValueBasicInfo),
                                 &Length);
        if (!NT_SUCCESS(Status))
        {
            /* There is no 'Log', so we are done */
            return STATUS_SUCCESS;
        }

        /* Check if the caller asked to commit the current state */
        if (!Commit)
        {
            /* We have a log, that must be committed first! */
            return STATUS_RXACT_COMMIT_NECESSARY;
        }

        /* Query the size of the 'Log' key value */
        Status = ZwQueryValueKey(KeyHandle,
                                 &ValueName,
                                 KeyValueFullInformation,
                                 NULL,
                                 0,
                                 &Length);
        if (Status != STATUS_BUFFER_TOO_SMALL)
        {
            return Status;
        }

        /* Allocate a buffer for the key value information */
        KeyValueInformation = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
        if (KeyValueInformation == NULL)
        {
            return STATUS_NO_MEMORY;
        }

        /* Query the 'Log' key value */
        Status = ZwQueryValueKey(KeyHandle,
                                 &ValueName,
                                 KeyValueFullInformation,
                                 KeyValueInformation,
                                 Length,
                                 &Length);
        if (!NT_SUCCESS(Status))
        {
            RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
            RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
            return Status;
        }

        /* Set the Data pointer to the key value data */
        Context->Data = (PRXACT_DATA)((PUCHAR)KeyValueInformation +
                                      KeyValueInformation->DataOffset);

        /* This is an old log, don't use handles when committing! */
        Context->CanUseHandles = FALSE;

        /* Commit the data */
        Status = RXactpCommit(Context);
        if (!NT_SUCCESS(Status))
        {
            RtlFreeHeap(RtlGetProcessHeap(), 0, KeyValueInformation);
            RtlFreeHeap(RtlGetProcessHeap(), 0, Context);
            return Status;
        }

        /* Delete the old key */
        Status = NtDeleteValueKey(KeyHandle, &ValueName);
        ASSERT(NT_SUCCESS(Status));

        /* Set the data member to the allocated buffer, so it will get freed */
        Context->Data = (PRXACT_DATA)KeyValueInformation;

        /* Abort the old transaction */
        Status = RtlAbortRXact(Context);
        ASSERT(NT_SUCCESS(Status));

        return Status;
    }
}
Beispiel #19
0
BOOLEAN
PreNotificationBlockSample(
    )
/*++

Routine Description:

    This sample shows how to block a registry operation in the
    pre-notification phase. 

    Two keys are created. The create operations should succeed, but one
    is intercepted by the callback and failed with STATUS_ACCESS_DENIED.
    The same is done for two values.

Return Value:

    TRUE if the sample completed successfully.

--*/
{
    PCALLBACK_CONTEXT CallbackCtx = NULL;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES KeyAttributes;
    UNICODE_STRING Name;
    HANDLE Key = NULL;
    HANDLE NotModifiedKey = NULL;
    DWORD ValueData = 0; 
    BOOLEAN Success = FALSE;

    InfoPrint("");
    InfoPrint("=== Pre-Notification Block Sample ====");
    
    //
    // Create the callback context
    //

    CallbackCtx = CreateCallbackContext(CALLBACK_MODE_PRE_NOTIFICATION_BLOCK,
                                        CALLBACK_ALTITUDE);
    if (CallbackCtx == NULL) {
        goto Exit;
    }
    
    //
    // Register callback
    //

    Status = CmRegisterCallbackEx(Callback,
                                  &CallbackCtx->Altitude,
                                  g_DeviceObj->DriverObject,
                                  (PVOID) CallbackCtx,
                                  &CallbackCtx->Cookie, 
                                  NULL);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmRegisterCallback failed. Status 0x%x", Status);
        goto Exit;
    }

    Success = TRUE;
    
    //
    // Create two keys.
    // Creating the "not modified" key will succeed.
    // Creating the other key will fail with STATUS_ACCESS_DENIED
    //

    RtlInitUnicodeString(&Name, NOT_MODIFIED_KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&NotModifiedKey,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_SUCCESS) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, KEY_NAME);
    InitializeObjectAttributes(&KeyAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               g_RootKey,
                               NULL);

    Status = ZwCreateKey(&Key,
                         KEY_ALL_ACCESS,
                         &KeyAttributes,
                         0,
                         NULL,
                         0,
                         NULL);

    if (Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwCreateKey returned unexpected status 0x%x", Status);
        Success = FALSE;
    }


    //
    // Set two values. 
    // Setting the "not modified" value will succeed.
    // Setting the other value will fail with STATUS_ACCESS_DENIED.
    //

    RtlInitUnicodeString(&Name, NOT_MODIFIED_VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(Status != STATUS_SUCCESS) {
        ErrorPrint("ZwSetValue return unexpected status 0x%x", Status);
        Success = FALSE;
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    Status = ZwSetValueKey(g_RootKey,
                           &Name,
                           0,
                           REG_DWORD,
                           &ValueData,
                           sizeof(ValueData));
    
    if(Status != STATUS_ACCESS_DENIED) {
        ErrorPrint("ZwSetValue return unexpected status 0x%x", Status);
        Success = FALSE;
    }
    
    //
    // Unregister the callback
    //

    Status = CmUnRegisterCallback(CallbackCtx->Cookie);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CmUnRegisterCallback failed. Status 0x%x", Status);
        Success = FALSE;
    }

  Exit:

    //
    // Clean up
    //

    if (Key != NULL) {
        ZwDeleteKey(Key);
        ZwClose(Key);
    }

    if (NotModifiedKey != NULL) {
        ZwDeleteKey(NotModifiedKey);
        ZwClose(NotModifiedKey);
    }

    RtlInitUnicodeString(&Name, VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);
    RtlInitUnicodeString(&Name, NOT_MODIFIED_VALUE_NAME);
    ZwDeleteValueKey(g_RootKey, &Name);

    if (CallbackCtx != NULL) {
        ExFreePoolWithTag(CallbackCtx, REGFLTR_CONTEXT_POOL_TAG);
    }

    if (Success) {
        InfoPrint("Pre-Notification Block Sample succeeded.");
    } else {
        ErrorPrint("Pre-Notification Block Sample FAILED.");
    }

    return Success;
    
}