Replace ReactOS implementation of SetupGetInfInformationW by Wine one (much more complete)

Merge from Wine (Patches by James Hawkins (<truiken@gmail.com>))
- Store the full name to the INF file in the inf_file structure
- Implement SetupGetInfInformationA 
- Implement SetupQueryInfFileInformationA/W (James Hawkins <truiken@gmail.com>)

svn path=/trunk/; revision=21580
This commit is contained in:
Hervé Poussineau 2006-04-13 12:16:50 +00:00
parent 69734f5025
commit c20e86702b
8 changed files with 328 additions and 101 deletions

View file

@ -151,7 +151,7 @@ static const WCHAR *get_csidl_dir( DWORD csidl )
}
/* retrieve the string corresponding to a dirid, or NULL if none */
const WCHAR *DIRID_get_string( HINF hinf, int dirid )
const WCHAR *DIRID_get_string( int dirid )
{
int i;
@ -161,7 +161,7 @@ const WCHAR *DIRID_get_string( HINF hinf, int dirid )
{
for (i = 0; i < nb_user_dirids; i++)
if (user_dirids[i].id == dirid) return user_dirids[i].str;
ERR("user id %d not found\n", dirid );
WARN("user id %d not found\n", dirid );
return NULL;
}
else if (dirid >= MIN_CSIDL_DIRID)
@ -174,7 +174,6 @@ const WCHAR *DIRID_get_string( HINF hinf, int dirid )
else
{
if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();
if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf );
if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );
return system_dirids[dirid];
}

View file

@ -68,7 +68,7 @@ struct inf_file
unsigned int alloc_fields;
struct field *fields;
int strings_section; /* index of [Strings] section or -1 if none */
WCHAR *src_root; /* source root directory */
WCHAR *filename; /* filename of the INF */
};
/* parser definitions */
@ -159,6 +159,15 @@ static void *grow_array( void *array, unsigned int *count, size_t elem )
}
/* get the directory of the inf file (as counted string, not null-terminated) */
static const WCHAR *get_inf_dir( struct inf_file *file, unsigned int *len )
{
const WCHAR *p = strrchrW( file->filename, '\\' );
*len = p ? (p + 1 - file->filename) : 0;
return file->filename;
}
/* find a section by name */
static int find_section( struct inf_file *file, const WCHAR *name )
{
@ -279,10 +288,12 @@ static struct field *add_field( struct inf_file *file, const WCHAR *text )
/* retrieve the string substitution for a directory id */
static const WCHAR *get_dirid_subst( int dirid, unsigned int *len )
static const WCHAR *get_dirid_subst( struct inf_file *file, int dirid, unsigned int *len )
{
extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );
const WCHAR *ret = DIRID_get_string( 0, dirid );
const WCHAR *ret;
if (dirid == DIRID_SRCPATH) return get_inf_dir( file, len );
ret = DIRID_get_string( dirid );
if (ret) *len = strlenW(ret);
return ret;
}
@ -326,7 +337,7 @@ static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, u
memcpy( dirid_str, str, *len * sizeof(WCHAR) );
dirid_str[*len] = 0;
dirid = strtolW( dirid_str, &end, 10 );
if (!*end) ret = get_dirid_subst( dirid, len );
if (!*end) ret = get_dirid_subst( file, dirid, len );
HeapFree( GetProcessHeap(), 0, dirid_str );
return ret;
}
@ -978,15 +989,34 @@ static struct inf_file *parse_file( HANDLE handle, UINT *error_line )
}
/***********************************************************************
* PARSER_get_inf_filename
*
* Retrieve the filename of an inf file.
*/
const WCHAR *PARSER_get_inf_filename( HINF hinf )
{
struct inf_file *file = hinf;
return file->filename;
}
/***********************************************************************
* PARSER_get_src_root
*
* Retrieve the source directory of an inf file.
*/
const WCHAR *PARSER_get_src_root( HINF hinf )
WCHAR *PARSER_get_src_root( HINF hinf )
{
struct inf_file *file = hinf;
return file->src_root;
unsigned int len;
const WCHAR *dir = get_inf_dir( hinf, &len );
WCHAR *ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
if (ret)
{
memcpy( ret, dir, len * sizeof(WCHAR) );
ret[len] = 0;
}
return ret;
}
@ -1001,15 +1031,15 @@ WCHAR *PARSER_get_dest_dir( INFCONTEXT *context )
const WCHAR *dir;
WCHAR *ptr, *ret;
INT dirid;
DWORD len1, len2;
unsigned int len1;
DWORD len2;
if (!SetupGetIntField( context, 1, &dirid )) return NULL;
if (!(dir = DIRID_get_string( context->Inf, dirid ))) return NULL;
len1 = strlenW(dir) + 1;
if (!(dir = get_dirid_subst( context->Inf, dirid, &len1 ))) return NULL;
if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0;
if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2) * sizeof(WCHAR) ))) return NULL;
strcpyW( ret, dir );
ptr = ret + strlenW(ret);
if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2+1) * sizeof(WCHAR) ))) return NULL;
memcpy( ret, dir, len1 * sizeof(WCHAR) );
ptr = ret + len1;
if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\';
if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0;
return ret;
@ -1164,8 +1194,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err
return (HINF)INVALID_HANDLE_VALUE;
}
TRACE( "%s -> %p\n", debugstr_w(path), file );
file->src_root = path;
if ((p = strrchrW( path, '\\' ))) p[1] = 0; /* remove file name */
file->filename = path;
if (class)
{
@ -1274,7 +1303,7 @@ void WINAPI SetupCloseInfFile( HINF hinf )
unsigned int i;
for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
HeapFree( GetProcessHeap(), 0, file->src_root );
HeapFree( GetProcessHeap(), 0, file->filename );
HeapFree( GetProcessHeap(), 0, file->sections );
HeapFree( GetProcessHeap(), 0, file->fields );
HeapFree( GetProcessHeap(), 0, file->strings );
@ -1927,65 +1956,6 @@ BOOL WINAPI SetupGetMultiSzFieldW( PINFCONTEXT context, DWORD index, PWSTR buffe
return TRUE;
}
/***********************************************************************
* SetupGetInfInformationW (SETUPAPI.@)
*/
BOOL WINAPI
SetupGetInfInformationW(
IN LPCVOID InfSpec,
IN DWORD SearchControl,
IN PSP_INF_INFORMATION ReturnBuffer,
IN DWORD ReturnBufferSize,
IN PDWORD RequiredSize)
{
HINF hInf;
DWORD requiredSize;
BOOL Ret = FALSE;
TRACE("%p %lx %p %ld %p\n", InfSpec, SearchControl, ReturnBuffer,
ReturnBufferSize, RequiredSize);
if (SearchControl != INFINFO_INF_SPEC_IS_HINF
&& SearchControl != INFINFO_INF_NAME_IS_ABSOLUTE
&& SearchControl != INFINFO_DEFAULT_SEARCH
&& SearchControl != INFINFO_REVERSE_DEFAULT_SEARCH
&& SearchControl != INFINFO_INF_PATH_LIST_SEARCH)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
hInf = (HINF)InfSpec;
else
{
/* open .inf file and put its handle to hInf */
FIXME("SearchControl 0x%lx not implemented\n", SearchControl);
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
/* FIXME: add size of [Version] section */
requiredSize = sizeof(SP_INF_INFORMATION);
if (requiredSize <= ReturnBufferSize)
{
ReturnBuffer->InfStyle = INF_STYLE_WIN4; /* FIXME */
ReturnBuffer->InfCount = 1; /* FIXME */
/* FIXME: memcpy(ReturnBuffer->VersionData, ...); */
Ret = TRUE;
}
else
SetLastError(ERROR_INSUFFICIENT_BUFFER);
if (RequiredSize)
*RequiredSize = requiredSize;
if (SearchControl != INFINFO_INF_SPEC_IS_HINF)
SetupCloseInfFile(hInf);
return Ret;
}
/***********************************************************************
* SetupGetInfFileListW (SETUPAPI.@)
*/

View file

@ -0,0 +1,271 @@
/*
* setupapi query functions
*
* Copyright 2006 James Hawkins
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "setupapi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
/* fills the PSP_INF_INFORMATION struct fill_info is TRUE
* always returns the required size of the information
*/
static BOOL fill_inf_info(HINF inf, PSP_INF_INFORMATION buffer, DWORD size, DWORD *required)
{
LPCWSTR filename = PARSER_get_inf_filename(inf);
DWORD total_size = FIELD_OFFSET(SP_INF_INFORMATION, VersionData)
+ (lstrlenW(filename) + 1) * sizeof(WCHAR);
if (required) *required = total_size;
/* FIXME: we need to parse the INF file to find the correct version info */
if (buffer)
{
if (size < total_size)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
buffer->InfStyle = INF_STYLE_WIN4;
buffer->InfCount = 1;
/* put the filename in buffer->VersionData */
lstrcpyW((LPWSTR)&buffer->VersionData[0], filename);
}
return TRUE;
}
static HINF search_for_inf(LPCVOID InfSpec, DWORD SearchControl)
{
HINF hInf = INVALID_HANDLE_VALUE;
WCHAR inf_path[MAX_PATH];
static const WCHAR infW[] = {'\\','i','n','f','\\',0};
static const WCHAR system32W[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
if (SearchControl == INFINFO_REVERSE_DEFAULT_SEARCH)
{
GetWindowsDirectoryW(inf_path, MAX_PATH);
lstrcatW(inf_path, system32W);
lstrcatW(inf_path, InfSpec);
hInf = SetupOpenInfFileW(inf_path, NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
if (hInf != INVALID_HANDLE_VALUE)
return hInf;
GetWindowsDirectoryW(inf_path, MAX_PATH);
lstrcpyW(inf_path, infW);
lstrcatW(inf_path, InfSpec);
return SetupOpenInfFileW(inf_path, NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
}
return INVALID_HANDLE_VALUE;
}
/***********************************************************************
* SetupGetInfInformationA (SETUPAPI.@)
*
*/
BOOL WINAPI SetupGetInfInformationA(LPCVOID InfSpec, DWORD SearchControl,
PSP_INF_INFORMATION ReturnBuffer,
DWORD ReturnBufferSize, PDWORD RequiredSize)
{
LPWSTR inf = (LPWSTR)InfSpec;
DWORD len;
BOOL ret;
if (InfSpec && SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
{
len = lstrlenA(InfSpec) + 1;
inf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, InfSpec, -1, inf, len);
}
ret = SetupGetInfInformationW(inf, SearchControl, ReturnBuffer,
ReturnBufferSize, RequiredSize);
if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
HeapFree(GetProcessHeap(), 0, inf);
return ret;
}
/***********************************************************************
* SetupGetInfInformationW (SETUPAPI.@)
*
* BUGS
* Only handles the case when InfSpec is an INF handle.
*/
BOOL WINAPI SetupGetInfInformationW(LPCVOID InfSpec, DWORD SearchControl,
PSP_INF_INFORMATION ReturnBuffer,
DWORD ReturnBufferSize, PDWORD RequiredSize)
{
HINF inf;
BOOL ret;
TRACE("(%p, %ld, %p, %ld, %p)\n", InfSpec, SearchControl, ReturnBuffer,
ReturnBufferSize, RequiredSize);
if (!InfSpec)
{
if (SearchControl == INFINFO_INF_SPEC_IS_HINF)
SetLastError(ERROR_INVALID_HANDLE);
else
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!ReturnBuffer && ReturnBufferSize)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (SearchControl)
{
case INFINFO_INF_SPEC_IS_HINF:
inf = (HINF)InfSpec;
break;
case INFINFO_INF_NAME_IS_ABSOLUTE:
case INFINFO_DEFAULT_SEARCH:
inf = SetupOpenInfFileW(InfSpec, NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
break;
case INFINFO_REVERSE_DEFAULT_SEARCH:
inf = search_for_inf(InfSpec, SearchControl);
break;
case INFINFO_INF_PATH_LIST_SEARCH:
FIXME("Unhandled search control: %ld\n", SearchControl);
if (RequiredSize)
*RequiredSize = 0;
return FALSE;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (inf == INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
ret = fill_inf_info(inf, ReturnBuffer, ReturnBufferSize, RequiredSize);
if (SearchControl >= INFINFO_INF_NAME_IS_ABSOLUTE)
SetupCloseInfFile(inf);
return ret;
}
/***********************************************************************
* SetupQueryInfFileInformationA (SETUPAPI.@)
*/
BOOL WINAPI SetupQueryInfFileInformationA(PSP_INF_INFORMATION InfInformation,
UINT InfIndex, PSTR ReturnBuffer,
DWORD ReturnBufferSize, PDWORD RequiredSize)
{
LPWSTR filenameW;
DWORD size;
BOOL ret;
ret = SetupQueryInfFileInformationW(InfInformation, InfIndex, NULL, 0, &size);
if (!ret)
return FALSE;
filenameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
ret = SetupQueryInfFileInformationW(InfInformation, InfIndex,
filenameW, size, &size);
if (!ret)
{
HeapFree(GetProcessHeap(), 0, filenameW);
return FALSE;
}
if (RequiredSize)
*RequiredSize = size;
if (!ReturnBuffer)
{
if (ReturnBufferSize)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
if (size > ReturnBufferSize)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
WideCharToMultiByte(CP_ACP, 0, filenameW, -1, ReturnBuffer, size, NULL, NULL);
HeapFree(GetProcessHeap(), 0, filenameW);
return ret;
}
/***********************************************************************
* SetupQueryInfFileInformationW (SETUPAPI.@)
*/
BOOL WINAPI SetupQueryInfFileInformationW(PSP_INF_INFORMATION InfInformation,
UINT InfIndex, PWSTR ReturnBuffer,
DWORD ReturnBufferSize, PDWORD RequiredSize)
{
DWORD len;
LPWSTR ptr;
TRACE("(%p, %u, %p, %ld, %p) Stub!\n", InfInformation, InfIndex,
ReturnBuffer, ReturnBufferSize, RequiredSize);
if (!InfInformation)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (InfIndex != 0)
FIXME("Appended INF files are not handled\n");
ptr = (LPWSTR)&InfInformation->VersionData[0];
len = lstrlenW(ptr);
if (RequiredSize)
*RequiredSize = len + 1;
if (!ReturnBuffer)
return TRUE;
if (ReturnBufferSize < len)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
lstrcpyW(ReturnBuffer, ptr);
return TRUE;
}

View file

@ -282,12 +282,9 @@ static void get_src_file_info( HINF hinf, struct file_op *op )
/* find the SourceDisksFiles entry */
if (!SetupFindFirstLineW( hinf, SourceDisksFiles, op->src_file, &file_ctx ))
{
const WCHAR *dir;
if ((op->style & (SP_COPY_SOURCE_ABSOLUTE|SP_COPY_SOURCEPATH_ABSOLUTE))) return;
/* no specific info, use .inf file source directory */
if (!op->src_root && (dir = DIRID_get_string( hinf, DIRID_SRCPATH )))
op->src_root = strdupW( dir );
if (!op->src_root) op->src_root = PARSER_get_src_root( hinf );
return;
}
if (!SetupGetIntField( &file_ctx, 1, &diskid )) return;
@ -337,7 +334,7 @@ static void get_src_file_info( HINF hinf, struct file_op *op )
if (!SetupGetStringFieldW( &disk_ctx, 4, ptr, len2, NULL )) *ptr = 0;
}
}
if (!op->src_root) op->src_root = strdupW( PARSER_get_src_root(hinf) );
if (!op->src_root) op->src_root = PARSER_get_src_root(hinf);
}

View file

@ -1,4 +1,4 @@
<module name="setupapi" type="win32dll" baseaddress="${BASEADDRESS_SETUPAPI}" installbase="system32" installname="setupapi.dll" allowwarnings="true">
<module name="setupapi" type="win32dll" baseaddress="${BASEADDRESS_SETUPAPI}" installbase="system32" installname="setupapi.dll">
<importlibrary definition="setupapi.spec.def" />
<include base="setupapi">.</include>
<include base="ReactOS">include/reactos/wine</include>
@ -29,6 +29,7 @@
<file>install.c</file>
<file>misc.c</file>
<file>parser.c</file>
<file>query.c</file>
<file>queue.c</file>
<file>setupcab.c</file>
<file>stringtable.c</file>

View file

@ -462,8 +462,8 @@
@ stub SetupQueryDrivesInDiskSpaceListW
@ stub SetupQueryFileLogA
@ stub SetupQueryFileLogW
@ stub SetupQueryInfFileInformationA
@ stub SetupQueryInfFileInformationW
@ stdcall SetupQueryInfFileInformationA(ptr long str long ptr)
@ stdcall SetupQueryInfFileInformationW(ptr long wstr long ptr)
@ stub SetupQueryInfOriginalFileInformationA
@ stub SetupQueryInfOriginalFileInformationW
@ stub SetupQueryInfVersionInformationA

View file

@ -189,12 +189,13 @@ extern HINSTANCE hInstance;
/* string substitutions */
struct inf_file;
extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );
extern const WCHAR *DIRID_get_string( int dirid );
extern const WCHAR *PARSER_get_inf_filename( HINF hinf );
extern unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text,
char *buffer, unsigned int size );
extern unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text,
WCHAR *buffer, unsigned int size );
extern const WCHAR *PARSER_get_src_root( HINF hinf );
extern WCHAR *PARSER_get_src_root( HINF hinf );
extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context );
/* support for Ascii queue callback functions */

View file

@ -64,18 +64,6 @@ BOOL WINAPI SetupCopyOEMInfW(PCWSTR sourceinffile, PCWSTR sourcemedialoc,
return TRUE;
}
/***********************************************************************
* SetupGetInfInformationA (SETUPAPI.@)
*/
BOOL WINAPI SetupGetInfInformationA( LPCVOID InfSpec, DWORD SearchControl,
PSP_INF_INFORMATION ReturnBuffer,
DWORD ReturnBufferSize, PDWORD RequiredSize)
{
FIXME("(%p, %ld, %p, %ld, %p) Stub!\n",
InfSpec, SearchControl, ReturnBuffer, ReturnBufferSize, RequiredSize );
return TRUE;
}
/***********************************************************************
* SetupInitializeFileLogW(SETUPAPI.@)
*/