📄 pdrvinst.pas
字号:
(***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower Async Professional
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1991-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* PDRVINST.PAS 4.06 *}
{*********************************************************}
{* Printer driver installation *}
{*********************************************************}
{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}
{Options required for this unit}
{$X+,I-,T-}
{$IFDEF Win32}
{$H-,J-}
{$ENDIF}
unit PDrvInst;
{- Fax printer driver installation unit }
{Note: Does not install compressed printer driver files}
interface
uses
OoMisc,
AdExcept,
SysUtils;
type
TInstallDriverCallback = function : Boolean;
NotFoundException = class(Exception);
CantCopyException = class(Exception);
const
InstallDriverCallback : TInstallDriverCallback = nil;
var
DrvInstallError : Integer;
{ Contains the error code for the printer driver installation }
DrvInstallExtError : Integer;
{ Contains the extended error for the printer driver installation }
ErrorFile : string;
{ Contains the name of the file that couldn't be processed }
function InstallDriver (Filename : ShortString) : Boolean;
{ Attempt to install the print driver. Return True if successful. }
implementation
uses
WinTypes,
WinProcs,
WinSpool,
Registry,
Messages,
PDrvUni;
type
PPrinterStrings = ^TPrinterStrings;
TPrinterStrings =
record
pPortName : ShortString; {eg, PRINTFAX:}
pDriverName : ShortString; {eg, APF Fax}
pComment : ShortString;
pSepFile : ShortString;
pServerName : ShortString;
pPrintProcessor : ShortString;
pDataType : ShortString;
pDriverFileBase : ShortString; {eg, APFFILE}
pDriverFileName : ShortString; {eg, APFFILE.DRV}
SourceDirectory : ShortString; {eg, A:\INSTALL\}
end;
var
PrinterStrings : PPrinterStrings;
{-------------------------------------------------}
{ Copy the printer driver to the system directory }
{-------------------------------------------------}
procedure CopyDriverToSystemDirectory;
{ Copy the fax printer driver to the windows system directory }
var
lpszSrcFilename : PChar;
lpszDestFilename: PChar;
lpszSrcDir : PChar;
lpszDestDir : PChar;
lpszCurDir : PChar;
lpszTempFile : PChar;
TempFileLen : DWORD;
begin
with PrinterStrings^ do begin
lpszSrcFilename := StrAlloc(Max_Path);
lpszSrcDir := StrAlloc(Max_Path);
lpszDestDir := StrAlloc(Max_Path);
lpszTempFile := StrAlloc(Max_Path);
try
StrPCopy(lpszSrcFilename, pDriverFileName);
lpszDestFilename := lpszSrcFilename;
StrPCopy(lpszSrcDir, SourceDirectory);
lpszCurDir := nil;
TempFileLen := Max_Path;
GetSystemDirectory(lpszDestDir, Max_Path);
DrvInstallExtError := VerInstallFile(0, lpszSrcFilename,
lpszDestFilename,
lpszSrcDir, lpszDestDir,
lpszCurDir,
lpszTempFile, TempFileLen);
if DrvInstallExtError <> 0 then
if (DrvInstallExtError and (VIF_FILEINUSE or VIF_SRCOLD)) = 0 then
if (DrvInstallExtError and VIF_CANNOTREADSRC) <> 0 then
raise NotFoundException.Create(StrPas(lpszSrcFilename))
else
raise CantCopyException.Create(StrPas(lpszSrcFilename));
finally
StrDispose(lpszTempFile);
StrDispose(lpszDestDir);
StrDispose(lpszSrcDir);
StrDispose(lpszSrcFilename);
end;
end;
end;
{-----------------------------------------------------------------}
{ Code for reading string table entries directly from driver file }
{-----------------------------------------------------------------}
{ resource ID constants for printer driver installation strings }
{$I PDrvInst.INC}
type
PStringTableItem = ^TStringTableItem;
TStringTableItem =
record
Id : Word;
Tag : ShortString;
Next : PStringTableItem;
end;
procedure BuildStringTableList (var StringTableList : PStringTableItem);
{ Build a linked list of all string table entries in driver file }
type
{Old header snippet}
OldHeader =
record
Junk1 : array[1..$18] of Char;
NewHeaderFlag : Byte;
Junk2 : array[1..$23] of Char;
NewHeaderOfs : Word;
end;
{New header snippet}
NewHeader =
record
Junk : array[1..36] of Byte;
ResTableOfs : Word;
end;
{Resource table entry}
ResourceNameInfo =
record
rnOffset : Word;
rnLength : Word;
rnFlags : Word;
rnID : Word;
rnHandle : Word;
rnNLoad : Word;
end;
var
F : File;
OH : OldHeader;
NH : NewHeader;
RN : ResourceNameInfo;
ResType : Word;
Count : Word;
Align : Word;
ANode : PStringTableItem;
SaveMode : Byte;
function ReadNextType : Boolean;
{-Read the next resource type record}
begin
{Read resource type and count}
BlockRead(F, ResType, 2);
BlockRead(F, Count, SizeOf(Count));
ReadNextType := Lo(ResType) <> 0;
end;
procedure SkipNextType;
{-Skip all nameinfo entries for this resource type}
var
I : Word;
Junk : array[1..5] of Word;
begin
BlockRead(F, Junk, 4);
for I := 1 to Count do
BlockRead(F, RN, SizeOf(RN));
end;
procedure ReadStringResource (var NextNode : PStringTableItem);
{-Load the string table into an internal list}
var
Junk : array[1..10] of Byte;
B : Byte;
Adjust : Longint;
i,j : Integer;
SavedPos : Longint;
begin
BlockRead(F, Junk, 4); { reserved bytes }
for j := 1 to count do begin
BlockRead(F, RN, SizeOf(RN));
Adjust := 2 shl pred(Align);
SavedPos := FilePos(f);
Seek(F, LongInt(RN.rnOffset)*Adjust);
for i := 0 to 15 do begin
BlockRead(F, B, 1);
if B <> 0 then begin
if NextNode <> nil then begin
GetMem(NextNode^.Next, sizeof(TStringTableItem));
NextNode := NextNode^.Next;
end else begin
GetMem(StringTableList, sizeof(TStringTableItem));
NextNode := StringTableList;
end;
NextNode^.Next := nil;
BlockRead(F, NextNode^.Tag[1], B);
NextNode^.Tag[0] := Chr(B);
NextNode^.Id := pred(RN.rnID and $7FFF) * 16 + i;
end;
end;
Seek(f, SavedPos);
end;
end;
begin
with PrinterStrings^ do begin
{Open file}
SaveMode := FileMode;
FileMode := fmOpenRead;
Assign(F, AddBackSlash(SourceDirectory) + pDriverFileName);
Reset(F, 1);
FileMode := SaveMode;
if IoResult <> 0 then begin
ErrorFile := AddBackSlash(SourceDirectory) + pDriverFileName;
ErrorFile := pDriverFileName; {!!.04}
DrvInstallError := ecDrvDriverNotFound;
Exit;
end;
{Read in old-style header, done if no new style header}
BlockRead(F, OH, SizeOf(OH));
if OH.NewHeaderFlag < $40 then
Exit;
{Read in new header, seek to start of Resource Table}
Seek(F, OH.NewHeaderOfs);
BlockRead(F, NH, SizeOf(NH));
Seek(F, OH.NewHeaderOfs+NH.ResTableOfs);
{Read align shift word}
BlockRead(F, Align, 2);
ANode := nil;
while ReadNextType do begin
{Exit on errors}
if IoResult <> 0 then begin
Close(F);
if IoResult <> 0 then ;
Exit;
end;
{Handle this resource type}
if ResType = $8006 then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -