diff --git a/dlls/setupapi/install.c b/dlls/setupapi/install.c index 939f2ac6b93..6322fa1678f 100644 --- a/dlls/setupapi/install.c +++ b/dlls/setupapi/install.c @@ -69,9 +69,12 @@ static const WCHAR Ini2Reg[] = {'I','n','i','2','R','e','g',0}; static const WCHAR LogConf[] = {'L','o','g','C','o','n','f',0}; static const WCHAR AddReg[] = {'A','d','d','R','e','g',0}; static const WCHAR DelReg[] = {'D','e','l','R','e','g',0}; +static const WCHAR BitReg[] = {'B','i','t','R','e','g',0}; static const WCHAR UpdateInis[] = {'U','p','d','a','t','e','I','n','i','s',0}; +static const WCHAR CopyINF[] = {'C','o','p','y','I','N','F',0}; static const WCHAR UpdateIniFields[] = {'U','p','d','a','t','e','I','n','i','F','i','e','l','d','s',0}; static const WCHAR RegisterDlls[] = {'R','e','g','i','s','t','e','r','D','l','l','s',0}; +static const WCHAR ProfileItems[] = {'P','r','o','f','i','l','e','I','t','e','m','s',0}; /*********************************************************************** @@ -576,6 +579,11 @@ static BOOL register_dlls_callback( HINF hinf, PCWSTR field, void *arg ) return ret; } +/*********************************************************************** + * update_ini_callback + * + * Called once for each UpdateInis entry in a given section. + */ static BOOL update_ini_callback( HINF hinf, PCWSTR field, void *arg ) { INFCONTEXT context; @@ -643,6 +651,24 @@ static BOOL logconf_callback( HINF hinf, PCWSTR field, void *arg ) return TRUE; } +static BOOL bitreg_callback( HINF hinf, PCWSTR field, void *arg ) +{ + FIXME( "should do bitreg %s\n", debugstr_w(field) ); + return TRUE; +} + +static BOOL profile_items_callback( HINF hinf, PCWSTR field, void *arg ) +{ + FIXME( "should do profile items %s\n", debugstr_w(field) ); + return TRUE; +} + +static BOOL copy_inf_callback( HINF hinf, PCWSTR field, void *arg ) +{ + FIXME( "should do copy inf %s\n", debugstr_w(field) ); + return TRUE; +} + /*********************************************************************** * iterate_section_fields @@ -804,13 +830,11 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, if (!iterate_section_fields( hinf, section, Ini2Reg, ini2reg_callback, NULL )) return FALSE; } - if (flags & SPINST_LOGCONFIG) { if (!iterate_section_fields( hinf, section, LogConf, logconf_callback, NULL )) return FALSE; } - if (flags & SPINST_REGSVR) { struct register_dll_info info; @@ -826,7 +850,6 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, if (!iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info )) return FALSE; } - if (flags & SPINST_UNREGSVR) { struct register_dll_info info; @@ -842,7 +865,6 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, if (!iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info )) return FALSE; } - if (flags & SPINST_REGISTRY) { struct registry_callback_info info; @@ -855,8 +877,78 @@ BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, if (!iterate_section_fields( hinf, section, AddReg, registry_callback, &info )) return FALSE; } + if (flags & SPINST_BITREG) + { + if (!iterate_section_fields( hinf, section, BitReg, bitreg_callback, NULL )) + return FALSE; + } + if (flags & SPINST_PROFILEITEMS) + { + if (!iterate_section_fields( hinf, section, ProfileItems, profile_items_callback, NULL )) + return FALSE; + } + if (flags & SPINST_COPYINF) + { + if (!iterate_section_fields( hinf, section, CopyINF, copy_inf_callback, NULL )) + return FALSE; + } - if (flags & (SPINST_BITREG|SPINST_PROFILEITEMS|SPINST_COPYINF)) - FIXME( "unsupported flags %x\n", flags ); return TRUE; } + + +/*********************************************************************** + * InstallHinfSectionW (SETUPAPI.@) + * + * NOTE: 'cmdline' is
from + * RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection
+ */ +void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show ) +{ + WCHAR *p, *path, section[MAX_PATH]; + void *callback_context; + UINT mode; + HINF hinf; + + TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline)); + + lstrcpynW( section, cmdline, sizeof(section)/sizeof(WCHAR) ); + + if (!(p = strchrW( section, ' ' ))) return; + *p++ = 0; + while (*p == ' ') p++; + mode = atoiW( p ); + + if (!(p = strchrW( p, ' ' ))) return; + path = p + 1; + while (*path == ' ') path++; + + hinf = SetupOpenInfFileW( path, NULL, INF_STYLE_WIN4, NULL ); + if (hinf == INVALID_HANDLE_VALUE) return; + + callback_context = SetupInitDefaultQueueCallback( hwnd ); + SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER, + SetupDefaultQueueCallbackW, callback_context, + NULL, NULL ); + SetupTermDefaultQueueCallback( callback_context ); + SetupCloseInfFile( hinf ); + + /* FIXME: should check the mode and maybe reboot */ + /* there isn't much point in doing that since we */ + /* don't yet handle deferred file copies anyway. */ +} + + +/*********************************************************************** + * InstallHinfSectionA (SETUPAPI.@) + */ +void WINAPI InstallHinfSectionA( HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show ) +{ + UNICODE_STRING cmdlineW; + + if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline )) + { + InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show ); + RtlFreeUnicodeString( &cmdlineW ); + } +} diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index f01d3460715..8ff9337cd2e 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -27,9 +27,9 @@ @ stub GetSetFileTimestamp @ stub GetVersionInfoFromImage @ stub InfIsFromOemLocation -@ stdcall InstallHinfSection(long long str long) -@ stub InstallHinfSectionA -@ stub InstallHinfSectionW +@ stdcall InstallHinfSection(long long str long) InstallHinfSectionA +@ stdcall InstallHinfSectionA(long long str long) +@ stdcall InstallHinfSectionW(long long wstr long) @ stub InstallStop @ stub IsUserAdmin @ stub LookUpStringInTable diff --git a/dlls/setupapi/setupx_main.c b/dlls/setupapi/setupx_main.c index 4f5b9525c3b..ca3ac711792 100644 --- a/dlls/setupapi/setupx_main.c +++ b/dlls/setupapi/setupx_main.c @@ -76,6 +76,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(setupapi); +#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16)) + /*********************************************************************** * SURegOpenKey (SETUPX.47) */ @@ -98,74 +100,6 @@ DWORD WINAPI SURegQueryValueEx( HKEY hkey, LPSTR lpszValueName, lpbData, lpcbData ); } -/* - * Returns pointer to a string list with the first entry being number - * of strings. - * - * Hmm. Should this be InitSubstrData(), GetFirstSubstr() and GetNextSubstr() - * instead? - */ -static LPSTR *SETUPX_GetSubStrings(LPSTR start, char delimiter) -{ - LPSTR p, q; - LPSTR *res = NULL; - DWORD count = 0; - int len; - - p = start; - - while (1) - { - /* find beginning of real substring */ - while ( (*p == ' ') || (*p == '\t') || (*p == '"') ) p++; - - /* find end of real substring */ - q = p; - while ( (*q) - && (*q != ' ') && (*q != '\t') && (*q != '"') - && (*q != ';') && (*q != delimiter) ) q++; - if (q == p) - break; - len = (int)q - (int)p; - - /* alloc entry for new substring in steps of 32 units and copy over */ - if (count % 32 == 0) - { /* 1 for count field + current count + 32 */ - if (res) - res = HeapReAlloc(GetProcessHeap(), 0, res, (1+count+32)*sizeof(LPSTR)); - else - res = HeapAlloc(GetProcessHeap(), 0, (1+count+32)*sizeof(LPSTR)); - } - *(res+1+count) = HeapAlloc(GetProcessHeap(), 0, len+1); - strncpy(*(res+1+count), p, len); - (*(res+1+count))[len] = '\0'; - count++; - - /* we are still within last substring (before delimiter), - * so get out of it */ - while ((*q) && (*q != ';') && (*q != delimiter)) q++; - if ((!*q) || (*q == ';')) - break; - p = q+1; - } - - /* put number of entries at beginning of list */ - *(DWORD *)res = count; - return res; -} - -static void SETUPX_FreeSubStrings(LPSTR *substr) -{ - DWORD count = *(DWORD *)substr; - LPSTR *pStrings = substr+1; - DWORD n; - - for (n=0; n < count; n++) - HeapFree(GetProcessHeap(), 0, *pStrings++); - - HeapFree(GetProcessHeap(), 0, substr); -} - /*********************************************************************** * InstallHinfSection (SETUPX.527) @@ -180,63 +114,8 @@ static void SETUPX_FreeSubStrings(LPSTR *substr) */ RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCmdLine, INT16 nCmdShow) { - LPSTR *pSub; - DWORD count; - HINF16 hInf = 0; - RETERR16 res = OK, tmp; - WORD wFlags; - BOOL reboot = FALSE; - - TRACE("(%04x, %04x, %s, %d);\n", hwnd, hinst, lpszCmdLine, nCmdShow); - - pSub = SETUPX_GetSubStrings((LPSTR)lpszCmdLine, ' '); - - count = *(DWORD *)pSub; - if (count < 2) /* invalid number of arguments ? */ - goto end; - if (IpOpen16(*(pSub+count), &hInf) != OK) - { - res = ERROR_FILE_NOT_FOUND; /* yes, correct */ - goto end; - } - if (VcpOpen16(NULL, 0)) - goto end; - if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK) - goto end; - wFlags = atoi(*(pSub+count-1)) & ~128; - switch (wFlags) - { - case HOW_ALWAYS_SILENT_REBOOT: - case HOW_SILENT_REBOOT: - reboot = TRUE; - break; - case HOW_ALWAYS_PROMPT_REBOOT: - case HOW_PROMPT_REBOOT: - if (MessageBoxA(HWND_32(hwnd), "You must restart Wine before the new settings will take effect.\n\nDo you want to exit Wine now ?", "Systems Settings Change", MB_YESNO|MB_ICONQUESTION) == IDYES) - reboot = TRUE; - break; - default: - ERR("invalid flags %d !\n", wFlags); - goto end; - } - - res = OK; -end: - tmp = VcpClose16(VCPFL_ALL, NULL); - if (tmp != OK) - res = tmp; - tmp = IpClose16(hInf); - if (tmp != OK) - res = tmp; - SETUPX_FreeSubStrings(pSub); - if (reboot) - { - /* FIXME: we should have a means of terminating all wine + wineserver */ - MESSAGE("Program or user told me to restart. Exiting Wine...\n"); - ExitProcess(1); - } - - return res; + InstallHinfSectionA( HWND_32(hwnd), HINSTANCE_32(hinst), lpszCmdLine, nCmdShow ); + return OK; } typedef struct diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 7aef31c40b7..f9d8beca4f4 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -188,14 +188,6 @@ BOOL WINAPI SetupCopyOEMInfA(PCSTR sourceinffile, PCSTR sourcemedialoc, return FALSE; } -/*********************************************************************** - * InstallHinfSection (SETUPAPI.@) - */ -void WINAPI InstallHinfSection(HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show) -{ - FIXME("stub, hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_a(cmdline)); -} - /*********************************************************************** * SetupGetInfInformationA (SETUPAPI.@) */ diff --git a/include/setupapi.h b/include/setupapi.h index d9c33fef3a8..fe92dd0d504 100644 --- a/include/setupapi.h +++ b/include/setupapi.h @@ -599,6 +599,9 @@ DECL_WINELIB_SETUPAPI_TYPE_AW(PFILEPATHS) #define SPDRP_INSTALL_STATE 0x00000022 #define SPDRP_MAXIMUM_PROPERTY 0x00000023 +void WINAPI InstallHinfSectionA( HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show ); +void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show ); +#define InstallHinfSection WINELIB_NAME_AW(InstallHinfSection) HINF WINAPI SetupOpenInfFileA( PCSTR name, PCSTR pszclass, DWORD style, UINT *error ); HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR pszclass, DWORD style, UINT *error ); #define SetupOpenInfFile WINELIB_NAME_AW(SetupOpenInfFile)