unit Message; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Registry, ActiveX, ComObj, ExtCtrls, comserv; type TfrmMessage = class(TForm) Label1: TLabel; Panel1: TPanel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public Done: boolean; end; var frmMessage: TfrmMessage; implementation uses VAUtils, FSAPILib_TLB, VA508AccessibilityConst; {$R *.dfm} {$R FSAPIVER.res} {$R JAWSAPI.res} const JAWS_INSTALL_DIRECTORY_KEY = 'SOFTWARE\Freedom Scientific\JAWS\'; JAWS_INSTALL_DIRECTORY_VAR = 'Target'; JAWS_SHARED_DIR = 'Shared\'; JAWS_FSAPI_DIR = 'fsapi\'; DLL_NAME = 'FSAPI.dll'; CPP_INSTALL_APP = 'vcredist_x86.exe'; type TDllRegisterServer = function: HResult; stdcall; const DllRegisterServerName = 'DllRegisterServer'; UPDATE_VERSION_ID = 5000; TARGET_DIR_ID = 5001; DLL_RESOURCE_NAME = 'COMOBJECT'; procedure TfrmMessage.Button1Click(Sender: TObject); begin Close; end; procedure TfrmMessage.FormCreate(Sender: TObject); var UpdateDirs: TStringList; msg: string; buffer: array[0..255] of char; procedure ProcessParams; var data: TStringList; version: string; begin if (ParamCount > 1) and FileExists(ParamStr(1)) then begin version := FileVersionValue(ParamStr(1), FILE_VER_FILEVERSION); data := TStringList.Create; try data.add('STRINGTABLE'); data.add('{'); data.add(' ' + IntToStr(UPDATE_VERSION_ID) + ', "' + version + '"'); data.add('}'); data.SaveToFile(ParamStr(2)); finally data.Free; end; end; Done := TRUE; end; procedure GetTargetDirectories(Dirs: TStringList); var reg: TRegistry; keys: TStringList; idx, i: integer; key, dir: string; JFile, JFileVersion: string; VerOK, Found: boolean; begin keys := TStringList.Create; try reg := TRegistry.Create(KEY_READ); try reg.RootKey := HKEY_LOCAL_MACHINE; reg.OpenKeyReadOnly(JAWS_INSTALL_DIRECTORY_KEY); reg.GetKeyNames(keys); Found := FALSE; for I := 0 to keys.Count - 1 do begin key := JAWS_INSTALL_DIRECTORY_KEY + keys[i] + '\'; reg.CloseKey; if reg.OpenKeyReadOnly(key) then begin dir := LowerCase(reg.ReadString(JAWS_INSTALL_DIRECTORY_VAR)); JFile := AppendBackSlash(dir) + JAWS_APPLICATION_FILENAME; if FileExists(JFile) then begin Found := TRUE; JFileVersion := FileVersionValue(JFile, FILE_VER_FILEVERSION); VerOK := VersionOK(JAWS_REQUIRED_VERSION, JFileVersion); if VerOK then begin idx := pos('\jaws\', dir); if idx > 0 then begin dir := copy(dir, 1, idx); if dirs.IndexOf(dir) < 0 then dirs.Add(dir); end; end; end; end; end; if found and (dirs.Count = 0) then dirs.Add(''); finally reg.Free; end; finally keys.free; end; end; function RegSvr(filename: string): boolean; var dll: HModule; regsvr: TDllRegisterServer; begin Result := TRUE; dll := 0; try dll := LoadLibrary(PChar(Filename)); if dll > HINSTANCE_ERROR then begin try regsvr := GetProcAddress(dll, DllRegisterServerName); if assigned(regsvr) then OleCheck(regsvr); finally FreeLibrary(dll); end; end else Result := FALSE; except Result := FALSE; if dll > HINSTANCE_ERROR then FreeLibrary(dll); end; end; procedure RegisterServer(filename: string; var msg: string); var api: IJawsApi; oldmsg: string; Registered: boolean; cppInstall: string; begin try try api := CoJawsApi.Create; except oldmsg := msg; msg := 'Error registering the required JAWS Component (' + DLL_NAME + '). You must have admin rights on your machine to register this component. ' + 'Please contact your system administrator for assistance.'; try Registered := RegSvr(filename); if not Registered then begin cppInstall := ExtractFilePath(Application.ExeName) + CPP_INSTALL_APP; if fileExists(cppInstall) then begin ExecuteAndWait(cppInstall); Registered := RegSvr(filename); end; end; if Registered then begin api := CoJawsApi.Create; if oldmsg = '' then msg :='' else msg := oldmsg + #13#10; msg := msg + 'The required JAWS Component has been successfully registered.'; end; except end; end; finally api := nil; end; end; procedure UpdateCheck(UpdateDirs: TStringList; var msg: string); var UpdateVersion, ExistingVersion: string; i: integer; dirs: TStringList; filename, dir, TargetDir: string; update: boolean; begin LoadString(HInstance, UPDATE_VERSION_ID, @buffer, 255); UpdateVersion := StrPas(buffer); LoadString(HInstance, TARGET_DIR_ID, @buffer, 255); TargetDir := StrPas(buffer); dirs := TStringList.Create; try GetTargetDirectories(dirs); if dirs.Count < 1 then msg := 'Can not find JAWS installed on this machine'; if (dirs.Count = 1) and (dirs[0] = '') then begin dirs.Delete(0); msg := 'JAWS version ' + JAWS_REQUIRED_VERSION + ' or higher is required in order to run JAWSUpdate'; end; for I := 0 to dirs.Count - 1 do begin dir := dirs[i] + JAWS_SHARED_DIR + JAWS_FSAPI_DIR + TargetDir; dir := AppendBackSlash(dir); update := TRUE; if DirectoryExists(dir) then begin filename := dir + DLL_NAME; if FileExists(fileName) then begin ExistingVersion := FileVersionValue(fileName, FILE_VER_FILEVERSION); update := not VersionOK(UpdateVersion, ExistingVersion); if not update then RegisterServer(filename, msg); end; end; if update then UpdateDirs.Add(dirs[i]); end; finally dirs.Free; end; if (UpdateDirs.Count < 1) and (msg = '') then msg := 'The required JAWS Component is already installed on your machine'; end; function MakeDirError(dir: string; var msg: string): boolean; begin Result := FALSE; if not DirectoryExists(dir) then begin if not CreateDir(dir) then begin msg := 'Error Creating Directory ' + dir; Result := TRUE; end; end; end; procedure DoUpdate(UpdateDirs: TStringList; var msg: string); var i: integer; dir, last: string; TargetDir: string; rs: TResourceStream; fs: TFileStream; filename: string; begin LoadString(HInstance, TARGET_DIR_ID, @buffer, 255); TargetDir := StrPas(buffer); for I := 0 to UpdateDirs.Count - 1 do begin dir := UpdateDirs[i]; if MakeDirError(dir, msg) then continue; dir := dir + JAWS_SHARED_DIR; if MakeDirError(dir, msg) then continue; dir := dir + JAWS_FSAPI_DIR; if MakeDirError(dir, msg) then continue; dir := dir + TargetDir; dir := AppendBackSlash(dir); if MakeDirError(dir, msg) then continue; filename := dir + DLL_NAME; if FileExists(filename) then DeleteFile(filename); last := filename; try rs := TResourceStream.Create(HInstance, DLL_RESOURCE_NAME, RT_RCDATA); try fs := TFileStream.Create(filename, fmCreate OR fmShareExclusive); try fs.CopyFrom(rs, rs.Size); finally fs.Free; end; finally rs.Free; end; except on e:Exception do msg := e.Message; end; end; if msg = '' then begin msg := 'The required JAWS Component has been successfully installed.'; RegisterServer(last, msg); end; end; procedure DeleteOldUpdater; var u8File: string; begin u8File := ExtractFilePath(Application.ExeName) + 'Jaws8Update.exe'; if fileExists(u8File) then SysUtils.DeleteFile(u8File); end; begin if (ParamCount > 0) then ProcessParams else begin DeleteOldUpdater; UpdateDirs := TStringList.Create; try msg := ''; UpdateCheck(UpdateDirs, msg); if UpdateDirs.Count > 0 then DoUpdate(UpdateDirs, msg); label1.Caption := msg; finally UpdateDirs.Free; end; end; end; procedure TfrmMessage.FormShow(Sender: TObject); begin if Done then Close; end; end.