include: Use the hard-float calling convention for Windows APIs on ARM
[wine.git] / dlls / setupapi / query.c
blobeaeadc0f2bb82389d9aa2f1e408ec820463cc895
1 /*
2 * setupapi query functions
4 * Copyright 2006 James Hawkins
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.
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.
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
21 #include <stdarg.h>
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"
34 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
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};
57 /* fills the PSP_INF_INFORMATION struct fill_info is TRUE
58 * always returns the required size of the information
60 static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWORD *required)
62 LPCWSTR filename = PARSER_get_inf_filename(inf);
63 DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData)
64 + (lstrlenW(filename) + 1) * sizeof(WCHAR);
66 if (required) *required = total_size;
68 /* FIXME: we need to parse the INF file to find the correct version info */
69 if (buffer)
71 if (size < total_size)
73 SetLastError(ERROR_INSUFFICIENT_BUFFER);
74 return FALSE;
76 buffer->InfStyle = INF_STYLE_WIN4;
77 buffer->InfCount = 1;
78 /* put the filename in buffer->VersionData */
79 lstrcpyW((LPWSTR)&buffer->VersionData[0], filename);
81 return TRUE;
84 static HINF search_for_inf(LPCVOID InfSpec, DWORD SearchControl)
86 HINF hInf = INVALID_HANDLE_VALUE;
87 WCHAR inf_path[MAX_PATH];
89 static const WCHAR infW[] = {'\\','i','n','f','\\',0};
90 static const WCHAR system32W[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
92 if (SearchControl == INFINFO_REVERSE_DEFAULT_SEARCH)
94 GetWindowsDirectoryW(inf_path, MAX_PATH);
95 lstrcatW(inf_path, system32W);
96 lstrcatW(inf_path, InfSpec);
98 hInf = SetupOpenInfFileW(inf_path, NULL,
99 INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
100 if (hInf != INVALID_HANDLE_VALUE)
101 return hInf;
103 GetWindowsDirectoryW(inf_path, MAX_PATH);
104 lstrcpyW(inf_path, infW);
105 lstrcatW(inf_path, InfSpec);
107 return SetupOpenInfFileW(inf_path, NULL,
108 INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
111 return INVALID_HANDLE_VALUE;
114 /***********************************************************************
115 * SetupGetInfInformationA (SETUPAPI.@)
118 BOOL WINAPI SetupGetInfInformationA(LPCVOID InfSpec, DWORD SearchControl,
119 PSP_INF_INFORMATION ReturnBuffer,
120 DWORD ReturnBufferSize, PDWORD RequiredSize)
122 LPWSTR inf = (LPWSTR)InfSpec;
123 DWORD len;
124 BOOL ret;
126 if (InfSpec && SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
128 len = MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, NULL, 0);
129 inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
130 if (!inf)
132 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
133 return FALSE;
135 MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, inf, len);
138 ret = SetupGetInfInformationW(inf, SearchControl, ReturnBuffer,
139 ReturnBufferSize, RequiredSize);
141 if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
142 HeapFree(GetProcessHeap(), 0, inf);
144 return ret;
147 /***********************************************************************
148 * SetupGetInfInformationW (SETUPAPI.@)
150 * BUGS
151 * Only handles the case when InfSpec is an INF handle.
153 BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl,
154 PSP_INF_INFORMATION ReturnBuffer,
155 DWORD ReturnBufferSize, PDWORD RequiredSize)
157 HINF inf;
158 BOOL ret;
159 DWORD infSize;
161 TRACE("(%p, %d, %p, %d, %p)\n", InfSpec, SearchControl, ReturnBuffer,
162 ReturnBufferSize, RequiredSize);
164 if (!InfSpec)
166 if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
167 SetLastError(ERROR_INVALID_HANDLE);
168 else
169 SetLastError(ERROR_INVALID_PARAMETER);
171 return FALSE;
174 switch (SearchControl)
176 case INFINFO_INF_SPEC_IS_HINF:
177 inf = (HINF)InfSpec;
178 break;
179 case INFINFO_INF_NAME_IS_ABSOLUTE:
180 case INFINFO_DEFAULT_SEARCH:
181 inf = SetupOpenInfFileW(InfSpec, NULL,
182 INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
183 break;
184 case INFINFO_REVERSE_DEFAULT_SEARCH:
185 inf = search_for_inf(InfSpec, SearchControl);
186 break;
187 case INFINFO_INF_PATH_LIST_SEARCH:
188 FIXME("Unhandled search control: %d\n", SearchControl);
190 if (RequiredSize)
191 *RequiredSize = 0;
193 return FALSE;
194 default:
195 SetLastError(ERROR_INVALID_PARAMETER);
196 return FALSE;
199 if (inf == INVALID_HANDLE_VALUE)
201 SetLastError(ERROR_FILE_NOT_FOUND);
202 return FALSE;
205 ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, &infSize);
206 if (!ReturnBuffer && (ReturnBufferSize >= infSize))
208 SetLastError(ERROR_INVALID_PARAMETER);
209 ret = FALSE;
211 if (RequiredSize) *RequiredSize = infSize;
213 if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
214 SetupCloseInfFile(inf);
216 return ret;
219 /***********************************************************************
220 * SetupQueryInfFileInformationA (SETUPAPI.@)
222 BOOL WINAPI SetupQueryInfFileInformationA(PSP_INF_INFORMATION InfInformation,
223 UINT InfIndex, PSTR ReturnBuffer,
224 DWORD ReturnBufferSize, PDWORD RequiredSize)
226 LPWSTR filenameW;
227 DWORD size;
228 BOOL ret;
230 ret = SetupQueryInfFileInformationW(InfInformation, InfIndex, NULL, 0, &size);
231 if (!ret)
232 return FALSE;
234 filenameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
236 ret = SetupQueryInfFileInformationW(InfInformation, InfIndex,
237 filenameW, size, &size);
238 if (!ret)
240 HeapFree(GetProcessHeap(), 0, filenameW);
241 return FALSE;
244 if (RequiredSize)
245 *RequiredSize = size;
247 if (!ReturnBuffer)
249 HeapFree(GetProcessHeap(), 0, filenameW);
250 if (ReturnBufferSize)
252 SetLastError(ERROR_INVALID_PARAMETER);
253 return FALSE;
256 return TRUE;
259 if (size > ReturnBufferSize)
261 HeapFree(GetProcessHeap(), 0, filenameW);
262 SetLastError(ERROR_INSUFFICIENT_BUFFER);
263 return FALSE;
266 WideCharToMultiByte(CP_ACP, 0, filenameW, -1, ReturnBuffer, size, NULL, NULL);
267 HeapFree(GetProcessHeap(), 0, filenameW);
269 return ret;
272 /***********************************************************************
273 * SetupQueryInfFileInformationW (SETUPAPI.@)
275 BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation,
276 UINT InfIndex, PWSTR ReturnBuffer,
277 DWORD ReturnBufferSize, PDWORD RequiredSize)
279 DWORD len;
280 LPWSTR ptr;
282 TRACE("(%p, %u, %p, %d, %p) Stub!\n", InfInformation, InfIndex,
283 ReturnBuffer, ReturnBufferSize, RequiredSize);
285 if (!InfInformation)
287 SetLastError(ERROR_INVALID_PARAMETER);
288 return FALSE;
291 if (InfIndex != 0)
292 FIXME("Appended INF files are not handled\n");
294 ptr = (LPWSTR)InfInformation->VersionData;
295 len = lstrlenW(ptr);
297 if (RequiredSize)
298 *RequiredSize = len + 1;
300 if (!ReturnBuffer)
301 return TRUE;
303 if (ReturnBufferSize < len)
305 SetLastError(ERROR_INSUFFICIENT_BUFFER);
306 return FALSE;
309 lstrcpyW(ReturnBuffer, ptr);
310 return TRUE;
313 /***********************************************************************
314 * SetupGetSourceFileLocationA (SETUPAPI.@)
317 BOOL WINAPI SetupGetSourceFileLocationA( HINF hinf, PINFCONTEXT context, PCSTR filename,
318 PUINT source_id, PSTR buffer, DWORD buffer_size,
319 PDWORD required_size )
321 BOOL ret = FALSE;
322 WCHAR *filenameW = NULL, *bufferW = NULL;
323 DWORD required;
324 INT size;
326 TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_a(filename), source_id,
327 buffer, buffer_size, required_size);
329 if (filename && *filename && !(filenameW = strdupAtoW( filename )))
330 return FALSE;
332 if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, NULL, 0, &required ))
333 goto done;
335 if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
336 goto done;
338 if (!SetupGetSourceFileLocationW( hinf, context, filenameW, source_id, bufferW, required, NULL ))
339 goto done;
341 size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
342 if (required_size) *required_size = size;
344 if (buffer)
346 if (buffer_size >= size)
347 WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
348 else
350 SetLastError( ERROR_INSUFFICIENT_BUFFER );
351 goto done;
354 ret = TRUE;
356 done:
357 HeapFree( GetProcessHeap(), 0, filenameW );
358 HeapFree( GetProcessHeap(), 0, bufferW );
359 return ret;
362 static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename )
364 DWORD size;
365 LPWSTR source_id;
367 if (!SetupFindFirstLineW( hinf, source_disks_files_platform, filename, context ) &&
368 !SetupFindFirstLineW( hinf, source_disks_files, filename, context ))
369 return NULL;
371 if (!SetupGetStringFieldW( context, 1, NULL, 0, &size ))
372 return NULL;
374 if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
375 return NULL;
377 if (!SetupGetStringFieldW( context, 1, source_id, size, NULL ))
379 HeapFree( GetProcessHeap(), 0, source_id );
380 return NULL;
383 if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id, context ) &&
384 !SetupFindFirstLineW( hinf, source_disks_names, source_id, context ))
386 HeapFree( GetProcessHeap(), 0, source_id );
387 return NULL;
389 return source_id;
392 /***********************************************************************
393 * SetupGetSourceFileLocationW (SETUPAPI.@)
396 BOOL WINAPI SetupGetSourceFileLocationW( HINF hinf, PINFCONTEXT context, PCWSTR filename,
397 PUINT source_id, PWSTR buffer, DWORD buffer_size,
398 PDWORD required_size )
400 INFCONTEXT ctx;
401 WCHAR *end, *source_id_str;
403 TRACE("%p, %p, %s, %p, %p, 0x%08x, %p\n", hinf, context, debugstr_w(filename), source_id,
404 buffer, buffer_size, required_size);
406 if (!context) context = &ctx;
408 if (!(source_id_str = get_source_id( hinf, context, filename )))
409 return FALSE;
411 *source_id = strtolW( source_id_str, &end, 10 );
412 if (end == source_id_str || *end)
414 HeapFree( GetProcessHeap(), 0, source_id_str );
415 return FALSE;
417 HeapFree( GetProcessHeap(), 0, source_id_str );
419 if (SetupGetStringFieldW( context, 4, buffer, buffer_size, required_size ))
420 return TRUE;
422 if (required_size) *required_size = 1;
423 if (buffer)
425 if (buffer_size >= 1) buffer[0] = 0;
426 else
428 SetLastError( ERROR_INSUFFICIENT_BUFFER );
429 return FALSE;
432 return TRUE;
435 /***********************************************************************
436 * SetupGetSourceInfoA (SETUPAPI.@)
439 BOOL WINAPI SetupGetSourceInfoA( HINF hinf, UINT source_id, UINT info,
440 PSTR buffer, DWORD buffer_size, LPDWORD required_size )
442 BOOL ret = FALSE;
443 WCHAR *bufferW = NULL;
444 DWORD required;
445 INT size;
447 TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
448 required_size);
450 if (!SetupGetSourceInfoW( hinf, source_id, info, NULL, 0, &required ))
451 return FALSE;
453 if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
454 return FALSE;
456 if (!SetupGetSourceInfoW( hinf, source_id, info, bufferW, required, NULL ))
457 goto done;
459 size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
460 if (required_size) *required_size = size;
462 if (buffer)
464 if (buffer_size >= size)
465 WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
466 else
468 SetLastError( ERROR_INSUFFICIENT_BUFFER );
469 goto done;
472 ret = TRUE;
474 done:
475 HeapFree( GetProcessHeap(), 0, bufferW );
476 return ret;
479 /***********************************************************************
480 * SetupGetSourceInfoW (SETUPAPI.@)
483 BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info,
484 PWSTR buffer, DWORD buffer_size, LPDWORD required_size )
486 INFCONTEXT ctx;
487 WCHAR source_id_str[11];
488 static const WCHAR fmt[] = {'%','d',0};
489 DWORD index;
491 TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size,
492 required_size);
494 sprintfW( source_id_str, fmt, source_id );
496 if (!SetupFindFirstLineW( hinf, source_disks_names_platform, source_id_str, &ctx ) &&
497 !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx ))
498 return FALSE;
500 switch (info)
502 case SRCINFO_PATH: index = 4; break;
503 case SRCINFO_TAGFILE: index = 2; break;
504 case SRCINFO_DESCRIPTION: index = 1; break;
505 default:
506 WARN("unknown info level: %d\n", info);
507 return FALSE;
510 if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size ))
511 return TRUE;
513 if (required_size) *required_size = 1;
514 if (buffer)
516 if (buffer_size >= 1) buffer[0] = 0;
517 else
519 SetLastError( ERROR_INSUFFICIENT_BUFFER );
520 return FALSE;
523 return TRUE;
526 /***********************************************************************
527 * SetupGetTargetPathA (SETUPAPI.@)
530 BOOL WINAPI SetupGetTargetPathA( HINF hinf, PINFCONTEXT context, PCSTR section, PSTR buffer,
531 DWORD buffer_size, PDWORD required_size )
533 BOOL ret = FALSE;
534 WCHAR *sectionW = NULL, *bufferW = NULL;
535 DWORD required;
536 INT size;
538 TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_a(section), buffer,
539 buffer_size, required_size);
541 if (section && !(sectionW = strdupAtoW( section )))
542 return FALSE;
544 if (!SetupGetTargetPathW( hinf, context, sectionW, NULL, 0, &required ))
545 goto done;
547 if (!(bufferW = HeapAlloc( GetProcessHeap(), 0, required * sizeof(WCHAR) )))
548 goto done;
550 if (!SetupGetTargetPathW( hinf, context, sectionW, bufferW, required, NULL ))
551 goto done;
553 size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
554 if (required_size) *required_size = size;
556 if (buffer)
558 if (buffer_size >= size)
559 WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, buffer_size, NULL, NULL );
560 else
562 SetLastError( ERROR_INSUFFICIENT_BUFFER );
563 goto done;
566 ret = TRUE;
568 done:
569 HeapFree( GetProcessHeap(), 0, sectionW );
570 HeapFree( GetProcessHeap(), 0, bufferW );
571 return ret;
574 /***********************************************************************
575 * SetupGetTargetPathW (SETUPAPI.@)
578 BOOL WINAPI SetupGetTargetPathW( HINF hinf, PINFCONTEXT context, PCWSTR section, PWSTR buffer,
579 DWORD buffer_size, PDWORD required_size )
581 static const WCHAR destination_dirs[] =
582 {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
583 static const WCHAR default_dest_dir[] =
584 {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
586 INFCONTEXT ctx;
587 WCHAR *dir, systemdir[MAX_PATH];
588 unsigned int size;
589 BOOL ret = FALSE;
591 TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_w(section), buffer,
592 buffer_size, required_size);
594 if (context) ret = SetupFindFirstLineW( hinf, destination_dirs, NULL, context );
595 else if (section)
597 if (!(ret = SetupFindFirstLineW( hinf, destination_dirs, section, &ctx )))
598 ret = SetupFindFirstLineW( hinf, destination_dirs, default_dest_dir, &ctx );
600 if (!ret || !(dir = PARSER_get_dest_dir( context ? context : &ctx )))
602 GetSystemDirectoryW( systemdir, MAX_PATH );
603 dir = systemdir;
605 size = strlenW( dir ) + 1;
606 if (required_size) *required_size = size;
608 if (buffer)
610 if (buffer_size >= size)
611 lstrcpyW( buffer, dir );
612 else
614 SetLastError( ERROR_INSUFFICIENT_BUFFER );
615 if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir );
616 return FALSE;
619 if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir );
620 return TRUE;
623 /***********************************************************************
624 * SetupQueryInfOriginalFileInformationA (SETUPAPI.@)
626 BOOL WINAPI SetupQueryInfOriginalFileInformationA(
627 PSP_INF_INFORMATION InfInformation, UINT InfIndex,
628 PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
629 PSP_ORIGINAL_FILE_INFO_A OriginalFileInfo)
631 BOOL ret;
632 SP_ORIGINAL_FILE_INFO_W OriginalFileInfoW;
634 TRACE("(%p, %d, %p, %p)\n", InfInformation, InfIndex,
635 AlternativePlatformInfo, OriginalFileInfo);
637 if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
639 WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
640 SetLastError( ERROR_INVALID_USER_BUFFER );
641 return FALSE;
644 OriginalFileInfoW.cbSize = sizeof(OriginalFileInfoW);
645 ret = SetupQueryInfOriginalFileInformationW(InfInformation, InfIndex,
646 AlternativePlatformInfo, &OriginalFileInfoW);
647 if (ret)
649 WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalInfName, -1,
650 OriginalFileInfo->OriginalInfName, MAX_PATH, NULL, NULL);
651 WideCharToMultiByte(CP_ACP, 0, OriginalFileInfoW.OriginalCatalogName, -1,
652 OriginalFileInfo->OriginalCatalogName, MAX_PATH, NULL, NULL);
655 return ret;
658 /***********************************************************************
659 * SetupQueryInfOriginalFileInformationW (SETUPAPI.@)
661 BOOL WINAPI SetupQueryInfOriginalFileInformationW(
662 PSP_INF_INFORMATION InfInformation, UINT InfIndex,
663 PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
664 PSP_ORIGINAL_FILE_INFO_W OriginalFileInfo)
666 LPCWSTR inf_name;
667 LPCWSTR inf_path;
668 HINF hinf;
669 static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
670 static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };
672 FIXME("(%p, %d, %p, %p): semi-stub\n", InfInformation, InfIndex,
673 AlternativePlatformInfo, OriginalFileInfo);
675 if (OriginalFileInfo->cbSize != sizeof(*OriginalFileInfo))
677 WARN("incorrect OriginalFileInfo->cbSize of %d\n", OriginalFileInfo->cbSize);
678 SetLastError(ERROR_INVALID_USER_BUFFER);
679 return FALSE;
682 inf_path = (LPWSTR)InfInformation->VersionData;
684 /* FIXME: we should get OriginalCatalogName from CatalogFile line in
685 * the original inf file and cache it, but that would require building a
686 * .pnf file. */
687 hinf = SetupOpenInfFileW(inf_path, NULL, INF_STYLE_WIN4, NULL);
688 if (hinf == INVALID_HANDLE_VALUE) return FALSE;
690 if (!SetupGetLineTextW(NULL, hinf, wszVersion, wszCatalogFile,
691 OriginalFileInfo->OriginalCatalogName,
692 sizeof(OriginalFileInfo->OriginalCatalogName)/sizeof(OriginalFileInfo->OriginalCatalogName[0]),
693 NULL))
695 OriginalFileInfo->OriginalCatalogName[0] = '\0';
697 SetupCloseInfFile(hinf);
699 /* FIXME: not quite correct as we just return the same file name as
700 * destination (copied) inf file, not the source (original) inf file.
701 * to fix it properly would require building a .pnf file */
702 /* file name is stored in VersionData field of InfInformation */
703 inf_name = strrchrW(inf_path, '\\');
704 if (inf_name) inf_name++;
705 else inf_name = inf_path;
707 strcpyW(OriginalFileInfo->OriginalInfName, inf_name);
709 return TRUE;