Don't open device if already open.
[wine] / dlls / ntdll / tests / info.c
1 /* Unit test suite for *Information* Registry API functions
2  *
3  * Copyright 2005 Paul Vriens
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "ntdll_test.h"
22
23 static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
24
25 static HMODULE hntdll = 0;
26
27 #define NTDLL_GET_PROC(func) \
28     p ## func = (void*)GetProcAddress(hntdll, #func); \
29     if(!p ## func) { \
30       trace("GetProcAddress(%s) failed\n", #func); \
31       FreeLibrary(hntdll); \
32       return FALSE; \
33     }
34
35 static BOOL InitFunctionPtrs(void)
36 {
37     hntdll = LoadLibraryA("ntdll.dll");
38     if(!hntdll) {
39       trace("Could not load ntdll.dll\n");
40       return FALSE;
41     }
42     if (hntdll)
43     {
44       NTDLL_GET_PROC(NtQuerySystemInformation)
45     }
46     return TRUE;
47 }
48
49 static void test_query_basic()
50 {
51     DWORD status;
52     ULONG ReturnLength;
53     SYSTEM_BASIC_INFORMATION sbi;
54
55     /* This test also covers some basic parameter testing that should be the same for 
56      * every information class
57     */
58
59     /* Use a nonexistent info class */
60     trace("Check nonexistent info class\n");
61     status = pNtQuerySystemInformation(-1, NULL, 0, NULL);
62     ok( status == STATUS_INVALID_INFO_CLASS, "Expected STATUS_INVALID_INFO_CLASS, got %08lx\n", status);
63
64     /* Use an existing class but with a zero-length buffer */
65     trace("Check zero-length buffer\n");
66     status = pNtQuerySystemInformation(SystemBasicInformation, NULL, 0, NULL);
67     ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status);
68
69     /* Use an existing class, correct length but no SystemInformation buffer */
70     trace("Check no SystemInformation buffer\n");
71     status = pNtQuerySystemInformation(SystemBasicInformation, NULL, sizeof(sbi), NULL);
72     ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
73
74     /* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
75     trace("Check no ReturnLength pointer\n");
76     status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL);
77     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status);
78
79     /* Finally some correct calls */
80     trace("Check with correct parameters\n");
81     status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength);
82     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status);
83     ok( sizeof(sbi) == ReturnLength, "Inconsistent length (%08x) <-> (%ld)\n", sizeof(sbi), ReturnLength);
84
85     /* Check if we have some return values */
86     trace("Number of Processors : %d\n", sbi.NumberOfProcessors);
87     ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", sbi.NumberOfProcessors);
88 }
89
90 static void test_query_handle()
91 {
92     DWORD status;
93     ULONG ReturnLength;
94     ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION);
95     SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength);
96
97     /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */
98     status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
99
100     /* The following check assumes more than one handle on any given system */
101     todo_wine
102     {
103         ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status);
104     }
105     ok( ReturnLength > 0, "Expected ReturnLength to be > 0, it was %ld\n", ReturnLength);
106
107     SystemInformationLength = ReturnLength;
108     shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength);
109     status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength);
110     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status);
111
112     /* Check if we have some return values */
113     trace("Number of Handles : %ld\n", shi->Count);
114     todo_wine
115     {
116         /* our implementation is a stub for now */
117         ok( shi->Count > 1, "Expected more than 1 handles, got (%ld)\n", shi->Count);
118     }
119
120     HeapFree( GetProcessHeap(), 0, shi);
121 }
122
123
124 START_TEST(info)
125 {
126     if(!InitFunctionPtrs())
127         return;
128
129     /* 0 SystemBasicInformation */
130     trace("Starting test_query_basic()\n");
131     test_query_basic();
132
133     /* 0x10 SystemHandleInformation */
134     trace("Starting test_query_handle()\n");
135     test_query_handle();
136
137     FreeLibrary(hntdll);
138 }