⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdrvinst.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 2 页
字号:
(***** 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 + -