Remove no-longer-used svn_*_get_mergeinfo_for_tree APIs.
[svn.git] / packages / windows-innosetup / is_main.pas
blob5bebb3dd33d19a2f4b134babd72225b2d5f1b799
1 (* is_main.pas: Pascal Scripts routines for Inno Setup Windows installer.
2 * ====================================================================
3 * Copyright (c) 2000-2005 CollabNet. All rights reserved.
5 * This software is licensed as described in the file COPYING, which
6 * you should have received as part of this distribution. The terms
7 * are also available at http://subversion.tigris.org/license-1.html.
8 * If newer versions of this license are posted there, you may use a
9 * newer version instead, at your option.
11 * This software consists of voluntary contributions made by many
12 * individuals. For exact contribution history, see the revision
13 * history and logs, available at http://subversion.tigris.org/.
14 * ====================================================================
17 // ****************************************************************************
18 // Global variables
19 var
20 // Required dlls
21 g_bMsVcpNotFound: Boolean; // Visual C++ 6.0 Runtimes
22 g_bShFolderNotFound: Boolean; // shfolder.dll
24 // Apache
25 g_bHandleApache: Boolean;
26 g_sApachePath: String;
27 g_sApachePathBin: String;
28 g_sApachePathConf: String;
31 const
32 // Visual C++ 6.0 Runtime file related
33 FILE_MSVCPDLL = 'msvcp60.dll';
34 URL_VCREDIST = 'http://support.microsoft.com/support/kb/articles/Q259/4/03.ASP';
36 // shfolder.dll related
37 FILE_SHFOLDERDLL = 'shfolder.dll';
38 URL_SHFREDIST = 'http://download.microsoft.com/download/platformsdk/Redist/5.50.4027.300/W9XNT4/EN-US/shfinst.EXE';
40 // Apache
41 REG_KEY_APACHE_SERVICE = 'SYSTEM\CurrentControlSet\Services\Apache2';
42 APACHE_VER_MIN = '{#= apache_ver_min}';
44 // Status codes for modules in httpd.conf
45 STATUS_NONE = 0;
46 STATUS_DISABLED = 1;
47 STATUS_ENABLED = 2;
49 // ****************************************************************************
50 // Name: BackslashToSlash
51 // Purpose: Turning back slashes into slashes. This function is stolen
52 // shamelessly from the Inno help file.
53 // NOTE: For some unknown reason, this function has to stay here before
54 // other functions in order to avoid compile errors from the setup
55 // program. I don't not why, ..anyone?
56 function BackslashToSlash(const S: String): String;
57 var
58 I: Integer;
59 begin
60 Result := S;
61 I := 1;
62 while I <= Length(Result) do
63 begin
64 if Result[I] = '\' then
65 Result[I] := '/';
66 // Go to the next character. But do not simply increment I by 1.
67 // Increment by CharLength() in case Result[I] is a double-byte character.
68 I := I + CharLength(Result, I);
69 end;
70 end;
72 ///////////////////////////////////////////////////////////////////////////////
73 // APACHE related stuff
75 // ****************************************************************************
76 // Name: ApachePathParent
77 // Purpose: Returns the path of Apache parent folder.
78 function ApachePathParent(): String;
79 var
80 sApachePathParent: String;
81 iLengthString: Integer;
82 iPosK: Integer;
83 begin
85 if RegKeyExists(HKLM, REG_KEY_APACHE_SERVICE) and UsingWinNT then
86 begin
87 // Set g_sApachePathBin
88 RegQueryStringValue(HKLM, REG_KEY_APACHE_SERVICE,
89 'ImagePath', sApachePathParent);
91 // Remove the run command and strip quotes away from g_sApachePathBin
92 iPosK := Pos('-k', sApachePathParent);
93 iLengthString := Length(sApachePathParent);
94 Delete(sApachePathParent, iLengthString - (iLengthString - iPosK), iPosK);
95 sApachePathParent := RemoveQuotes(sApachePathParent);
97 // Strip basename twice so only the Apache parent path is left
98 sApachePathParent := ExtractFileDir(sApachePathParent);
99 sApachePathParent := ExtractFileDir(sApachePathParent);
100 end;
102 // Function variables
103 Result := sApachePathParent;
104 end;
106 // ****************************************************************************
107 // Name: ApacheTask
108 // Purpose: Decide if we should handle the Apache Server or not
109 function ApacheTask(): Boolean;
110 begin
111 Result:= UsingWinNT and not (ApachePathParent = '');
112 end;
114 // ****************************************************************************
115 // Name: ApacheBinFound
116 // Purpose: Checks if bin\apache.exe excists in Apache's parent folder.
117 // Returns True if Yes and False if No
118 function ApacheBinFound(): Boolean;
120 sApacheBinary: String;
121 begin
122 sApacheBinary := ApachePathParent() + '\bin\apache.exe';
124 if FileExists(sApacheBinary) then
125 begin
126 Result:= True;
127 end else begin
128 Result:= False;
129 end;
130 end;
132 // ****************************************************************************
133 // Name: ApacheServiceStop
134 // Purpose: Stopping the Apache Service
135 procedure ApacheServiceStop();
137 bRetVal: Boolean;
138 ErrorCode: Integer;
139 begin
140 bRetVal := Exec('cmd.exe', '/C apache -k stop', g_sApachePathBin,
141 SW_HIDE, ewWaitUntilTerminated, ErrorCode);
142 end;
144 // ****************************************************************************
145 // Name: ApacheServiceStart
146 // Purpose: Starting the Apache Service
147 procedure ApacheServiceStart();
149 bRetVal: Boolean;
150 ErrorCode: Integer;
151 begin
152 bRetVal := Exec('cmd.exe', '/C apache -k start', g_sApachePathBin,
153 SW_HIDE, ewWaitUntilTerminated, ErrorCode);
154 end;
157 // ****************************************************************************
158 // Name: ApacheModuleStatus
159 // Purpose: Identifying if a module is in a string and returning its status
160 Function ApacheModuleStatus(sLine: String): Integer;
162 iStatus: Integer;
163 iPosSharp, iPosModule: Integer;
164 begin
165 iStatus:= STATUS_NONE;
166 iPosSharp := Pos('#', sLine);
167 iPosModule := Pos('LoadModule ', sLine);
169 if Pos('foo_module ', sLine) = 0 then
170 begin
171 if (iPosSharp > 0) and (iPosModule > iPosSharp) then
172 begin
173 iStatus := STATUS_DISABLED;
174 end else
175 begin
176 iStatus := STATUS_ENABLED;
177 end;
178 end;
180 Result := iStatus;
181 end;
183 // ****************************************************************************
184 // Name: ApacheModuleName
185 // Purpose: Extracting and returning a module name from a string
186 Function ApacheModuleName(sLine: String): String;
188 iPosModNameStart, iPosModNameEnd: Integer;
189 iCharNum: Integer;
190 sModuleName : String;
191 begin
192 iPosModNameStart := (Pos('modules/mod_', sLine) + 12);
193 iPosModNameEnd := (Pos('.so', sLine) - 1);
195 sModuleName := '';
196 iCharNum := iPosModNameStart;
198 for iCharNum := iPosModNameStart to iPosModNameEnd do
199 begin
200 sModuleName := sModuleName + StrGet(sLine, iCharNum);
201 end;
203 sModuleName := sModuleName + '_module';
205 Result := sModuleName;
206 end;
208 // ****************************************************************************
209 // Name: ApacheConfFileEdit
210 // Purpose: Checking if the httpd.conf (Subversion related modules) file
211 // if needed.
212 procedure ApacheConfFileEdit(aHttpdConf: TArrayOfString;
213 iPosFileModules, iPosFileModulesPost,
214 iPosModDav, iStatusModDav,
215 iPosModDavSvn, iStatusModDavSvn,
216 iPosModAuthzSvn, iStatusModAuthzSvn: Integer);
218 sConfFileName, sTimeString: String;
219 sModuleDir, sLoadModDav, sLoadModDavSvn, sLoadModAuthzSvn: String;
221 begin
222 sConfFileName := g_sApachePathConf + '\httpd.conf';
223 sTimeString := GetDateTimeString('yyyy/mm/dd hh:mm:ss', '-', ':');
225 sModuleDir := ExpandConstant('{app}');
226 sModuleDir := sModuleDir + '\bin';
227 sModuleDir := BackslashToSlash(sModuleDir);
229 sLoadModDav := 'LoadModule dav_module modules/mod_dav.so';
230 sLoadModDavSvn := 'LoadModule dav_svn_module "' + sModuleDir + '/mod_dav_svn.so"';
231 sLoadModAuthzSvn := 'LoadModule authz_svn_module "' + sModuleDir + '/mod_authz_svn.so"';
233 //Backup the current httpd.conf
234 FileCopy (sConfFileName, sConfFileName + '-svn-' + sTimeString + '.bak', False);
236 // Add the modules if they're not there
237 if (iStatusModDav = STATUS_NONE) then
238 begin
239 if iPosModDav = 0 then
240 begin
241 iPosModDav := iPosFileModules + 10;
242 end;
244 aHttpdConf[iPosModDav] := aHttpdConf[iPosModDav] + #13#10 + sLoadModDav;
245 end;
247 if (iStatusModDavSvn = STATUS_NONE) then
248 aHttpdConf[iPosFileModulesPost -1] := aHttpdConf[iPosFileModulesPost -1] + #13#10 +
249 sLoadModDavSvn;
251 if (iStatusModAuthzSvn = STATUS_NONE) then
252 aHttpdConf[iPosFileModulesPost -1] := aHttpdConf[iPosFileModulesPost -1] + #13#10 +
253 sLoadModAuthzSvn;
255 // Enable modules if disabled ********************************
256 if (iStatusModDav = STATUS_DISABLED) then
257 aHttpdConf[iPosModDav] := sLoadModDav;
259 if (iStatusModDavSvn = STATUS_DISABLED) then
260 aHttpdConf[iPosModDavSvn] := sLoadModDavSvn;
262 if (iStatusModAuthzSvn = STATUS_DISABLED) then
263 aHttpdConf[iPosModAuthzSvn] := sLoadModAuthzSvn;
265 SaveStringsToFile(sConfFileName, aHttpdConf, False);
266 end;
268 // ****************************************************************************
269 // Name: ApacheConfFileHandle
270 // Purpose: Checking if the httpd.conf (Subversion related modules) file should
271 // be edited and sets some data for further proccessing if needed.
272 procedure ApacheConfFileHandle();
274 aHttpdConf : TArrayOfString;
276 sConfFileName: String;
277 sCurrentLine: String;
279 iLineNum, iArrayLen: Integer;
281 iPosFileModules, iPosFileModulesPost : Integer;
282 iPosModDav, iPosModDavSvn, iPosModAuthzSvn: Integer;
283 iStatusModDav, iStatusModDavSvn, iStatusModAuthzSvn: Integer;
284 begin
285 iStatusModDav := STATUS_NONE;
286 iStatusModDavSvn := STATUS_NONE;
287 iStatusModAuthzSvn := STATUS_NONE;
289 sConfFileName:= g_sApachePathConf + '\httpd.conf';
291 //Load the httpd.conf to the aHttpdConf array and init vars
292 LoadStringsFromFile(sConfFileName, aHttpdConf);
294 iArrayLen := GetArrayLength(aHttpdConf)-1;
296 // Check httpd.conf line by line
297 for iLineNum := 0 to iArrayLen do
298 begin
299 sCurrentLine := aHttpdConf[iLineNum];
301 // Get module status and file data with help of the modules
302 if (Pos('LoadModule ', sCurrentLine) > 0 ) then
303 begin
304 if (ApacheModuleStatus(sCurrentLine) > 0) then
305 begin
306 if iPosFileModules = 0 then
307 begin
308 iPosFileModules := iLineNum;
309 end;
311 iPosFileModulesPost := iLineNum + 1;
312 end;
314 //Decide placements and status of modules --------
316 // dav_module: If we (for some reason) don't find dav_module then
317 // we'll try to set the placement with help of cgi_module and make
318 // sure that we do it _before_ a dav_fs_module.
319 if ApacheModuleName(sCurrentLine) = 'dav_module' then
320 begin
321 iPosModDav := iLineNum;
322 iStatusModDav := ApacheModuleStatus(sCurrentLine);
323 end;
325 if (ApacheModuleName(sCurrentLine) = 'cgi_module') and
326 ((iStatusModDav = STATUS_NONE) and (iPosModDav = 0)) then
327 iPosModDav := iLineNum + 1;
329 if (ApacheModuleName(sCurrentLine) = 'dav_fs_module') and
330 (iStatusModDav = STATUS_NONE) then
331 iPosModDav := iLineNum - 1;
333 // dav_svn_module:
334 if ApacheModuleName(sCurrentLine) = 'dav_svn_module' then
335 begin
336 iPosModDavSvn := iLineNum;
337 iStatusModDavSvn := ApacheModuleStatus(sCurrentLine);
338 end;
340 // authz_svn_module:
341 if ApacheModuleName(sCurrentLine) = 'authz_svn_module' then
342 begin
343 iPosModAuthzSvn := iLineNum;
344 iStatusModAuthzSvn := ApacheModuleStatus(sCurrentLine);
345 end;
346 end;
347 end;
349 // Edit httpd.conf if needed.
350 if (iStatusModDav + iStatusModDavSvn + iStatusModAuthzSvn) <>
351 (STATUS_ENABLED * 3) then
352 begin
353 ApacheConfFileEdit (aHttpdConf,
354 iPosFileModules, iPosFileModulesPost,
355 iPosModDav, iStatusModDav,
356 iPosModDavSvn, iStatusModDavSvn,
357 iPosModAuthzSvn, iStatusModAuthzSvn);
358 end;
359 end;
361 // ****************************************************************************
362 // Name: ApacheVersion
363 // Purpose: Returns apache.exe's version with the last number stripped.
364 function ApacheVersion(): String;
366 sApacheVersion: String;
367 begin
368 GetVersionNumbersString(g_sApachePathBin + '\apache.exe' ,sApacheVersion);
369 Delete(sApacheVersion, 7, 2);
370 Result := sApacheVersion;
371 end;
373 // ****************************************************************************
374 // Name: VerifyApache
375 // Purpose: Finding/Setting Apache paths and version info
376 procedure VerifyApache();
378 sMsg: String;
379 sApacheVersion: String;
380 begin
381 g_bHandleApache := True;
383 // Set/check the Apache paths
384 g_sApachePath := ApachePathParent;
386 // apache.exe
387 if g_sApachePathBin = '' then
388 g_sApachePathBin := g_sApachePath + '\bin';
390 if not FileExists(g_sApachePathBin + '\apache.exe') then
391 begin
392 sMsg := 'Could not find ''apache.exe'' in the system. Please, browse' +
393 ' to the folder where the Apache binary is.';
394 BrowseForFolder(sMsg , g_sApachePathBin, false);
395 end;
397 // httpd.conf
398 if g_sApachePathConf = '' then
399 g_sApachePathConf := g_sApachePath + '\conf';
401 if not FileExists(g_sApachePathConf + '\httpd.conf') then
402 begin
403 sMsg := 'Could not find ''httpd.conf'' in the system. Please, browse' +
404 ' to the folder where configuration file is.';
405 BrowseForFolder(sMsg, g_sApachePathConf, false);
406 end;
408 // Check that we have the required Apache version and warn the user if
409 // needed
410 sApacheVersion := ApacheVersion;
412 if CompareStr(sApacheVersion, APACHE_VER_MIN) < 0 then
413 begin
414 sMsg :=
415 'WARNING: Apache http server version ' + sApacheVersion + ' is detected and the' + #13#10 +
416 'Subversion modules are built for the ' + APACHE_VER_MIN + ' version of the server.' + #13#10#13#10 +
417 'You are strongly encouraged to quit this setup and upgrade your' + #13#10 +
418 'apache server first, or go back to this setup''s ''Additional Tasks''' + #13#10 +
419 'dialog box and uncheck the task of installing the Apache modules.' + #13#10;
421 MsgBox(sMsg, mbError, MB_OK);
422 end;
423 end;
425 ///////////////////////////////////////////////////////////////////////////////
426 // Misc. funtions used by the setup
428 // ****************************************************************************
429 // Name: ComponentList
430 // Purpose: In use for UninsHs when the user wants to uninstall/repair the
431 // installation,
432 function ComponentList(Default: string):string;
433 begin
434 Result := WizardSelectedComponents(False);
435 end;
437 // ****************************************************************************
438 // Name: ShFolderDllNotFound
439 // Purpose: Checks if FILE_SHFOLDERDLL does not exist.
440 // Returns True if missing and False if present.
441 function ShFolderDllNotFound(): Boolean;
443 sSysDir: String;
444 begin
445 sSysDir := ExpandConstant('{sys}');
447 if FileExists(sSysDir + '\' + FILE_SHFOLDERDLL) then
448 begin
449 g_bShFolderNotFound := False;
450 end else begin
451 g_bShFolderNotFound := True;
452 end;
454 Result:= g_bShFolderNotFound;
455 end;
457 // ****************************************************************************
458 // Name: SysFilesDownLoadInfo
459 // Purpose: Informs the user about missing Windows system file(s).
460 Procedure SysFilesDownLoadInfo;
462 sSysFiles: String;
463 sItThem: String;
464 sFile: string;
465 sDocument: string;
466 sMsg: String;
467 begin
468 sItThem := ' it';
469 sFile := ' file';
470 sDocument := ' document';
472 if (g_bMsVcpNotFound and g_bShFolderNotFound) then
473 begin
474 sSysfiles := FILE_MSVCPDLL + ' and ' + FILE_SHFOLDERDLL;
475 sItThem := ' them';
476 sFile := ' files';
477 sDocument := ' documents';
478 end;
480 if (g_bMsVcpNotFound and not g_bShFolderNotFound) then
481 sSysfiles := FILE_MSVCPDLL;
483 if (g_bShFolderNotFound and not g_bMsVcpNotFound) then
484 sSysfiles := FILE_SHFOLDERDLL;
486 sMsg :='The' + sFile + ' ' + sSysFiles + ' was not found in the system.' + #13#10#13#10 +
487 'Please, go to the Subversion entry in the Start Menu after the installation and' + #13#10 +
488 'read the ''Download and install''' + sDocument + ' for ' + sSysfiles + '.' + #13#10#13#10 +
489 'Subversion will not work without this' + sFile + '.' + #13#10#13#10;
491 MsgBox(sMsg, mbInformation, MB_OK);
492 end;
494 // ****************************************************************************
495 // Name: VCRuntimeNotFound
496 // Purpose: Checks if FILE_MSVCPDLL does not exist.
497 // Returns True if missing and False if present.
498 function VCRuntimeNotFound(): Boolean;
500 sSysDir: String;
501 begin
502 sSysDir := ExpandConstant('{sys}');
504 if FileExists(sSysDir + '\' + FILE_MSVCPDLL) then
505 begin
506 g_bMsVcpNotFound := False;
507 end else begin
508 g_bMsVcpNotFound := True;
509 end;
511 Result:= g_bMsVcpNotFound;
512 end;
514 ///////////////////////////////////////////////////////////////////////////////
515 // Build in Inno Setup Pascal functions
516 // See Inno help file for usage about this functions.
518 // ****************************************************************************
519 // Name: InitializeSetup
520 // Purpose: Called during Setup's initialization.
521 // Return False to abort Setup, True otherwise.
522 function InitializeSetup(): Boolean;
523 begin
524 //Initialize some global variables
525 g_bMsVcpNotFound := VCRuntimeNotFound;
526 g_bShFolderNotFound := ShFolderDllNotFound;
527 g_bHandleApache:= False;
528 Result := True;
529 end;
531 // ****************************************************************************
532 // Name: CurPageChanged
533 // Purpose: Called after a new wizard page (specified by CurPageID) is shown.
534 procedure CurPageChanged(CurStep: Integer);
535 begin
536 case CurStep of
537 wpReady: // Event after selected tasks
538 if IsTaskSelected('apachehandler') then
539 VerifyApache;
540 wpInstalling: // Event before setup is copying destination files
541 if g_bHandleApache then
542 begin
543 ApacheServiceStop;
544 //ApacheCopyModules;
545 end;
546 end;
547 end;
549 // ****************************************************************************
550 // Name: CurStepChanged
551 // Purpose: Event function to perform pre- and post-install tasks.
552 procedure CurStepChanged(CurStep: TSetupStep);
553 begin
554 if (CurStep = ssPostInstall) and g_bHandleApache then
555 begin;
556 ApacheConfFileHandle;
557 ApacheServiceStart;
558 end;
559 end;
561 // ****************************************************************************
562 // Name: NextButtonClick
563 // Purpose: Called when the user clicks the Next button.
564 // If you return True, the wizard will move to the next page; if you
565 // return False, it will remain on the current page (specified by
566 // CurPageID).
567 function NextButtonClick(CurPage: Integer): Boolean;
568 begin
569 if (CurPage = wpSelectComponents) then
570 if (g_bMsVcpNotFound or g_bShFolderNotFound) then
571 SysFilesDownLoadInfo();
573 Result := True;
574 end;
576 // ****************************************************************************
577 // Name: ShouldSkipPage
578 // Purpose: Event function to determine whether or not a particular page
579 // (specified by PageID) should be shown at all.
580 function ShouldSkipPage(CurPage: Integer): Boolean;
581 begin
582 // START In use by UninsHs
583 if Pos('/SP-', UpperCase(GetCmdTail)) > 0 then
584 case CurPage of
585 wpWelcome, wpLicense, wpPassword, wpInfoBefore, wpUserInfo,
586 wpSelectDir, wpSelectProgramGroup, wpInfoAfter:
587 Result := True;
588 end;
589 // END In use by UninsHs
590 end;