xref: /reactos/base/applications/setup16/main.c (revision 5100859e)
1 #define WIN32_NO_STATUS
2 #define WIN32_LEAN_AND_MEAN
3 #include <windows.h>
4 #include <shellapi.h>
5 #include <shlobj.h>
6 #include <setupapi.h>
7 
8 #define NT_PARAMS        L"NT3.51 Intel Params"
9 #define MSSETUP_PATH     L"~MSSETUP.T\\"
10 
11 static UINT WINAPI ExtCabCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
12 {
13     FILE_IN_CABINET_INFO_W *pInfo;
14     FILEPATHS_W *pFilePaths;
15 
16     DBG_UNREFERENCED_LOCAL_VARIABLE(pFilePaths);
17 
18     switch(Notification)
19     {
20         case SPFILENOTIFY_FILEINCABINET:
21             pInfo = (FILE_IN_CABINET_INFO_W*)Param1;
22             wcscpy(pInfo->FullTargetName, (LPCWSTR)Context);
23             wcscat(pInfo->FullTargetName, pInfo->NameInCabinet);
24             return FILEOP_DOIT;
25         case SPFILENOTIFY_FILEEXTRACTED:
26             pFilePaths = (FILEPATHS_W*)Param1;
27             return NO_ERROR;
28     }
29     return NO_ERROR;
30 }
31 
32 BOOL DeleteDirectory(LPWSTR lpszDir)
33 {
34     SHFILEOPSTRUCT fileop;
35     DWORD len = wcslen(lpszDir);
36     WCHAR *pszFrom = HeapAlloc(GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR));
37     int ret;
38 
39     wcscpy(pszFrom, lpszDir);
40     pszFrom[len] = 0;
41     pszFrom[len+1] = 0;
42 
43     fileop.hwnd   = NULL;
44     fileop.wFunc  = FO_DELETE;
45     fileop.pFrom  = pszFrom;
46     fileop.pTo    = NULL;
47     fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT;
48     fileop.fAnyOperationsAborted = FALSE;
49     fileop.lpszProgressTitle     = NULL;
50     fileop.hNameMappings         = NULL;
51 
52     ret = SHFileOperation(&fileop);
53     HeapFree(GetProcessHeap(), 0, pszFrom);
54     return (ret == 0);
55 }
56 
57 VOID GetSystemDrive(LPWSTR lpszDrive)
58 {
59     WCHAR szWindir[MAX_PATH];
60     GetWindowsDirectoryW(szWindir, MAX_PATH);
61     _wsplitpath(szWindir, lpszDrive, NULL, NULL, NULL);
62     wcscat(lpszDrive, L"\\");
63 }
64 
65 int APIENTRY wWinMain(HINSTANCE hInstance,
66                        HINSTANCE hPrevInstance,
67                        LPWSTR    lpCmdLine,
68                        int       nCmdShow)
69 {
70     WCHAR szSetupPath[MAX_PATH];
71     WCHAR szFileName[MAX_PATH];
72     WCHAR szCabFileName[MAX_PATH];
73     WCHAR szCabFilePath[MAX_PATH];
74     WCHAR szTempDirName[50];
75     WCHAR szCmdLine[MAX_PATH];
76     WCHAR szTempCmdLine[MAX_PATH];
77     WCHAR szTempPath[MAX_PATH];
78     WCHAR szFullTempPath[MAX_PATH];
79     WCHAR szDrive[4];
80     DWORD dwAttrib;
81     PROCESS_INFORMATION processInfo;
82     STARTUPINFO startupInfo;
83     UNREFERENCED_PARAMETER(hPrevInstance);
84     UNREFERENCED_PARAMETER(nCmdShow);
85 
86     GetCurrentDirectory(MAX_PATH, szSetupPath);
87     wcscat(szSetupPath, L"\\");
88     wcscpy(szFileName, szSetupPath);
89     wcscat(szFileName, L"setup.lst");
90 
91     if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES)
92     {
93         MessageBoxW(0, L"Cannot find Setup.lst file", L"Error", MB_OK | MB_ICONERROR);
94         return 1;
95     }
96 
97     /* read information from setup.lst */
98     GetPrivateProfileStringW(NT_PARAMS, L"CabinetFile", NULL, szCabFileName, MAX_PATH, szFileName);
99     GetPrivateProfileStringW(NT_PARAMS, L"TmpDirName", NULL, szTempDirName, 50, szFileName);
100     GetPrivateProfileStringW(NT_PARAMS, L"CmdLine", NULL, szCmdLine, MAX_PATH, szFileName);
101 
102     wcscpy(szCabFilePath, szSetupPath);
103     wcscat(szCabFilePath, szCabFileName);
104 
105     /* ceate temp directory */
106     GetSystemDrive(szDrive);
107     wcscpy(szTempPath, szDrive);
108     wcscat(szTempPath, MSSETUP_PATH);
109     wcscpy(szFullTempPath, szTempPath);
110     wcscat(szFullTempPath, szTempDirName);
111     wcscat(szFullTempPath, L"\\");
112 
113     if (SHCreateDirectoryEx(0, szFullTempPath, NULL) != ERROR_SUCCESS)
114     {
115         MessageBoxW(0, L"Could not create Temp Directory.", L"Error", MB_OK | MB_ICONERROR);
116         return 1;
117     }
118 
119     dwAttrib = GetFileAttributes(szTempPath);
120     SetFileAttributes(szTempPath, dwAttrib | FILE_ATTRIBUTE_HIDDEN);
121 
122     /* extract files */
123     if (!SetupIterateCabinetW(szCabFilePath, 0, ExtCabCallback, szFullTempPath))
124     {
125         MessageBoxW(0, L"Could not extract cab file", L"Error", MB_OK | MB_ICONERROR);
126         DeleteDirectory(szTempPath);
127         return 1;
128     }
129 
130     /* prepare command line */
131     wsprintf(szTempCmdLine, szCmdLine, szFullTempPath, lpCmdLine);
132     wcscpy(szCmdLine, szFullTempPath);
133     wcscat(szCmdLine, szTempCmdLine);
134 
135     /* execute the 32-Bit installer */
136     ZeroMemory(&processInfo, sizeof(processInfo));
137     ZeroMemory(&startupInfo, sizeof(startupInfo));
138     startupInfo.cb = sizeof(startupInfo);
139     if (CreateProcessW(NULL, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, szFullTempPath, &startupInfo, &processInfo))
140     {
141         WaitForSingleObject(processInfo.hProcess, INFINITE);
142         CloseHandle(processInfo.hProcess);
143         CloseHandle(processInfo.hThread);
144     }
145     else
146     {
147         WCHAR szMsg[MAX_PATH];
148         wsprintf(szMsg, L"Failed to load the installer. Error %lu", GetLastError());
149         MessageBoxW(0, szMsg, L"Error", MB_OK | MB_ICONERROR);
150         DeleteDirectory(szTempPath);
151         return 1;
152     }
153 
154     /* cleanup */
155     DeleteDirectory(szTempPath);
156 
157     return 0;
158 }
159 
160 /* EOF */
161