~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/setupapi/query.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "setupapi.h"
 28 #include "advpub.h"
 29 #include "winnls.h"
 30 #include "wine/debug.h"
 31 #include "wine/unicode.h"
 32 #include "setupapi_private.h"
 33 
 34 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
 35 
 36 #ifdef __i386__
 37 static const WCHAR source_disks_names_platform[] =
 38     {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','x','8','6',0};
 39 static const WCHAR source_disks_files_platform[] =
 40     {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','x','8','6',0};
 41 #elif defined(__x86_64)
 42 static const WCHAR source_disks_names_platform[] =
 43     {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','a','m','d','6','4',0};
 44 static const WCHAR source_disks_files_platform[] =
 45     {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','a','m','d','6','4',0};
 46 #else  /* FIXME: other platforms */
 47 static const WCHAR source_disks_names_platform[] =
 48     {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
 49 static const WCHAR source_disks_files_platform[] =
 50     {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
 51 #endif
 52 static const WCHAR source_disks_names[] =
 53     {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
 54 static const WCHAR source_disks_files[] =
 55     {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
 56 
 57 /* fills the PSP_INF_INFORMATION struct fill_info is TRUE
 58  * always returns the required size of the information
 59  */
 60 static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWORD *required)
 61 {
 62     LPCWSTR filename = PARSER_get_inf_filename(inf);
 63     DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData)
 64                         + (lstrlenW(filename) + 1) * sizeof(WCHAR);
 65 
 66     if (required) *required = total_size;
 67 
 68     /* FIXME: we need to parse the INF file to find the correct version info */
 69     if (buffer)
 70     {
 71         if (size < total_size)
 72         {
 73             SetLastError(ERROR_INSUFFICIENT_BUFFER);
 74             return FALSE;
 75         }
 76         buffer->InfStyle = INF_STYLE_WIN4;
 77         buffer->InfCount = 1;
 78         /* put the filename in buffer->VersionData */
 79         lstrcpyW((LPWSTR)&buffer->VersionData[0], filename);
 80     }
 81     return TRUE;
 82 }
 83 
 84 static HINF search_for_inf(LPCVOID InfSpec, DWORD SearchControl)
 85 {
 86     HINF hInf = INVALID_HANDLE_VALUE;
 87     WCHAR inf_path[MAX_PATH];
 88 
 89     static const WCHAR infW[] = {'\\','i','n','f','\\',0};
 90     static const WCHAR system32W[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
 91 
 92     if (SearchControl == INFINFO_REVERSE_DEFAULT_SEARCH)
 93     {
 94         GetWindowsDirectoryW(inf_path, MAX_PATH);
 95         lstrcatW(inf_path, system32W);
 96         lstrcatW(inf_path, InfSpec);
 97 
 98         hInf = SetupOpenInfFileW(inf_path, NULL,
 99                                  INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
100         if (hInf != INVALID_HANDLE_VALUE)
101             return hInf;
102 
103         GetWindowsDirectoryW(inf_path, MAX_PATH);
104         lstrcpyW(inf_path, infW);
105         lstrcatW(inf_path, InfSpec);
106 
107         return SetupOpenInfFileW(inf_path, NULL,
108                                  INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
109     }
110 
111     return INVALID_HANDLE_VALUE;
112 }
113 
114 /***********************************************************************
115  *      SetupGetInfInformationA    (SETUPAPI.@)
116  *
117  */
118 BOOL WINAPI SetupGetInfInformationA(LPCVOID InfSpec, DWORD SearchControl,
119                                     PSP_INF_INFORMATION ReturnBuffer,
120                                     DWORD ReturnBufferSize, PDWORD RequiredSize)
121 {
122     LPWSTR inf = (LPWSTR)InfSpec;
123     DWORD len;
124     BOOL ret;
125 
126     if (InfSpec && SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
127     {
128         len = lstrlenA(InfSpec) + 1;
129         inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
130         MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, inf, len);
131     }
132 
133     ret = SetupGetInfInformationW(inf, SearchControl, ReturnBuffer,
134                                   ReturnBufferSize, RequiredSize);
135 
136     if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
137         HeapFree(GetProcessHeap(), 0, inf);
138 
139     return ret;
140 }
141 
142 /***********************************************************************
143  *      SetupGetInfInformationW    (SETUPAPI.@)
144  * 
145  * BUGS
146  *   Only handles the case when InfSpec is an INF handle.
147  */
148 BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl,
149                                      PSP_INF_INFORMATION ReturnBuffer,
150                                      DWORD ReturnBufferSize, PDWORD RequiredSize)
151 {
152     HINF inf;
153     BOOL ret;
154     DWORD infSize;
155 
156     TRACE("(%p, %d, %p, %d, %p)\n", InfSpec, SearchControl, ReturnBuffer,
157            ReturnBufferSize, RequiredSize);
158 
159     if (!InfSpec)
160     {
161         if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
162             SetLastError(ERROR_INVALID_HANDLE);
163         else
164             SetLastError(ERROR_INVALID_PARAMETER);
165 
166         return FALSE;
167     }
168 
169     switch (SearchControl)
170     {
171         case INFINFO_INF_SPEC_IS_HINF:
172             inf = (HINF)InfSpec;
173             break;
174         case INFINFO_INF_NAME_IS_ABSOLUTE:
175         case INFINFO_DEFAULT_SEARCH:
176             inf = SetupOpenInfFileW(InfSpec, NULL,
177                                     INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
178             break;
179         case INFINFO_REVERSE_DEFAULT_SEARCH:
180             inf = search_for_inf(InfSpec, SearchControl);
181             break;
182         case INFINFO_INF_PATH_LIST_SEARCH:
183             FIXME("Unhandled search control: %d\n", SearchControl);
184 
185             if (RequiredSize)
186                 *RequiredSize = 0;
187 
188             return FALSE;
189         default:
190             SetLastError(ERROR_INVALID_PARAMETER);
191             return FALSE;
192     }
193 
194     if (inf == INVALID_HANDLE_VALUE)
195     {
196         SetLastError(ERROR_FILE_NOT_FOUND);
197         return FALSE;
198     }
199 
200     ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, &infSize);
201     if (!ReturnBuffer && (ReturnBufferSize >= infSize))
202     {
203         SetLastError(ERROR_INVALID_PARAMETER);
204         ret = FALSE;
205     }
206     if (RequiredSize) *RequiredSize = infSize;
207 
208     if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
209         SetupCloseInfFile(inf);
210 
211     return ret;
212 }
213 
214 /***********************************************************************
215  *      SetupQueryInfFileInformationA    (SETUPAPI.@)
216  */
217 BOOL WINAPI SetupQueryInfFileInformationA(PSP_INF_INFORMATION InfInformation,
218                                           UINT InfIndex, PSTR ReturnBuffer,
219                                           DWORD ReturnBufferSize, PDWORD RequiredSize)
220 {
221     LPWSTR filenameW;
222     DWORD size;
223     BOOL ret;
224 
225     ret = SetupQueryInfFileInformationW(InfInformation, InfIndex, NULL, 0, &size);
226     if (!ret)
227         return FALSE;
228 
229     filenameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
230 
231     ret = SetupQueryInfFileInformationW(InfInformation, InfIndex,
232                                         filenameW, size, &size);
233     if (!ret)
234     {
235         HeapFree(GetProcessHeap(), 0, filenameW);
236         return FALSE;
237     }
238 
239     if (RequiredSize)
240         *RequiredSize = size;
241 
242     if (!ReturnBuffer)
243     {
244         HeapFree(GetProcessHeap(), 0, filenameW);
245         if (ReturnBufferSize)
246         {
247             SetLastError(ERROR_INVALID_PARAMETER);
248             return FALSE;
249         }
250 
251         return TRUE;
252     }
253 
254     if (size > ReturnBufferSize)
255     {
256         HeapFree(GetProcessHeap(), 0, filenameW);
257         SetLastError(ERROR_INSUFFICIENT_BUFFER);
258         return FALSE;
259     }
260 
261     WideCharToMultiByte(CP_ACP, 0, filenameW, -1, ReturnBuffer, size, NULL, NULL);
262     HeapFree(GetProcessHeap(), 0, filenameW);
263 
264     return ret;
265 }
266 
267 /***********************************************************************
268  *      SetupQueryInfFileInformationW    (SETUPAPI.@)
269  */
270 BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation,
271                                           UINT InfIndex, PWSTR ReturnBuffer,
272                                           DWORD ReturnBufferSize, PDWORD RequiredSize) 
273 {
274     DWORD len;
275     LPWSTR ptr;
276 
277     TRACE("(%p, %u, %p, %d, %p) Stub!\n", InfInformation, InfIndex,
278           ReturnBuffer, ReturnBufferSize, RequiredSize);
279 
280     if (!InfInformation)
281     {
282         SetLastError(ERROR_INVALID_PARAMETER);
283         return FALSE;
284     }
285 
286     if (InfIndex != 0)
287         FIXME("Appended INF files are not handled\n");
288 
289     ptr = (LPWSTR)&InfInformation->VersionData[0];
290     len = lstrlenW(ptr);
291 
292     if (RequiredSize)
293         *RequiredSize = len + 1;
294 
295     if (!ReturnBuffer)
296         return TRUE;
297 
298     if (ReturnBufferSize < len)
299     {
300         SetLastError(ERROR_INSUFFICIENT_BUFFER);
301         return FALSE;
302     }
303 
304     lstrcpyW(ReturnBuffer, ptr);
305     return TRUE;
306 }
307 
308 /***********************************************************************
309  *            SetupGetSourceFileLocationA   (SETUPAPI.@)
310  */
311 
312 BOOL WINAPI SetupGetSourceFileLocationA( HINF hinf, PINFCONTEXT context, PCSTR filename,
313                                          PUINT source_id, PSTR buffer, DWORD buffer_size,
314                                          PDWORD required_size )
315 {
316     BOOL ret = FALSE;
317     WCHAR *filenameW = NULL, *bufferW = NULL;
318     DWORD required;
319     INT size;
320 
321     TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_a(filename), source_id,
322           buffer, buffer_size, required_size);
323 
324     if (filename && *filename && !(filenameW = strdupAtoW( filename )))
325         return FALSE;
326 
327     if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, NULL, 0, &required ))
328         goto done;
329 
330     if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
331         goto done;
332 
333     if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, bufferW, required, NULL ))
334         goto done;
335 
336     size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
337     if (required_size) *required_size = size;
338 
339     if (buffer)
340     {
341         if (buffer_size >= size)
342             WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
343         else
344         {
345             SetLastError( ERROR_INSUFFICIENT_BUFFER );
346             goto done;
347         }
348     }
349     ret = TRUE;
350 
351  done:
352     HeapFree( GetProcessHeap(), 0, filenameW );
353     HeapFree( GetProcessHeap(), 0, bufferW );
354     return ret;
355 }
356 
357 static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename )
358 {
359     DWORD size;
360     LPWSTR source_id;
361 
362     if (!SetupFindFirstLineW( hinf, source_disks_files_platform, filename, context ) &&
363         !SetupFindFirstLineW( hinf, source_disks_files, filename, context ))
364         return NULL;
365 
366     if (!SetupGetStringFieldW( context, 1, NULL, 0, &size ))
367         return NULL;
368 
369     if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
370         return NULL;
371 
372     if (!SetupGetStringFieldW( context, 1, source_id, size, NULL ))
373     {
374         HeapFree( GetProcessHeap(), 0, source_id );
375         return NULL;
376     }
377 
378     if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id, context ) &&
379         !SetupFindFirstLineW( hinf, source_disks_names, source_id, context ))
380     {
381         HeapFree( GetProcessHeap(), 0, source_id );
382         return NULL;
383     }
384     return source_id;
385 }
386 
387 /***********************************************************************
388  *            SetupGetSourceFileLocationW   (SETUPAPI.@)
389  */
390 
391 BOOL WINAPI SetupGetSourceFileLocationW( HINF hinf, PINFCONTEXT context, PCWSTR filename,
392                                          PUINT source_id, PWSTR buffer, DWORD buffer_size,
393                                          PDWORD required_size )
394 {
395     INFCONTEXT ctx;
396     WCHAR *end, *source_id_str;
397 
398     TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_w(filename), source_id,
399           buffer, buffer_size, required_size);
400 
401     if (!context) context = &ctx;
402 
403     if (!(source_id_str = get_source_id( hinf, context, filename )))
404         return FALSE;
405 
406     *source_id = strtolW( source_id_str, &end, 10 );
407     if (end == source_id_str || *end)
408     {
409         HeapFree( GetProcessHeap(), 0, source_id_str );
410         return FALSE;
411     }
412     HeapFree( GetProcessHeap(), 0, source_id_str );
413 
414     if (SetupGetStringFieldW( context, 4, buffer, buffer_size, required_size ))
415         return TRUE;
416 
417     if (required_size) *required_size = 1;
418     if (buffer)
419     {
420         if (buffer_size >= 1) buffer[0] = 0;
421         else
422         {
423             SetLastError( ERROR_INSUFFICIENT_BUFFER );
424             return FALSE;
425         }
426     }
427     return TRUE;
428 }
429 
430 /***********************************************************************
431  *            SetupGetSourceInfoA  (SETUPAPI.@)
432  */
433 
434 BOOL WINAPI SetupGetSourceInfoA( HINF hinf, UINT source_id, UINT info,
435                                  PSTR buffer, DWORD buffer_size, LPDWORD required_size )
436 {
437     BOOL ret = FALSE;
438     WCHAR *bufferW = NULL;
439     DWORD required;
440     INT size;
441 
442     TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
443           required_size);
444 
445     if (!SetupGetSourceInfoW( hinf, source_id, info, NULL, 0, &required ))
446         return FALSE;
447 
448     if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
449         return FALSE;
450 
451     if (!SetupGetSourceInfoW( hinf, source_id, info, bufferW, required, NULL ))
452         goto done;
453 
454     size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
455     if (required_size) *required_size = size;
456 
457     if (buffer)
458     {
459         if (buffer_size >= size)
460             WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
461         else
462         {
463             SetLastError( ERROR_INSUFFICIENT_BUFFER );
464             goto done;
465         }
466     }
467     ret = TRUE;
468 
469  done:
470     HeapFree( GetProcessHeap(), 0, bufferW );
471     return ret;
472 }
473 
474 /***********************************************************************
475  *            SetupGetSourceInfoW  (SETUPAPI.@)
476  */
477 
478 BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info,
479                                  PWSTR buffer, DWORD buffer_size, LPDWORD required_size )
480 {
481     INFCONTEXT ctx;
482     WCHAR source_id_str[11];
483     static const WCHAR fmt[] = {'%','d',0};
484     DWORD index;
485 
486     TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
487           required_size);
488 
489     sprintfW( source_id_str, fmt, source_id );
490 
491     if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id_str, &ctx ) &&
492         !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx ))
493         return FALSE;
494 
495     switch (info)
496     {
497     case SRCINFO_PATH:          index = 4; break;
498     case SRCINFO_TAGFILE:       index = 2; break;
499     case SRCINFO_DESCRIPTION:   index = 1; break;
500     default:
501         WARN("unknown info level: %d\n", info);
502         return FALSE;
503     }
504 
505     if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size ))
506         return TRUE;
507 
508     if (required_size) *required_size = 1;
509     if (buffer)
510     {
511         if (buffer_size >= 1) buffer[0] = 0;
512         else
513         {
514             SetLastError( ERROR_INSUFFICIENT_BUFFER );
515             return FALSE;
516         }
517     }
518     return TRUE;
519 }
520 
521 /***********************************************************************
522  *            SetupGetTargetPathA   (SETUPAPI.@)
523  */
524 
525 BOOL WINAPI SetupGetTargetPathA( HINF hinf, PINFCONTEXT context, PCSTR section, PSTR buffer,
526                                  DWORD buffer_size, PDWORD required_size )
527 {
528     BOOL ret = FALSE;
529     WCHAR *sectionW = NULL, *bufferW = NULL;
530     DWORD required;
531     INT size;
532 
533     TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_a(section), buffer,
534           buffer_size, required_size);
535 
536     if (section && !(sectionW = strdupAtoW( section )))
537         return FALSE;
538 
539     if (!SetupGetTargetPathW( hinf, context, sectionW, NULL, 0, &required ))
540         goto done;
541 
542     if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
543         goto done;
544 
545     if (!SetupGetTargetPathW( hinf, context, sectionW, bufferW, required, NULL ))
546         goto done;
547 
548     size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
549     if (required_size) *required_size = size;
550 
551     if (buffer)
552     {
553         if (buffer_size >= size)
554             WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
555         else
556         {
557             SetLastError( ERROR_INSUFFICIENT_BUFFER );
558             goto done;
559         }
560     }
561     ret = TRUE;
562 
563  done:
564     HeapFree( GetProcessHeap(), 0, sectionW );
565     HeapFree( GetProcessHeap(), 0, bufferW );
566     return ret;
567 }
568 
569 /***********************************************************************
570  *            SetupGetTargetPathW   (SETUPAPI.@)
571  */
572 
573 BOOL WINAPI SetupGetTargetPathW( HINF hinf, PINFCONTEXT context, PCWSTR section, PWSTR buffer,
574                                  DWORD buffer_size, PDWORD required_size )
575 {
576     static const WCHAR destination_dirs[] =
577         {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
578     static const WCHAR default_dest_dir[]  =
579         {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
580 
581     INFCONTEXT ctx;
582     WCHAR *dir, systemdir[MAX_PATH];
583     unsigned int size;
584     BOOL ret = FALSE;
585 
586     TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_w(section), buffer,
587           buffer_size, required_size);
588 
589     if (context) ret = SetupFindFirstLineW( hinf, destination_dirs, NULL, context );
590     else if (section)
591     {
592         if (!(ret = SetupFindFirstLineW( hinf, destination_dirs, section, &ctx )))
593             ret = SetupFindFirstLineW( hinf, destination_dirs, default_dest_dir, &ctx );
594     }
595     if (!ret || !(dir = PARSER_get_dest_dir( context ? context : &ctx )))
596     {
597         GetSystemDirectoryW( systemdir, MAX_PATH );
598         dir = systemdir;
599     }
600     size = strlenW( dir ) + 1;
601     if (required_size) *required_size = size;
602 
603     if (buffer)
604     {
605         if (buffer_size >= size)
606             lstrcpyW( buffer, dir );
607         else
608         {
609             SetLastError( ERROR_INSUFFICIENT_BUFFER );
610             HeapFree( GetProcessHeap(), 0, dir );
611             return FALSE;
612         }
613     }
614     if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir );
615     return TRUE;
616 }
617 
618 /***********************************************************************
619  *            SetupQueryInfOriginalFileInformationA   (SETUPAPI.@)
620  */
621 BOOL WINAPI SetupQueryInfOriginalFileInformationA(
622     PSP_INF_INFORMATION InfInformation, UINT InfIndex,
623     PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
624     PSP_ORIGINAL_FILE_INFO_A OriginalFileInfo)
625 {
626     BOOL ret;
627     SP_ORIGINAL_FILE_INFO_W OriginalFileInfoW;
628 
629     TRACE("(%p, %d, %p, %p)\n", InfInformation, InfIndex,
630         AlternativePlatformInfo, OriginalFileInfo);
631 
632     if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
633     {
634         WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
635         SetLastError( ERROR_INVALID_USER_BUFFER );
636         return FALSE;
637     }
638 
639     OriginalFileInfoW.cbSize = sizeof(OriginalFileInfoW);
640     ret = SetupQueryInfOriginalFileInformationW(InfInformation, InfIndex,
641         AlternativePlatformInfo, &OriginalFileInfoW);
642     if (ret)
643     {
644         WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalInfName, -1,
645             OriginalFileInfo->OriginalInfName, MAX_PATH, NULL, NULL);
646         WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalCatalogName, -1,
647             OriginalFileInfo->OriginalCatalogName, MAX_PATH, NULL, NULL);
648     }
649 
650     return ret;
651 }
652 
653 /***********************************************************************
654  *            SetupQueryInfOriginalFileInformationW   (SETUPAPI.@)
655  */
656 BOOL WINAPI SetupQueryInfOriginalFileInformationW(
657     PSP_INF_INFORMATION InfInformation, UINT InfIndex,
658     PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
659     PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo)
660 {
661     LPCWSTR inf_name;
662     LPCWSTR inf_path;
663     HINF hinf;
664     static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
665     static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };
666 
667     FIXME("(%p, %d, %p, %p): semi-stub\n", InfInformation, InfIndex,
668         AlternativePlatformInfo, OriginalFileInfo);
669 
670     if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
671     {
672         WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
673         SetLastError(ERROR_INVALID_USER_BUFFER);
674         return FALSE;
675     }
676 
677     inf_path = (LPWSTR)&InfInformation->VersionData[0];
678 
679     /* FIXME: we should get OriginalCatalogName from CatalogFile line in
680      * the original inf file and cache it, but that would require building a
681      * .pnf file. */
682     hinf = SetupOpenInfFileW(inf_path, NULL, INF_STYLE_WIN4, NULL);
683     if (hinf == INVALID_HANDLE_VALUE) return FALSE;
684 
685     if (!SetupGetLineTextW(NULL, hinf, wszVersion, wszCatalogFile,
686                            OriginalFileInfo->OriginalCatalogName,
687                            sizeof(OriginalFileInfo->OriginalCatalogName)/sizeof(OriginalFileInfo->OriginalCatalogName[0]),
688                            NULL))
689     {
690         OriginalFileInfo->OriginalCatalogName[0] = '\0';
691     }
692     SetupCloseInfFile(hinf);
693 
694     /* FIXME: not quite correct as we just return the same file name as
695      * destination (copied) inf file, not the source (original) inf file.
696      * to fix it properly would require building a .pnf file */
697     /* file name is stored in VersionData field of InfInformation */
698     inf_name = strrchrW(inf_path, '\\');
699     if (inf_name) inf_name++;
700     else inf_name = inf_path;
701 
702     strcpyW(OriginalFileInfo->OriginalInfName, inf_name);
703 
704     return TRUE;
705 }
706 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.