diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c index 7605bc1673b..da20e6cc636 100644 --- a/dlls/setupapi/queue.c +++ b/dlls/setupapi/queue.c @@ -1062,6 +1062,113 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style, return rc; } +/*********************************************************************** + * SetupInstallFileA (SETUPAPI.@) + */ +BOOL WINAPI SetupInstallFileA( HINF hinf, PINFCONTEXT inf_context, PCSTR source, PCSTR root, + PCSTR dest, DWORD style, PSP_FILE_CALLBACK_A handler, PVOID context ) +{ + BOOL ret = FALSE; + struct callback_WtoA_context ctx; + UNICODE_STRING sourceW, rootW, destW; + + TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_a(source), debugstr_a(root), + debugstr_a(dest), style, handler, context); + + sourceW.Buffer = rootW.Buffer = destW.Buffer = NULL; + if (source && !RtlCreateUnicodeStringFromAsciiz( &sourceW, source )) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + if (root && !RtlCreateUnicodeStringFromAsciiz( &rootW, root )) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + goto exit; + } + if (dest && !RtlCreateUnicodeStringFromAsciiz( &destW, dest )) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + goto exit; + } + + ctx.orig_context = context; + ctx.orig_handler = handler; + + ret = SetupInstallFileW( hinf, inf_context, sourceW.Buffer, rootW.Buffer, destW.Buffer, style, QUEUE_callback_WtoA, &ctx ); + +exit: + RtlFreeUnicodeString( &sourceW ); + RtlFreeUnicodeString( &rootW ); + RtlFreeUnicodeString( &destW ); + return ret; +} + +/*********************************************************************** + * SetupInstallFileW (SETUPAPI.@) + */ +BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source, PCWSTR root, + PCWSTR dest, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context ) +{ + static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0}; + + BOOL ret, absolute = (root && *root && !(style & SP_COPY_SOURCE_ABSOLUTE)); + WCHAR *buffer, *p, *inf_source = NULL; + unsigned int len; + + TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_w(source), debugstr_w(root), + debugstr_w(dest), style, handler, context); + + if (hinf) + { + INFCONTEXT ctx; + + if (!inf_context) + { + inf_context = &ctx; + if (!SetupFindFirstLineW( hinf, CopyFiles, NULL, inf_context )) return FALSE; + } + if (!SetupGetStringFieldW( inf_context, 1, NULL, 0, &len )) return FALSE; + if (!(inf_source = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + if (!SetupGetStringFieldW( inf_context, 1, inf_source, len, NULL )) return FALSE; + source = inf_source; + } + else if (!source) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + len = strlenW( source ) + 1; + if (absolute) len += strlenW( root ) + 1; + + if (!(p = buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + { + HeapFree( GetProcessHeap(), 0, inf_source ); + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + + if (absolute) + { + strcpyW( buffer, root ); + p += strlenW( buffer ); + if (p[-1] != '\\') *p++ = '\\'; + } + while (*source == '\\') source++; + strcpyW( p, source ); + + ret = do_file_copyW( buffer, dest, style, handler, context ); + + HeapFree( GetProcessHeap(), 0, inf_source ); + HeapFree( GetProcessHeap(), 0, buffer ); + return ret; +} + /*********************************************************************** * SetupCommitFileQueueW (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 5f31721b0e3..ca37474a4cb 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -434,10 +434,10 @@ @ stdcall SetupInitDefaultQueueCallbackEx(long long long long ptr) @ stdcall SetupInitializeFileLogA (str long) @ stdcall SetupInitializeFileLogW (wstr long) -@ stub SetupInstallFileA +@ stdcall SetupInstallFileA(ptr ptr str str str long ptr ptr) @ stub SetupInstallFileExA @ stub SetupInstallFileExW -@ stub SetupInstallFileW +@ stdcall SetupInstallFileW(ptr ptr wstr wstr wstr long ptr ptr) @ stdcall SetupInstallFilesFromInfSectionA(long long long str str long) @ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long) @ stdcall SetupInstallFromInfSectionA(long long str long long str long ptr ptr long ptr)