PIF 文件格式
From Borland NewsGroup:Rimvydas Paulavicius <PauLita@post.5ci.lt>
type
{Sergey Merzlikin: smsoft@chat.ru}
section_heading_record_type = record
Name : array [ 0 .. 15 ] of char ; {ASCIZ name of the section}
NextHdOfs : word ; {Offset of heading of the next section}
{from the beginning of the file}
NextDataOfs : word ; {Offset of heading of the section data}
{from the beginning of the file}
Len : word ; {Section data length}
end ;
section_heading_record_ref_type = ^ section_heading_record_type ;
windows_386_section_type = packed record
MaxMem : word ; {Max amount of conventional memory in KB (0280h)}
ReqMem : word ; {Required amount of conventional memory in KB}
ActivePriority : word ; {0064h}
BackgroundPriority : word ; {0032h}
MaxEMS : word ; {Max amount of EMS memory in KB}
{FFFFh in 32-bit OS, 0400h in Windows 3.x}
ReqEMS : word ;
MaxXMS : word ; {Max amount of XMS memory in KB}
{FFFFh in 32-bit OS, 0400h in Windows 3.x}
ReqXMS : word ;
Flags1 : longint ;
{00000001h Permit an exit when is active}
{default 00021002h}
{00000002h Continuation of work in background}
{00000004h Exclusive run mode}
{00000008h Full screen mode}
{00000020h not use Alt+Tab}
{00000040h not use Alt+Esc}
{00000080h not use Alt+Space}
{00000100h not use Alt+Enter}
{00000200h not use Alt+PrtScr}
{00000400h not use PrtScr}
{00000800h not use Ctrl+Esc}
{00001000h Detect idle time}
{00002000h Not use HMA}
{00004000h Use shortcut key}
{00008000h EMS memory is locked}
{00010000h XMS memory is locked}
{00020000h Use fast paste}
{00040000h Lock application memory}
{00080000h Memory protection}
{00100000h Minimized windows}
{00200000h Maximized windows}
{00800000h MS-DOS mode}
{01000000h Prevent Windows detection}
{04000000h Not auto offer transition in a MS_DOS mode}
{10000000h Not warn before transition in a MS_DOS mode}
Flags2 : word ; {0001h Video ROM emulation}
{default 0001Fh}
{0002h Do not check ports: text}
{0004h Do not check ports: low graphics}
{0008h Do not check ports: high graphics}
{0010h Video memory: text}
{0020h Video memory: low graphics}
{0040h Video memory: high graphics}
{0080h Retain video memory}
ScanCode : word ; {Scan code of a shortcut key}
Modifier : word ; {0003h Shortcut key modifier: Shift}
{0004h Shortcut key modifier: Ctrl}
{0008h Shortcut key modifier: Alt}
Shortcut : word ; {000Fh Use shortcut key}
Extended : word ; {0001h The shortcut key scan code is extended}
Unknown1 : word ; {0000h, 0064h in Windows NT}
Unknown2 : word ; {0000h, 0032h in Windows NT}
Unknown3 : array [ 1 .. 6 ] of byte ;
Params : array [ 0 .. 63 ] of char ; {Parameters string}
end ;
windows_vmm_section_type = packed record
Unknown : array [ 1 .. 88 ] of byte ;
IconFile : array [ 0 .. 79 ] of char ; {Name of the file containing an icon}
IconNo : word ; {Number of an icon}
Flags1 : word ; {0002h Continue run in background mode}
{0010h Not warn on exit}
{0020h Disallow Screen Saver}
Unknown2 : array [ 1 .. 10 ] of byte ;
Priority : word ; {0032h}
Flags2 : word ; {0001h Video-ROM emulation}
{0080h Do not dynamically allocate video memory}
{0100h Full-screen mode}
Unknown3 : array [ 1 .. 8 ] of byte ;
NoLines : word ; {Number of text lines in a window}
Flags3 : word ; {0001h Fast paste}
{0020h Not use Alt+Tab}
{0040h Not use Alt+Esc}
{0080h Not use Alt+Space}
{0100h Not use Alt+Enter}
{0200h Not use Alt+PrtSc}
{0400h Not use PrtSc}
{0800h Not use Ctrl+Esc}
Unknown4 : array [ 1 .. 16 ] of byte ;
Flags4 : word ; {0001h Not use the mouse for selection}
{0002h Exclusive use of the mouse}
Unknown5 : array [ 1 .. 6 ] of byte ;
Flags5 : word ; {0004h Use raster fonts}
{0008h Use TrueType fonts}
{0010h Automatically choose the font size}
{0400h The current font is raster}
{0800h The current font is TruType}
Unknown6 : array [ 1 .. 2 ] of byte ;
rHorSize : word ; {Horizontal size of the current raster font}
rVertSize : word ; {Vertical size of the current raster font}
HorSize : word ; {Horizontal size of the current font}
VertSize : word ; {Vertical size of the current font}
rFontName : array [ 0 .. 31 ] of char ; {The name of a raster font}
FontName : array [ 0 .. 31 ] of char ; {The name of a TrueType font}
Unknown7 : array [ 1 .. 2 ] of byte ; {04e3h in Windows NT/2000}
Flags6 : word ; {0001h Unknown}
{0002h Show toolbar}
Flags7 : word ; {0001h Not restore settings at startup}
Cols : word ;
Rows : word ;
ClientHorSize : word ;
ClientVertSize : word ;
WindowHorSize : word ;
WindowVertSize : word ;
Unknown8 : array [ 1 .. 2 ] of byte ; {0016h}
Flags8 : word ; {0002h At last start the windows was maximized}
Flags9 : word ; {0001h At last start the windows was of the normal size}
{0002h At last start the windows was minimized}
{0003h At last start the windows was maximized}
Unknown9 : array [ 1 .. 4 ] of byte ; {FFFFFFFFh}
Right : word ; {The right window border position in maximized window}
Bottom : word ; {The bottom window border position in maximized window}
Left : word ; {The left window border position in maximized window}
Top : word ; {The top window border position in maximized window}
nRight : word ; {The right window border position in normal window}
nBottom : word ; {The bottom window border position in normal window}
Unknown10 : array [ 1 .. 4 ] of byte ; {00000000h}
BatFile : array [ 0 .. 79 ] of char ;
EnvMem : word ; {Memory amount for environment}
DPMIMem : word ; {Volume of memory DPMI}
Unknown11 : word ; {0001h}
end ;
windows_vmm_section_ref_type = ^ windows_vmm_section_type ;
{Ralf Brown interrupt list 6.1}
{Sergey Merzlikin: smsoft@chat.ru}
pif_record_type = packed record
Reserved : byte ;
CheckSum : byte ; {of bytes 02h through 170h; default=78h}
Title : array [ 1 .. 30 ] of char ; {blank-padded window title}
MaxMem : word ; {maximum memory to allocate to partition in KB}
{0280h in 32-bit OS, 0080h in Windows 3.x}
MinMem : word ; {minimum memory required in KB}
FileName : array [ 0 .. 62 {!} ] of char ; {ASCIZ program filename w/o params}
Flags1 : word ; {0001h Directly modify memory}
{0002h Graphics/Multiple text}
{0004h Prevent program switch}
{0008h No screen exchange}
{0010h Close windows on exit}
{0040h Direct interact with COM1}
{0080h Direct interact with COM2}
DefDir : array [ 0 .. 63 ] of char ; {ASCIZ default directory name}
Params : array [ 0 .. 63 ] of char ; {ASCIZ program parameters}
VideoMode : byte ; {initial video mode (also see offset 189h)}
{ 00h in 32-bit OS, 7Fh in others }
NoTextPg : byte ; {number of text pages allocated}
FirstIntr : byte ; {number of first interrupt to save}
LastIntr : byte ; {number of last interrupt to save}
NRows : byte ; {rows in virtual screen buffer}
NCols : byte ; {columns in virtual screen buffer}
InitRow : byte ; {initial window position, row}
InitCol : byte ; {initial window position, column}
Flags2 : word ; {0007h No of last text video page}
{0010h Graphics/Multiple text mode}
SharedName : array [ 0 .. 63 ] of char ; {ASCIZ shared program name}
SharedData : array [ 0 .. 63 ] of char ; {ASCIZ shared program data file}
Flags3 : word ; {0010h Direct interaction with the keyboard}
{0020h Use coprocessor }
{0040h Stop in backgroud mode}
{0080h Directly modify screen}
{2000h Exchange interrupt vectors}
{4000h There are parameters in the cmnd line}
BasicHeading : section_heading_record_type ;
FirstHeading : section_heading_record_type ;
{019Dh First section }
{ Heading of the second section}
{ Second section }
{ ... }
{ Heading of the last section }
{ Last section }
end ;
pif_record_ref_type = ^ pif_record_type ;
const
VIDEO_ROM_EMULATION = $0001 ;
DYN_ALLOC_VIDEO_MEM = $0080 ;
FULL_SCREEN_MODE = $0100 ;
CLOSE_ON_EXIT = $0010 ;
procedure CreateShortcut(const FileName: string; Location: ShortcutType);
{ proc to create a shortcut on the desktop or startmenu }
var
MyObject: IUnknown;
MySLink: IShellLink;
MyPFile: IPersistFile;
Directory: string;
LinkName: string;
IconName: string;
DirName: string;
pifName: WideString;
WFileName: WideString;
QuickLaunchReg: TRegIniFile;
aPidl: PItemIDList;
Res: HResult;
Buf: PByteArray;
PPif: pif_record_ref_type absolute Buf;
Flag: boolean;
i, j: integer;
n: longint;
PHeading: section_heading_record_ref_type;
PVMMSection: windows_vmm_section_ref_type;
PW386Section: ^windows_386_section_type;
f: file;
begin
MyObject := CreateComObject(CLSID_ShellLink);
MySLink := MyObject as IShellLink;
MyPFile := MyObject as IPersistFile;
MySLink.SetPath(PChar(FileName));
LinkName := ChangeFileExt(FileName, '.lnk');
LinkName := ExtractFileName(LinkName);
case Location of
_DESKTOP: Res := SHGetSpecialFolderLocation(
Application.Handle, CSIDL_DESKTOPDIRECTORY, aPidl);
_STARTMENU: Res := SHGetSpecialFolderLocation(
Application.Handle, CSIDL_STARTMENU, aPidl);
_SENDTO: Res := SHGetSpecialFolderLocation(
Application.Handle, CSIDL_SENDTO, aPidl);
_QUICKLAUNCH: Res := 0;
end; { Location }
if Res <> NOERROR then
begin
case Location of
_DESKTOP: Directory := 'ShellFolders->Desktop';
_STARTMENU: Directory := 'ShellFolders->Start Menu';
_SENDTO: Directory := 'ShellFolders->SendTo';
_QUICKLAUNCH: Directory := 'MapGroups->Quick Launch';
end; { Location }
ShowMessage(Directory + ': Failed');
end { '' }
else
begin
// Get the actual path from the PItemIDList
SetLength(Directory, MAX_PATH);
SHGetPathFromIDList(aPidl, PChar(Directory));
SetLength(Directory, StrLen(PChar(Directory)));
(*****)
WFileName := Directory + '\' + LinkName;
if (Location = _DESKTOP) and (LinkName = 'PAULITA.lnk') then
begin
pifName := ExtractFilePath(FileName);
Res := MyPFile.Load(PWChar(pifName +
'SYS\PauLita.pif'), 0);
if Res = E_OUTOFMEMORY then
ShowMessage('.PIF LOAD: Out of Memory')
else if Res = E_FAIL then
ShowMessage('.PIF LOAD: Failed');
IconName := pifName + 'SYS\PAULITA.ICO';
Res := MySLink.SetIconLocation(PChar(IconName), 0);
if Res <> NOERROR then
ShowMessage('SetIconLocation: Failed');
end; { PauLita }
MySLink.SetPath(PChar(FileName));
DirName := ExtractFilePath(FileName);
DirName := Copy(DirName, 1, Length(DirName) - 1);
MySLink.SetWorkingDirectory(PChar(DirName));
Res := MyPFile.Save(PWChar(WFileName), FALSE);
if Res <> S_OK then
ShowMessage('Save ' + WFileName + ' Failed');
{-----------}
if (Location = _DESKTOP) and (LinkName = 'PAULITA.lnk') then
begin
Buf := nil;
Assign(f, Directory + '\PAULITA.PIF');
try
Reset(f, 1);
n := FileSize(f);
GetMem(Buf, n);
BlockRead(f, Buf^, n);
PW386Section := nil;
Flag := FALSE;
i := $187;
while i + SizeOf(section_heading_record_type) <= n do
begin
PHeading := @Buf^[i];
{ShowMessage( PHeading^.Name );}
{-Look for WINDOWS 386 3.0 group-}
if StrPas(@PHeading^.Name) = 'WINDOWS 386 3.0' then
begin
PW386Section := @Buf^[i +
SizeOf(section_heading_record_type)];
end;
{-Look for WINDOWS VMM 4.0 group-}
if StrPas(@PHeading^.Name) = 'WINDOWS VMM 4.0' then
begin
Flag := TRUE;
Break;
end;
i := i + SizeOf(section_heading_record_type) +
PHeading^.Len;
end; { <=n }
if not Flag then
begin
ShowMessage('WINDOWS VMM 4.0 not Found in
'+Directory + ' \PAULITA.PIF' );
end
else
begin
Flag := FALSE;
if (PPif^.Flags1 and CLOSE_ON_EXIT) = $0000 then
begin
PPif^.Flags1 := PPif^.Flags1 or CLOSE_ON_EXIT;
Flag := TRUE;
end;
j := Pos('PAULITA.EXE', PPif^.FileName);
if j > 0 then
begin
StrPCopy(PPif^.FileName, Copy(
StrPas(@PPif^.FileName), 1, j - 1) + 'LITA.BAT'#0);
Flag := TRUE;
end;
if PW386Section <> nil then
begin
if (PW386Section^.Flags1 and $00000008) = $0000 then
begin
{Used} PW386Section^.Flags1 := PW386Section^.Flags1
or $00000008; {Full screen mode}
Flag := TRUE;
end;
if (PW386Section^.MaxEMS <> $FFFF) or
(PW386Section^.ReqEMS <> $0000)
or (PW386Section^.MaxXMS <> $FFFF) or
(PW386Section^.ReqXMS <> $0000) then
begin
PW386Section^.MaxEMS := $FFFF;
PW386Section^.ReqEMS := $0000;
PW386Section^.MaxXMS := $FFFF;
PW386Section^.ReqXMS := $0000;
Flag := TRUE;
end;
end; { <>NIL }
PVMMSection := @Buf^[i +
SizeOf(section_heading_record_type)];
if (PVMMSection^.Flags2 and FULL_SCREEN_MODE) =
$0000 then
begin
{Not used} PVMMSection^.Flags2 := PVMMSection^.Flags2 or
FULL_SCREEN_MODE;
Flag := TRUE;
end;
if Flag then
begin
Seek(f, 0);
BlockWrite(f, Buf^, n);
end; { Flag }
end; { Flag }
finally
Close(f);
if Buf <> nil then
FreeMem(Buf, n);
end;
end; { PauLita }
{--}
end; { Directory<>'' }
end; { CreateShortcut }