1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE:     Test for NtUnloadDriver
5  * COPYRIGHT:   Copyright 2019 Thomas Faber (thomas.faber@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 START_TEST(NtUnloadDriver)
11 {
12     NTSTATUS Status;
13     BOOLEAN OldPrivilege, OldPrivilege2;
14     UNICODE_STRING ServiceName;
15     PWCHAR Buffer = NULL;
16 
17     Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, FALSE, FALSE, &OldPrivilege);
18     if (!NT_SUCCESS(Status))
19     {
20         skip("Failed to drop driver load privilege\n");
21         return;
22     }
23 
24     Status = NtUnloadDriver(NULL);
25     ok_hex(Status, STATUS_PRIVILEGE_NOT_HELD);
26 
27     Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE, FALSE, &OldPrivilege2);
28     if (!NT_SUCCESS(Status))
29     {
30         skip("Failed to acquire driver load privilege\n");
31         goto Exit;
32     }
33 
34     Status = NtUnloadDriver(NULL);
35     ok_hex(Status, STATUS_ACCESS_VIOLATION);
36 
37     RtlInitEmptyUnicodeString(&ServiceName, NULL, 0);
38     Status = NtUnloadDriver(&ServiceName);
39     ok_hex(Status, STATUS_INVALID_PARAMETER);
40 
41     Buffer = AllocateGuarded(0x10000);
42     if (!Buffer)
43     {
44         skip("Failed to allocate memory\n");
45         goto Exit;
46     }
47 
48     RtlFillMemoryUlong(Buffer, 0x10000, 'A' << 16 | 'A');
49 
50     ServiceName.Buffer = Buffer;
51     ServiceName.Length = 0xFFFF;
52     ServiceName.MaximumLength = MAXUSHORT;
53     Status = NtUnloadDriver(&ServiceName);
54     ok_hex(Status, STATUS_OBJECT_NAME_INVALID);
55 
56     ServiceName.Buffer = Buffer;
57     ServiceName.Length = 0xFFFE;
58     ServiceName.MaximumLength = MAXUSHORT;
59     Status = NtUnloadDriver(&ServiceName);
60     ok_hex(Status, STATUS_OBJECT_NAME_INVALID);
61 
62     ServiceName.Buffer = Buffer;
63     ServiceName.Length = 0xFFFD;
64     ServiceName.MaximumLength = MAXUSHORT;
65     Status = NtUnloadDriver(&ServiceName);
66     ok_hex(Status, STATUS_OBJECT_NAME_INVALID);
67 
68     ServiceName.Buffer = Buffer;
69     ServiceName.Length = 0xFFFC;
70     ServiceName.MaximumLength = MAXUSHORT;
71     Status = NtUnloadDriver(&ServiceName);
72     ok_hex(Status, STATUS_OBJECT_PATH_SYNTAX_BAD);
73 
74     ServiceName.Buffer = Buffer;
75     ServiceName.Length = 0x1000;
76     ServiceName.MaximumLength = MAXUSHORT;
77     Status = NtUnloadDriver(&ServiceName);
78     ok_hex(Status, STATUS_OBJECT_PATH_SYNTAX_BAD);
79 
80     ServiceName.Buffer = Buffer;
81     ServiceName.Length = 1;
82     ServiceName.MaximumLength = MAXUSHORT;
83     Status = NtUnloadDriver(&ServiceName);
84     ok_hex(Status, STATUS_OBJECT_NAME_INVALID);
85 
86     Buffer[0xFFFC / sizeof(WCHAR)] = L'\\';
87     ServiceName.Buffer = Buffer;
88     ServiceName.Length = 0xFFFC;
89     ServiceName.MaximumLength = MAXUSHORT;
90     Status = NtUnloadDriver(&ServiceName);
91     ok_hex(Status, STATUS_OBJECT_PATH_SYNTAX_BAD);
92 
93     Buffer[0xFFFC / sizeof(WCHAR) - 1] = L'\\';
94     ServiceName.Buffer = Buffer;
95     ServiceName.Length = 0xFFFC;
96     ServiceName.MaximumLength = MAXUSHORT;
97     Status = NtUnloadDriver(&ServiceName);
98     ok_hex(Status, STATUS_OBJECT_PATH_SYNTAX_BAD);
99 
100 Exit:
101     if (Buffer != NULL)
102     {
103         FreeGuarded(Buffer);
104     }
105 
106     Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, OldPrivilege, FALSE, &OldPrivilege2);
107     ok_hex(Status, STATUS_SUCCESS);
108 }
109