Setupapi - InstallHInfSection
Steven Edwards
steven_ed4153 at yahoo.com
Wed Feb 25 15:17:07 CST 2004
Hello,
Here is the ReactOS patch for setupapi InstallHInfSection with cleanups
for WINE. I didnt know if we should duplicate the trivial SetupX
Functions or share them for setupapi and setupx so I told Aleksey I
would send you patches with it either way. Take your pick.
Thanks
Steven
Changelog:
Aleksey Bragin <aleksey at studiocerebral.com>
Implement most of InstallHInfSection
__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools
-------------- next part --------------
Changelog:
Aleksey Bragin <aleksey at studiocerebral.com>
Implement most of InstallHInfSection
Index: setupapi/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/setupapi/Makefile.in,v
retrieving revision 1.24
diff -u -r1.24 Makefile.in
--- setupapi/Makefile.in 21 Oct 2003 23:45:43 -0000 1.24
+++ setupapi/Makefile.in 25 Feb 2004 20:56:07 -0000
@@ -17,6 +17,7 @@
parser.c \
queue.c \
setupcab.c \
+ setupapi_main.c \
stubs.c
C_SRCS16 = \
Index: setupapi/stubs.c
===================================================================
RCS file: /home/wine/wine/dlls/setupapi/stubs.c,v
retrieving revision 1.18
diff -u -r1.18 stubs.c
--- setupapi/stubs.c 17 Feb 2004 22:48:25 -0000 1.18
+++ setupapi/stubs.c 25 Feb 2004 20:56:08 -0000
@@ -189,14 +189,6 @@
}
/***********************************************************************
- * 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.@)
*/
BOOL WINAPI SetupGetInfInformationA( LPCVOID InfSpec, DWORD SearchControl,
--- /dev/null Wed Feb 25 15:48:47 2004
+++ setupapi_main.c Wed Feb 25 15:46:14 2004
@@ -0,0 +1,376 @@
+/*
+ * SETUPAPI library functions
+ * 32-bit version of setupx_main.c
+ *
+ * Copyright 2004 Aleksey Bragin (ReactOS Project)
+ *
+ * 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 "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winerror.h"
+#include "wine/winuser16.h"
+#include "wownt32.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "setupapi.h"
+#include "setupx16.h"
+#include "setupapi_private.h"
+#include "winerror.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+
+/*
+ * 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 (SETUPAPI.@)
+ *
+ * hwnd = parent window
+ * handle = instance of SETUPAPI.DLL
+ * lpszCmdLine = e.g. "DefaultInstall 132 C:\MYINSTALL\MYDEV.INF"
+ * Here "DefaultInstall" is the .inf file section to be installed (optional).
+ * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h).
+ *
+ * nCmdShow = nCmdShow of CreateProcess
+ */
+
+void WINAPI InstallHinfSection(HWND hwnd, HINSTANCE handle, LPCSTR lpszCmdLine, INT nCmdShow)
+{
+ LPSTR *pSub;
+ DWORD count;
+ HINF hInf = 0;
+ WORD wFlags;
+ BOOL reboot = FALSE;
+ BOOL err;
+ HSPFILEQ fQueue;
+ PVOID cbContext;
+
+ TRACE("(%04x, %04x, %s, %d);\n", hwnd, handle, lpszCmdLine, nCmdShow);
+
+ pSub = SETUPX_GetSubStrings((LPSTR)lpszCmdLine, ' ');
+ count = *(DWORD *)pSub;
+
+ if (count < 2) /* invalid number of arguments ? */
+ {
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ hInf = SetupOpenInfFileA(*(pSub+count), NULL, INF_STYLE_WIN4, NULL);
+ if (hInf == (HINF)INVALID_HANDLE_VALUE)
+ {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ /* Deal with registry settings */
+ err = SetupInstallFromInfSectionA(hwnd, hInf, (PCSTR)(*(pSub+1)), SPINST_ALL ^ SPINST_FILES/*flags*/,
+ NULL/*HKEY key_root*/, NULL/*PCWSTR src_root*/, 0/*UINT copy_flags*/,
+ NULL/*PSP_FILE_CALLBACK_W callback*/, NULL/*PVOID context*/,
+ NULL/*HDEVINFO devinfo*/, NULL/*PSP_DEVINFO_DATA devinfo_data*/);
+
+ if (err)
+ {
+ /* TODO: Show some message box saying installing from INF section has failed */
+ /* FIXME: Use strings from resources, and do it the way Windows does */
+ MessageBoxA(hwnd, "InstallFromHinfSection", "Installing registry settings from an INF section failed", MB_OK);
+
+ /* release alloced memory */
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ /* Deal with files now */
+ fQueue = SetupOpenFileQueue();
+
+ if (fQueue == INVALID_HANDLE_VALUE)
+ {
+ /* TODO: Show some message box saying creating a file queue has failed */
+ MessageBoxA(hwnd, "InstallFromHinfSection", "File queue opening failed", MB_OK);
+
+ /* release alloced memory */
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ cbContext = SetupInitDefaultQueueCallback(hwnd);
+
+ /* Fullfill the file queue */
+ /* FIXME: Is the flag (SP_COPY_NEWER) right for this call? */
+ SetupInstallFilesFromInfSectionA(hInf, /*HINF hlayout*/NULL, fQueue,
+ (PCSTR)(*(pSub+1)), /*PCSTR src_root*/NULL, SP_COPY_NEWER);
+
+ err = SetupCommitFileQueueA(hwnd, fQueue, SetupDefaultQueueCallbackA, cbContext);
+
+
+ /* Release all alloced handles and memory */
+ SetupCloseFileQueue(fQueue);
+ SetupTermDefaultQueueCallback(cbContext);
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+
+ /* Deal with flags now */
+ 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:
+ /* FIXME: What is the SetupPromptReboot() function is for? */
+ /* Anyway it isn't implemented */
+ if (MessageBoxA(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);
+ return;
+ }
+
+ if (reboot)
+ {
+ ExitWindowsEx(EWX_REBOOT, 0);
+ }
+}
+
+typedef struct
+{
+ LPCSTR RegValName;
+ LPCSTR StdString; /* fallback string; sub dir of windows directory */
+} LDID_DATA;
+
+static const LDID_DATA LDID_Data[34] =
+{
+ { /* 0 (LDID_NULL) -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */
+ "SourcePath", /* hmm, does SETUPX have to care about updating it ?? */
+ NULL
+ },
+ { /* 2 (LDID_SETUPTEMP) = setup temp dir */
+ "SetupTempDir",
+ NULL
+ },
+ { /* 3 (LDID_UNINSTALL) = uninstall backup dir */
+ "UninstallDir",
+ NULL
+ },
+ { /* 4 (LDID_BACKUP) = backup dir */
+ "BackupDir",
+ NULL
+ },
+ { /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */
+ "SetupScratchDir",
+ NULL
+ },
+ { /* 6 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 7 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 8 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 9 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 10 (LDID_WIN) = windows dir */
+ "WinDir",
+ ""
+ },
+ { /* 11 (LDID_SYS) = system dir */
+ "SysDir",
+ NULL /* call GetSystemDirectory() instead */
+ },
+ { /* 12 (LDID_IOS) = IOSubSys dir */
+ NULL, /* FIXME: registry string ? */
+ "SYSTEM\\IOSUBSYS"
+ },
+ { /* 13 (LDID_CMD) = COMMAND dir */
+ NULL, /* FIXME: registry string ? */
+ "COMMAND"
+ },
+ { /* 14 (LDID_CPL) = control panel dir */
+ NULL,
+ ""
+ },
+ { /* 15 (LDID_PRINT) = windows printer dir */
+ NULL,
+ "SYSTEM" /* correct ?? */
+ },
+ { /* 16 (LDID_MAIL) = destination mail dir */
+ NULL,
+ ""
+ },
+ { /* 17 (LDID_INF) = INF dir */
+ "SetupScratchDir", /* correct ? */
+ "INF"
+ },
+ { /* 18 (LDID_HELP) = HELP dir */
+ NULL, /* ??? */
+ "HELP"
+ },
+ { /* 19 (LDID_WINADMIN) = Admin dir */
+ "WinAdminDir",
+ ""
+ },
+ { /* 20 (LDID_FONTS) = Fonts dir */
+ NULL, /* ??? */
+ "FONTS"
+ },
+ { /* 21 (LDID_VIEWERS) = Viewers */
+ NULL, /* ??? */
+ "SYSTEM\\VIEWERS"
+ },
+ { /* 22 (LDID_VMM32) = VMM32 dir */
+ NULL, /* ??? */
+ "SYSTEM\\VMM32"
+ },
+ { /* 23 (LDID_COLOR) = ICM dir */
+ "ICMPath",
+ "SYSTEM\\COLOR"
+ },
+ { /* 24 (LDID_APPS) = root of boot drive ? */
+ "AppsDir",
+ "C:\\"
+ },
+ { /* 25 (LDID_SHARED) = shared dir */
+ "SharedDir",
+ ""
+ },
+ { /* 26 (LDID_WINBOOT) = Windows boot dir */
+ "WinBootDir",
+ ""
+ },
+ { /* 27 (LDID_MACHINE) = machine specific files */
+ "MachineDir",
+ NULL
+ },
+ { /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */
+ "HostWinBootDir",
+ NULL
+ },
+ { /* 29 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 30 (LDID_BOOT) = Root of boot drive */
+ "BootDir",
+ NULL
+ },
+ { /* 31 (LDID_BOOT_HOST) = Root of boot drive host */
+ "BootHost",
+ NULL
+ },
+ { /* 32 (LDID_OLD_WINBOOT) = subdir of root */
+ "OldWinBootDir",
+ NULL
+ },
+ { /* 33 (LDID_OLD_WIN) = old win dir */
+ "OldWinDir",
+ NULL
+ }
+ /* the rest (34-38) isn't too interesting, so I'll forget about it */
+};
-------------- next part --------------
Changelog:
Aleksey Bragin <aleksey at studiocerebral.com>
Implement most of InstallHInfSection
Index: setupapi/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/setupapi/Makefile.in,v
retrieving revision 1.24
diff -u -r1.24 Makefile.in
--- setupapi/Makefile.in 21 Oct 2003 23:45:43 -0000 1.24
+++ setupapi/Makefile.in 25 Feb 2004 21:09:44 -0000
@@ -17,6 +17,7 @@
parser.c \
queue.c \
setupcab.c \
+ setupapi_main.c \
stubs.c
C_SRCS16 = \
Index: setupapi/setupx_main.c
===================================================================
RCS file: /home/wine/wine/dlls/setupapi/setupx_main.c,v
retrieving revision 1.28
diff -u -r1.28 setupx_main.c
--- setupapi/setupx_main.c 14 Oct 2003 05:24:20 -0000 1.28
+++ setupapi/setupx_main.c 25 Feb 2004 21:09:45 -0000
@@ -76,6 +76,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+void SETUPX_FreeSubStrings(LPSTR *substr);
+LPSTR *SETUPX_GetSubStrings(LPSTR start, char delimiter);
+
/***********************************************************************
* SURegOpenKey (SETUPX.47)
*/
@@ -96,74 +99,6 @@
lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
return RegQueryValueExA( hkey, lpszValueName, lpdwReserved, lpdwType,
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);
}
Index: setupapi/stubs.c
===================================================================
RCS file: /home/wine/wine/dlls/setupapi/stubs.c,v
retrieving revision 1.18
diff -u -r1.18 stubs.c
--- setupapi/stubs.c 17 Feb 2004 22:48:25 -0000 1.18
+++ setupapi/stubs.c 25 Feb 2004 21:09:45 -0000
@@ -189,14 +189,6 @@
}
/***********************************************************************
- * 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.@)
*/
BOOL WINAPI SetupGetInfInformationA( LPCVOID InfSpec, DWORD SearchControl,
--- /dev/null Wed Feb 25 16:02:08 2004
+++ setupapi_main.c Wed Feb 25 15:58:14 2004
@@ -0,0 +1,376 @@
+/*
+ * SETUPAPI library functions
+ * 32-bit version of setupx_main.c
+ *
+ * Copyright 2004 Aleksey Bragin (ReactOS Project)
+ *
+ * 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 "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winerror.h"
+#include "wine/winuser16.h"
+#include "wownt32.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "setupapi.h"
+#include "setupx16.h"
+#include "setupapi_private.h"
+#include "winerror.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+
+/*
+ * Returns pointer to a string list with the first entry being number
+ * of strings.
+ *
+ * Hmm. Should this be InitSubstrData(), GetFirstSubstr() and GetNextSubstr()
+ * instead?
+ */
+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;
+}
+
+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 (SETUPAPI.@)
+ *
+ * hwnd = parent window
+ * handle = instance of SETUPAPI.DLL
+ * lpszCmdLine = e.g. "DefaultInstall 132 C:\MYINSTALL\MYDEV.INF"
+ * Here "DefaultInstall" is the .inf file section to be installed (optional).
+ * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h).
+ *
+ * nCmdShow = nCmdShow of CreateProcess
+ */
+
+void WINAPI InstallHinfSection(HWND hwnd, HINSTANCE handle, LPCSTR lpszCmdLine, INT nCmdShow)
+{
+ LPSTR *pSub;
+ DWORD count;
+ HINF hInf = 0;
+ WORD wFlags;
+ BOOL reboot = FALSE;
+ BOOL err;
+ HSPFILEQ fQueue;
+ PVOID cbContext;
+
+ TRACE("(%04x, %04x, %s, %d);\n", hwnd, handle, lpszCmdLine, nCmdShow);
+
+ pSub = SETUPX_GetSubStrings((LPSTR)lpszCmdLine, ' ');
+ count = *(DWORD *)pSub;
+
+ if (count < 2) /* invalid number of arguments ? */
+ {
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ hInf = SetupOpenInfFileA(*(pSub+count), NULL, INF_STYLE_WIN4, NULL);
+ if (hInf == (HINF)INVALID_HANDLE_VALUE)
+ {
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ /* Deal with registry settings */
+ err = SetupInstallFromInfSectionA(hwnd, hInf, (PCSTR)(*(pSub+1)), SPINST_ALL ^ SPINST_FILES/*flags*/,
+ NULL/*HKEY key_root*/, NULL/*PCWSTR src_root*/, 0/*UINT copy_flags*/,
+ NULL/*PSP_FILE_CALLBACK_W callback*/, NULL/*PVOID context*/,
+ NULL/*HDEVINFO devinfo*/, NULL/*PSP_DEVINFO_DATA devinfo_data*/);
+
+ if (err)
+ {
+ /* TODO: Show some message box saying installing from INF section has failed */
+ /* FIXME: Use strings from resources, and do it the way Windows does */
+ MessageBoxA(hwnd, "InstallFromHinfSection", "Installing registry settings from an INF section failed", MB_OK);
+
+ /* release alloced memory */
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ /* Deal with files now */
+ fQueue = SetupOpenFileQueue();
+
+ if (fQueue == INVALID_HANDLE_VALUE)
+ {
+ /* TODO: Show some message box saying creating a file queue has failed */
+ MessageBoxA(hwnd, "InstallFromHinfSection", "File queue opening failed", MB_OK);
+
+ /* release alloced memory */
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+ return;
+ }
+
+ cbContext = SetupInitDefaultQueueCallback(hwnd);
+
+ /* Fullfill the file queue */
+ /* FIXME: Is the flag (SP_COPY_NEWER) right for this call? */
+ SetupInstallFilesFromInfSectionA(hInf, /*HINF hlayout*/NULL, fQueue,
+ (PCSTR)(*(pSub+1)), /*PCSTR src_root*/NULL, SP_COPY_NEWER);
+
+ err = SetupCommitFileQueueA(hwnd, fQueue, SetupDefaultQueueCallbackA, cbContext);
+
+
+ /* Release all alloced handles and memory */
+ SetupCloseFileQueue(fQueue);
+ SetupTermDefaultQueueCallback(cbContext);
+ SetupCloseInfFile(hInf);
+ SETUPX_FreeSubStrings(pSub);
+
+ /* Deal with flags now */
+ 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:
+ /* FIXME: What is the SetupPromptReboot() function is for? */
+ /* Anyway it isn't implemented */
+ if (MessageBoxA(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);
+ return;
+ }
+
+ if (reboot)
+ {
+ ExitWindowsEx(EWX_REBOOT, 0);
+ }
+}
+
+typedef struct
+{
+ LPCSTR RegValName;
+ LPCSTR StdString; /* fallback string; sub dir of windows directory */
+} LDID_DATA;
+
+static const LDID_DATA LDID_Data[34] =
+{
+ { /* 0 (LDID_NULL) -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */
+ "SourcePath", /* hmm, does SETUPX have to care about updating it ?? */
+ NULL
+ },
+ { /* 2 (LDID_SETUPTEMP) = setup temp dir */
+ "SetupTempDir",
+ NULL
+ },
+ { /* 3 (LDID_UNINSTALL) = uninstall backup dir */
+ "UninstallDir",
+ NULL
+ },
+ { /* 4 (LDID_BACKUP) = backup dir */
+ "BackupDir",
+ NULL
+ },
+ { /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */
+ "SetupScratchDir",
+ NULL
+ },
+ { /* 6 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 7 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 8 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 9 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 10 (LDID_WIN) = windows dir */
+ "WinDir",
+ ""
+ },
+ { /* 11 (LDID_SYS) = system dir */
+ "SysDir",
+ NULL /* call GetSystemDirectory() instead */
+ },
+ { /* 12 (LDID_IOS) = IOSubSys dir */
+ NULL, /* FIXME: registry string ? */
+ "SYSTEM\\IOSUBSYS"
+ },
+ { /* 13 (LDID_CMD) = COMMAND dir */
+ NULL, /* FIXME: registry string ? */
+ "COMMAND"
+ },
+ { /* 14 (LDID_CPL) = control panel dir */
+ NULL,
+ ""
+ },
+ { /* 15 (LDID_PRINT) = windows printer dir */
+ NULL,
+ "SYSTEM" /* correct ?? */
+ },
+ { /* 16 (LDID_MAIL) = destination mail dir */
+ NULL,
+ ""
+ },
+ { /* 17 (LDID_INF) = INF dir */
+ "SetupScratchDir", /* correct ? */
+ "INF"
+ },
+ { /* 18 (LDID_HELP) = HELP dir */
+ NULL, /* ??? */
+ "HELP"
+ },
+ { /* 19 (LDID_WINADMIN) = Admin dir */
+ "WinAdminDir",
+ ""
+ },
+ { /* 20 (LDID_FONTS) = Fonts dir */
+ NULL, /* ??? */
+ "FONTS"
+ },
+ { /* 21 (LDID_VIEWERS) = Viewers */
+ NULL, /* ??? */
+ "SYSTEM\\VIEWERS"
+ },
+ { /* 22 (LDID_VMM32) = VMM32 dir */
+ NULL, /* ??? */
+ "SYSTEM\\VMM32"
+ },
+ { /* 23 (LDID_COLOR) = ICM dir */
+ "ICMPath",
+ "SYSTEM\\COLOR"
+ },
+ { /* 24 (LDID_APPS) = root of boot drive ? */
+ "AppsDir",
+ "C:\\"
+ },
+ { /* 25 (LDID_SHARED) = shared dir */
+ "SharedDir",
+ ""
+ },
+ { /* 26 (LDID_WINBOOT) = Windows boot dir */
+ "WinBootDir",
+ ""
+ },
+ { /* 27 (LDID_MACHINE) = machine specific files */
+ "MachineDir",
+ NULL
+ },
+ { /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */
+ "HostWinBootDir",
+ NULL
+ },
+ { /* 29 -- not defined */
+ NULL,
+ NULL
+ },
+ { /* 30 (LDID_BOOT) = Root of boot drive */
+ "BootDir",
+ NULL
+ },
+ { /* 31 (LDID_BOOT_HOST) = Root of boot drive host */
+ "BootHost",
+ NULL
+ },
+ { /* 32 (LDID_OLD_WINBOOT) = subdir of root */
+ "OldWinBootDir",
+ NULL
+ },
+ { /* 33 (LDID_OLD_WIN) = old win dir */
+ "OldWinDir",
+ NULL
+ }
+ /* the rest (34-38) isn't too interesting, so I'll forget about it */
+};
More information about the wine-patches
mailing list