[setup16]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sun, 11 Mar 2012 10:51:40 +0000 (10:51 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sun, 11 Mar 2012 10:51:40 +0000 (10:51 +0000)
32-Bit stub installer for 16-Bit Microsoft installers

TODO: -load this installer instead of the original 16bit Microsoft installer
      -improve error handling and string allocation

svn path=/trunk/; revision=56110

reactos/base/applications/CMakeLists.txt
reactos/base/applications/setup16/CMakeLists.txt [new file with mode: 0644]
reactos/base/applications/setup16/main.c [new file with mode: 0644]

index e750c45..bac7357 100644 (file)
@@ -29,6 +29,7 @@ add_subdirectory(regedit)
 add_subdirectory(regedt32)
 add_subdirectory(sc)
 add_subdirectory(screensavers)
 add_subdirectory(regedt32)
 add_subdirectory(sc)
 add_subdirectory(screensavers)
+add_subdirectory(setup16)
 add_subdirectory(shutdown)
 add_subdirectory(sndrec32)
 add_subdirectory(sndvol32)
 add_subdirectory(shutdown)
 add_subdirectory(sndrec32)
 add_subdirectory(sndvol32)
diff --git a/reactos/base/applications/setup16/CMakeLists.txt b/reactos/base/applications/setup16/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ed84cd0
--- /dev/null
@@ -0,0 +1,10 @@
+
+set_rc_compiler()
+
+add_executable(setup16
+    main.c)
+
+set_module_type(setup16 win32gui UNICODE)
+add_importlibs(setup16 user32 gdi32 advapi32 msvcrt kernel32 shell32 setupapi)
+
+add_cd_file(TARGET setup16 DESTINATION reactos/system32 FOR all)
diff --git a/reactos/base/applications/setup16/main.c b/reactos/base/applications/setup16/main.c
new file mode 100644 (file)
index 0000000..78aed7e
--- /dev/null
@@ -0,0 +1,148 @@
+#include <windows.h>
+#include <shlobj.h>
+#include <setupapi.h>
+
+#define NT_PARAMS        L"NT3.51 Intel Params"
+#define MSSETUP_PATH     L"~MSSETUP.T\\"
+
+static UINT WINAPI ExtCabCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
+{
+    FILE_IN_CABINET_INFO_W *pInfo;
+    FILEPATHS_W *pFilePaths;
+
+    switch(Notification)
+    {
+        case SPFILENOTIFY_FILEINCABINET:
+            pInfo = (FILE_IN_CABINET_INFO_W*)Param1;
+            wcscpy(pInfo->FullTargetName, (LPCWSTR)Context);
+            wcscat(pInfo->FullTargetName, pInfo->NameInCabinet);
+            return FILEOP_DOIT;
+        case SPFILENOTIFY_FILEEXTRACTED:
+            pFilePaths = (FILEPATHS_W*)Param1;
+            return NO_ERROR;
+    }
+    return NO_ERROR;
+}
+
+BOOL DeleteDirectory(LPWSTR lpszDir)
+{
+    DWORD len = wcslen(lpszDir);
+    WCHAR *pszFrom = HeapAlloc(GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR)); 
+    wcscpy(pszFrom, lpszDir);
+    pszFrom[len] = 0;
+    pszFrom[len+1] = 0;
+
+    SHFILEOPSTRUCT fileop;
+    fileop.hwnd   = NULL;
+    fileop.wFunc  = FO_DELETE;
+    fileop.pFrom  = pszFrom;
+    fileop.pTo    = NULL;
+    fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT;
+    fileop.fAnyOperationsAborted = FALSE;
+    fileop.lpszProgressTitle     = NULL;
+    fileop.hNameMappings         = NULL;
+
+    int ret = SHFileOperation(&fileop);
+    HeapFree(GetProcessHeap(), 0, &pszFrom);
+    return (ret == 0);
+}
+
+VOID GetSystemDrive(LPWSTR lpszDrive)
+{
+    WCHAR szWindir[MAX_PATH];
+    GetWindowsDirectoryW(szWindir, MAX_PATH);
+    _wsplitpath(szWindir, lpszDrive, NULL, NULL, NULL);
+    wcscat(lpszDrive, L"\\");
+}
+
+int APIENTRY wWinMain(HINSTANCE hInstance,
+                       HINSTANCE hPrevInstance,
+                       LPWSTR    lpCmdLine,
+                       int       nCmdShow)
+{
+    UNREFERENCED_PARAMETER(hPrevInstance);
+    UNREFERENCED_PARAMETER(nCmdShow);
+
+    WCHAR szSetupPath[MAX_PATH];
+    WCHAR szFileName[MAX_PATH];
+    WCHAR szCabFileName[MAX_PATH];
+    WCHAR szCabFilePath[MAX_PATH];
+    WCHAR szTempDirName[50];
+    WCHAR szCmdLine[MAX_PATH];
+    WCHAR szTempCmdLine[MAX_PATH];
+    WCHAR szTempPath[MAX_PATH];
+    WCHAR szFullTempPath[MAX_PATH];
+    WCHAR szDrive[4];
+    DWORD dwAttrib;
+    PROCESS_INFORMATION processInfo;
+    STARTUPINFO startupInfo;
+    
+    GetCurrentDirectory(MAX_PATH, szSetupPath);
+    wcscat(szSetupPath, L"\\");
+    wcscpy(szFileName, szSetupPath);
+    wcscat(szFileName, L"setup.lst");
+    
+    /* read information from setup.lst */
+    GetPrivateProfileStringW(NT_PARAMS, L"CabinetFile", NULL, szCabFileName, MAX_PATH, szFileName);
+    GetPrivateProfileStringW(NT_PARAMS, L"TmpDirName", NULL, szTempDirName, 50, szFileName);
+    GetPrivateProfileStringW(NT_PARAMS, L"CmdLine", NULL, szCmdLine, MAX_PATH, szFileName);
+    
+    wcscpy(szCabFilePath, szSetupPath);
+    wcscat(szCabFilePath, szCabFileName);
+    
+    /* ceate temp directory */
+    GetSystemDrive(szDrive);
+    wcscpy(szTempPath, szDrive);
+    wcscat(szTempPath, MSSETUP_PATH);
+    wcscpy(szFullTempPath, szTempPath);
+    wcscat(szFullTempPath, szTempDirName);
+    wcscat(szFullTempPath, L"\\");
+    
+    if (SHCreateDirectoryEx(0, szFullTempPath, NULL) != ERROR_SUCCESS)
+    {
+        MessageBoxW(0, L"Could not create Temp Directory.", L"Error", MB_OK | MB_ICONERROR);
+        return 1;
+    }    
+
+    dwAttrib = GetFileAttributes(szTempPath);
+    SetFileAttributes(szTempPath, dwAttrib | FILE_ATTRIBUTE_HIDDEN);
+    
+    /* extract files */
+    if (!SetupIterateCabinetW(szCabFilePath, 0, ExtCabCallback, szFullTempPath))
+    {
+        MessageBoxW(0, L"Could not extract cab file", L"Error", MB_OK | MB_ICONERROR);
+        DeleteDirectory(szTempPath);
+        return 1;
+    }
+     
+    /* prepare command line */
+    wsprintf(szTempCmdLine, szCmdLine, szFullTempPath, lpCmdLine);
+    wcscpy(szCmdLine, szFullTempPath);
+    wcscat(szCmdLine, szTempCmdLine);
+    
+    /* execute the 32-Bit installer */
+    ZeroMemory(&processInfo, sizeof(processInfo));
+    ZeroMemory(&startupInfo, sizeof(startupInfo));
+    startupInfo.cb = sizeof(startupInfo);
+    if (CreateProcessW(NULL, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, szFullTempPath, &startupInfo, &processInfo))
+    {
+        WaitForSingleObject(processInfo.hProcess, INFINITE);
+        CloseHandle(processInfo.hProcess);
+        CloseHandle(processInfo.hThread);
+    }
+    else
+    {
+        WCHAR szMsg[MAX_PATH];
+        wsprintf(szMsg, L"Failed to load the installer. Error %d", GetLastError());
+        MessageBoxW(0, szMsg, L"Error", MB_OK | MB_ICONERROR);
+        DeleteDirectory(szTempPath);
+        return 1;
+    }
+    
+    /* cleanup */
+    DeleteDirectory(szTempPath);
+    
+    return 0;
+}
+
+/* EOF */
\ No newline at end of file