ntdsapi: Add DsMakeSpnA to the spec file.
[wine] / dlls / setupapi / query.c
1 /*
2  * setupapi query functions
3  *
4  * Copyright 2006 James Hawkins
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "winreg.h"
27 #include "winver.h"
28 #include "setupapi.h"
29 #include "advpub.h"
30 #include "winnls.h"
31 #include "wine/debug.h"
32 #include "setupapi_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
35
36 /* fills the PSP_INF_INFORMATION struct fill_info is TRUE
37  * always returns the required size of the information
38  */
39 static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWORD *required)
40 {
41     LPCWSTR filename = PARSER_get_inf_filename(inf);
42     DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData)
43                         + (lstrlenW(filename) + 1) * sizeof(WCHAR);
44
45     if (required) *required = total_size;
46
47     /* FIXME: we need to parse the INF file to find the correct version info */
48     if (buffer)
49     {
50         if (size < total_size)
51         {
52             SetLastError(ERROR_INSUFFICIENT_BUFFER);
53             return FALSE;
54         }
55         buffer->InfStyle = INF_STYLE_WIN4;
56         buffer->InfCount = 1;
57         /* put the filename in buffer->VersionData */
58         lstrcpyW((LPWSTR)&buffer->VersionData[0], filename);
59     }
60     return TRUE;
61 }
62
63 static HINF search_for_inf(LPCVOID InfSpec, DWORD SearchControl)
64 {
65     HINF hInf = INVALID_HANDLE_VALUE;
66     WCHAR inf_path[MAX_PATH];
67
68     static const WCHAR infW[] = {'\\','i','n','f','\\',0};
69     static const WCHAR system32W[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
70
71     if (SearchControl == INFINFO_REVERSE_DEFAULT_SEARCH)
72     {
73         GetWindowsDirectoryW(inf_path, MAX_PATH);
74         lstrcatW(inf_path, system32W);
75         lstrcatW(inf_path, InfSpec);
76
77         hInf = SetupOpenInfFileW(inf_path, NULL,
78                                  INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
79         if (hInf != INVALID_HANDLE_VALUE)
80             return hInf;
81
82         GetWindowsDirectoryW(inf_path, MAX_PATH);
83         lstrcpyW(inf_path, infW);
84         lstrcatW(inf_path, InfSpec);
85
86         return SetupOpenInfFileW(inf_path, NULL,
87                                  INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
88     }
89
90     return INVALID_HANDLE_VALUE;
91 }
92
93 /***********************************************************************
94  *      SetupGetInfInformationA    (SETUPAPI.@)
95  *
96  */
97 BOOL WINAPI SetupGetInfInformationA(LPCVOID InfSpec, DWORD SearchControl,
98                                     PSP_INF_INFORMATION ReturnBuffer,
99                                     DWORD ReturnBufferSize, PDWORD RequiredSize)
100 {
101     LPWSTR inf = (LPWSTR)InfSpec;
102     DWORD len;
103     BOOL ret;
104
105     if (InfSpec && SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
106     {
107         len = lstrlenA(InfSpec) + 1;
108         inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
109         MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, inf, len);
110     }
111
112     ret = SetupGetInfInformationW(inf, SearchControl, ReturnBuffer,
113                                   ReturnBufferSize, RequiredSize);
114
115     if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
116         HeapFree(GetProcessHeap(), 0, inf);
117
118     return ret;
119 }
120
121 /***********************************************************************
122  *      SetupGetInfInformationW    (SETUPAPI.@)
123  * 
124  * BUGS
125  *   Only handles the case when InfSpec is an INF handle.
126  */
127 BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl,
128                                      PSP_INF_INFORMATION ReturnBuffer,
129                                      DWORD ReturnBufferSize, PDWORD RequiredSize)
130 {
131     HINF inf;
132     BOOL ret;
133
134     TRACE("(%p, %ld, %p, %ld, %p)\n", InfSpec, SearchControl, ReturnBuffer,
135            ReturnBufferSize, RequiredSize);
136
137     if (!InfSpec)
138     {
139         if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
140             SetLastError(ERROR_INVALID_HANDLE);
141         else
142             SetLastError(ERROR_INVALID_PARAMETER);
143
144         return FALSE;
145     }
146
147     if (!ReturnBuffer && ReturnBufferSize)
148     {
149         SetLastError(ERROR_INVALID_PARAMETER);
150         return FALSE;
151     }
152
153     switch (SearchControl)
154     {
155         case INFINFO_INF_SPEC_IS_HINF:
156             inf = (HINF)InfSpec;
157             break;
158         case INFINFO_INF_NAME_IS_ABSOLUTE:
159         case INFINFO_DEFAULT_SEARCH:
160             inf = SetupOpenInfFileW(InfSpec, NULL,
161                                     INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
162             break;
163         case INFINFO_REVERSE_DEFAULT_SEARCH:
164             inf = search_for_inf(InfSpec, SearchControl);
165             break;
166         case INFINFO_INF_PATH_LIST_SEARCH:
167             FIXME("Unhandled search control: %ld\n", SearchControl);
168
169             if (RequiredSize)
170                 *RequiredSize = 0;
171
172             return FALSE;
173         default:
174             SetLastError(ERROR_INVALID_PARAMETER);
175             return FALSE;
176     }
177
178     if (inf == INVALID_HANDLE_VALUE)
179     {
180         SetLastError(ERROR_FILE_NOT_FOUND);
181         return FALSE;
182     }
183
184     ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, RequiredSize);
185
186     if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
187         SetupCloseInfFile(inf);
188
189     return ret;
190 }
191
192 /***********************************************************************
193  *      SetupQueryInfFileInformationA    (SETUPAPI.@)
194  */
195 BOOL WINAPI SetupQueryInfFileInformationA(PSP_INF_INFORMATION InfInformation,
196                                           UINT InfIndex, PSTR ReturnBuffer,
197                                           DWORD ReturnBufferSize, PDWORD RequiredSize)
198 {
199     LPWSTR filenameW;
200     DWORD size;
201     BOOL ret;
202
203     ret = SetupQueryInfFileInformationW(InfInformation, InfIndex, NULL, 0, &size);
204     if (!ret)
205         return FALSE;
206
207     filenameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
208
209     ret = SetupQueryInfFileInformationW(InfInformation, InfIndex,
210                                         filenameW, size, &size);
211     if (!ret)
212     {
213         HeapFree(GetProcessHeap(), 0, filenameW);
214         return FALSE;
215     }
216
217     if (RequiredSize)
218         *RequiredSize = size;
219
220     if (!ReturnBuffer)
221     {
222         if (ReturnBufferSize)
223         {
224             SetLastError(ERROR_INVALID_PARAMETER);
225             return FALSE;
226         }
227
228         return TRUE;
229     }
230
231     if (size > ReturnBufferSize)
232     {
233         SetLastError(ERROR_INSUFFICIENT_BUFFER);
234         return FALSE;
235     }
236
237     WideCharToMultiByte(CP_ACP, 0, filenameW, -1, ReturnBuffer, size, NULL, NULL);
238     HeapFree(GetProcessHeap(), 0, filenameW);
239
240     return ret;
241 }
242
243 /***********************************************************************
244  *      SetupQueryInfFileInformationW    (SETUPAPI.@)
245  */
246 BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation,
247                                           UINT InfIndex, PWSTR ReturnBuffer,
248                                           DWORD ReturnBufferSize, PDWORD RequiredSize) 
249 {
250     DWORD len;
251     LPWSTR ptr;
252
253     TRACE("(%p, %u, %p, %ld, %p) Stub!\n", InfInformation, InfIndex,
254           ReturnBuffer, ReturnBufferSize, RequiredSize);
255
256     if (!InfInformation)
257     {
258         SetLastError(ERROR_INVALID_PARAMETER);
259         return FALSE;
260     }
261
262     if (InfIndex != 0)
263         FIXME("Appended INF files are not handled\n");
264
265     ptr = (LPWSTR)&InfInformation->VersionData[0];
266     len = lstrlenW(ptr);
267
268     if (RequiredSize)
269         *RequiredSize = len + 1;
270
271     if (!ReturnBuffer)
272         return TRUE;
273
274     if (ReturnBufferSize < len)
275     {
276         SetLastError(ERROR_INSUFFICIENT_BUFFER);
277         return FALSE;
278     }
279
280     lstrcpyW(ReturnBuffer, ptr);
281     return TRUE;
282 }