TwitterTwitter FacebookFacebook FlickrFlickr RSSRSS

20071013

Reference link: http://www.zend.com/forums/index.php?t=msg&S=9af35135701c2c5503e06156dee05a15&th=2970&goto=8121

After spending an entire day trying to figure out how to get ZS to work with SVN repo that i got from my hosting service, i finally found a solution.
I figure this should save some of you from the same "fun" i had to go through.
Chances are that you are reading this either because you tried clicking 'Check Out' from Tools->Subversion and you got a weird error message or when you attempt to check out, it tries to connect and hangs.

Applications you need:
PuTTY, Pageant, Plink, PuTTyGen

I will go over all steps, so feel free to skip ahead.
All 4 apps are made by the same person (group of people) and are available for download for free from:
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.h tml

PuTTY is your basic terminal emulator application. You use it to connect to telnet/ssh servers. At this point you really shouldn't need an explanation as to what putty does.
Plink is "putty in batch mode". it will not give you a nice window you can use to interact with the server. instead you can specify which commands it should execute when you run it and it will output the result in the command prompt window...STDOUT
Pageant and PuttyGen deal with public/private keys.
Puttygen will generate keys and Pageant will provide key info to putty/plink upon connection.

The way SVN+SSH works is that SVN opens a tunnel using SSH and then just sends all commands and data over it.

I would suggest you to save the 3 apps (putty, puttygen, pageant) somewhere in the default %PATH%, (e.g.: c:windows) so that you can run them from anywhere, including Start->Run

1. Download PuTTY, Pageant, Plink, PuTTyGen
2. Copy (Move) plink.exe to C:Program FilesZendZendStudio-5.5.0binSourceControlsvn
3. Rename plink.exe to ssh.exe
4. [In Putty] Connect to your server
5. you need to generate a public/private key pair. Enter: (without $)
$ ssh-keygen -b 1024 -t dsa -N <passphrase> -f key
Where <passphrase> should be some password/secret word/bla (doesn't have to be the same as your server password)
Running that command will generate 2 files, key and key.pub
file key has the private key and file key.pub has the public key
6. $ mkdir ~/.ssh
This line assumes that the currently logged-in username is the one that will be used for SVN connections
7. $ cp key.pub ~/.ssh/authorized_keys
You can close putty for now.
8. use some FTP/SFTP client to download the key (not key.pub) file to your local computer
9. Run PuttyGen
10. In PuttyGen click Conversions->Import Key
11. Browse to the key file you have just downloaded
12. Enter the passphrase you have specified
13. Click "Save Private Key"
PuttyGen will offer you to browse to a location to save the new .ppk (putty private key) file. Save it as whatever you want. You can close Puttygen -- you won't need it for now.
14. Run Pageant -- it will place itself into the system tray
15. Open Pageant window and click 'Add Key'
16. Browse for the .ppk file you've just created
17. Enter the same passphrase as you used before
There now should be a new entry in Pageant list.
You can close Pageant window.

You can now either jump into ZS, or keep reading...
If you want to make it easier to connect to your SVN repo so that you dont have to enter the full address _every time_ you can save the connection info.
1. open putty
2. Enter the following (in corresponding fields):
Session->Host Name: hostname/ip of the server
Session->Saved Sessions: some connection identifier ("my_svn" ?)
Data->Auto-login username: your username
3. Go back to Sessions and hit 'Save'
You can close Putty now
4. Now, in ZS Subversion connection window, all you need to enter is
Module URL: svn+ssh://my_svn/path/to/repo
(This line assumes that you have saved the connection info in putty as "my_svn")
you dont need to enter username, password, etc.
Just hit OK and you are ready to kick as$ and chew bubble gum.
If you are wondering how does ZS know about your putty settings -- recall that you downloaded Plink into the zs main dir. all putty-related applications (which plink is one of) share preferences, profiles, and connection settings.

Something to keep in mind:
Pageant must be running and it must have the key information. Each time you start Pageant, you have to re-add the key.
Pageant will not only let you use the whole SVN+SSH in ZS, but also youll be able to connect to the server in putty without having to enter the password, so don't leave your station unattended or your fancy new php project might start outputting "all your base are belong to us -- crash override/zero cool"

I hope you'll find this doc useful.

PS: let me know if i missed something in the doc.

HOW-TO: Using SVN+SSH in Zend Studio 5.5

Reference link: http://www.zend.com/forums/index.php?t=msg&goto=8129&S=65463b1107074808159b0e05ef46b1ab

It's not very friendly for Zend Studio to using SVN with SSH+SVN scheme. I found this link is useful with that.

  1. Copy (Move) plink.exe to C:Program FilesZendZendStudio-5.5.0binSourceControlsvn
  2. Rename plink.exe to ssh.exe
  3. Run Pageant -- it will place itself into the system tray
  4. Open Pageant window and click 'Add Key'
  5. Browse for the .ppk file you've just created
  6. Enter the same passphrase as you used before


SVN - SSH connection produces errors

Article #201
Product: Zend Studio

http://www.zend.com/support/knowledgebase.php?kbid=201&view_only=1

Summary




When trying to connect to SVN using SSH, this error shows:
svn: Can't create tunnel: The system cannot find the file specified.

Resolution




Please follow this procedure:

1. Download and installed the TortoiseSVN client for Windows.

2. Set the following environment variable (by right-clicking on My Computer, Properties, Advanced, Environment Variables, New)

Variable name: SVN_SSH
Variable value: C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe
in some versins you will need to set this value:
Variable value : C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe -ssh

3. Reboot your machine.

4. Launch ZDE again and try to svn+ssh

The information in this article applies to




Zend Studio Client.

Keywords




svn, ssh, error, ZDE, Studio, tunnel

AIX開發環境介紹
2006-03-05 12:14:04 作者:秦寶軍 來自:http://www-900.ibm.com

隨 著IBM pSeries服務器市場佔有率的不斷增加,AIX操作系統也為越來越多的IT業者所喜愛。AIX作為UNIX家族中出色的一員,有著豐富的開發環境, AIX最新的版本為AIX 5L版本2,最常見的版本為4.3.3,以5L版本為例,缺省安裝直接支持J2EE,這裡主要介紹AIX系統的C/C++開發部分。

首先 應當清楚,AIX並不集成C/C++,要使用這部分功能,必須安裝IBM C或者Visual Age C++(包含C編譯器),這篇文章只介紹Visual Age C++,將按照Visual Age C++的安裝、配置、編譯器的使用、程序調試的順序介紹,使用的平台為AIX 5L。

安裝Visual Age C++

Visual Age C++要在AIX 5L上使用,最低的版本為5.0.2,最新的版本為6.0。Visual Age C++是一個功能強大的集成開發環境,和Windows平台的Visual C++一樣,從項目的管理、編輯、編譯、調試等各方面,提供一系列完善的圖形化的操作界面。要完全安裝(包含IDE圖形界面)Visual Age C++,可遵循以下步驟:

1) 確定IDE圖形界面需要的Motif文件集已經安裝,命令如下:
lslpp -l X11.compat.adt.Motif12
如沒有安裝,應先從AIX操作系統安裝介質安裝這一文件集。

2) 將Visual Age C++的安裝介質放入機器的光驅中
注意,如果是Visual Age C++的產品盤,並不需要mount CD盤

3) 開始安裝Visual Age C++文件集,命令如下:smitty install_latest
安裝目錄選擇光區,使用F4鍵選擇,如下,
回車後將顯示如下界面:

顯示結果

如需要選擇安裝部分文件集,可在_all_latest菜單項下按F4鍵,使用F7鍵選擇要安裝的文件集,按回車鍵即可。

上面介紹的是是一種完整的安裝方式,如果只是使用C/C++的編譯器,不許要安裝Visual Age C++的圖形界面,可借助於下面的命令:

installp -aXgd /dev/cd0 vacpp.cmp

這條命令的運行結果是安裝我們需要的所有文件集。

配置Visual Age C++

正確安裝完Visual Age C++以後,還不能立刻使用,需要配置使用許可才可以正確使用。Visual Age C++的使用許可通過LUM(License Use Management)系統管理,所以正確的配置方法是先配置LUM服務器,再配置Visual Age C++的使用許可。

第一步:配置LUM

LUM在AIX 4.3.3及5L版本中是一個必須的部件,系統的初始安裝過程中已經安裝,但是並沒有配置,使用i4cfg命令配置,如下:

# cd /usr/opt/ifor/bin
# ./i4cfg -a n -S a

這條命令將配置LUM成為併發的節點鎖定服務器工作方式(Concurrent Nodelock Server),如果沒有錯誤輸出,下一步是啟動LUM服務器:

# ./i4cfg -start

之後,可以用以下命令檢測LUM服務器的工作狀態:

# ./i4cfg -list

將顯示為:

顯示結果

第二步:配置Visual Age C++的使用許可

正確安裝Visual Age C++產品以後,可以在/usr/vac和/usr/vacpp兩個目錄下看到後綴為lic的文件,這些文件記載了Visual Age C++的使用許可協議,需要做的就是將需要的許可協議添加到LUM的管理中。使用的命令為i4blt,使用方法為:

i4blt -a -f license_file_name -R u -T license_num

具體過程如下:
首先添加C的使用許可,
#cd /usr/opt/ifor/bin
#./i4blt -a -f /usr/vac/cforaix_cn.lic -R u -T 10
然後再配置C++的使用許可,
#./i4blt -a -f /usr/vacpp/vacpp_cn.lic -R u -T 10

在上面的例子中配置的許可數為10,正確的配置完後可通過如下命令驗證許可數是否正確或許可協議有沒有正確的被添加,

i4blt -sl cn

注意以上的配置是在AIX 5L版本上進行的,如在AIX 4.3.3版本上,則i4cfg、i4blt命令存在/var/ifor/bin目錄下。

Visual Age C++的使用

安裝、配置以後,可以使用C/C++編譯器了,但當你運行cc時卻發現,cc沒有找到,不必懷疑安裝的正確性,這是沒有設置環境變量的緣故,在/usr/vac/bin目錄下有一個腳本文件replaceCSET,它會完成這一切。

可以用一個經典的小程序hello.c來測試一下編譯器的正確性,程序內容如下:

#include <stdio.h>
main() {
printf("Hello!n");
}

編譯、連接:

cc -o hello hello.c

將生成hello可執行程序。

一般情況下,我們習慣直接使用cc編譯程序,實際上AIX的C/C++編譯器還提供了其他的使用方法,如後綴為_r就有xlc_r、xlC_r,這裡我們做一個完整的介紹。

AIX平台上缺省的C++編譯器為xlC,而C的編譯器有三個:

cc: 這是最習慣用的,擴展模式的C編譯器
xlc: ANSI C編譯器,使用UNIX的頭文件
c89: ANSI C編譯器,使用ANSI頭文件

具體選擇何種編譯器,需根據程序的情況來選擇,一般我們可以使用cc。另外,還有一些後綴供我們選擇,結合以上的基本編譯器,給我們提供了更大的選擇範圍,如下:

_r
連接UNIX98標準線程庫
_r4
連接POSIX Draft4(DCE)標準線程庫
_r7
連接POSIX Draft7標準線程庫
128
Double型類型為128位並使用連接相關的庫
128_r
Double類型為128位並使用UNIX98線程庫
128_r4
Double類型為128為並使用連接POSIX Draft4線程庫
128_r7
Double類型為128位並使用連接POSIX Draft7線程庫

另外,UNIX98已經兼容涵蓋了UNIX95、POSIX標準的內容,所以,如果程序中使用到線程函數,只許增加後綴_r就可以了。舉例說,編譯連接ANSI C並使用POSIX線程庫,可以使用xlc_r編譯器,當然也可以使用xlc -lpthread的形式。

這裡提到的只是最基本的東西,還有很多方面的內容並沒有介紹到,例如如何生成使用動態庫,這些更詳細的東西需要參考相關的手冊,或撥打IBM技術支持電話尋求技術支持。

程序調試

調試程序比較複雜,一方面需要我們借助一些調試工具,如dbx 、truss、tprof等,另一方面也需要我們具有一些調試經驗。

這裡介紹一個用dbx調試運行中的程序的方法,重點在於調試步驟,而不在於dbx工具的使用,以一個簡單的程序為例,程序為:

#include <stdio.h>
main() {
long count=0;
int loop_count;

while(1) {
count *= (count++);
printf(" Test debug, count : %ldn", count);
for (loop_count = 0; loop_count < 10; loop_count++) {
sleep(1);
}
}
}

程序名為dbg.c

調試步驟如下:
1) 編譯dbg.c
xlc -g -o dbg dbg.c

2) 運行dgb程序
./dbg

3) 查看dbg程序的進程ID
ps -ef | grep dbg | grep -v grep
假設dbg的PID為12345

4) 調試dbg程序
dbx -a 12345

5) 這時我們運行dbx的命令調試dbg程序了,下面是幾個常用的命令:
step : 單步運行
stop at line_number : 在某一行設置斷點
stop in subroutine_name: 設置斷點到某一個函數
cont : 繼續運行

6) 退出調試

注意退出時應使用detach而不是exit,否則會影響程序的運行,導致程序退出。

這篇文章只是簡單介紹AIX的開發環境,實際工作中用到的內容將遠遠不止這些知識,需要開發者查閱大量的相關資料,或訪問以下網址:

http://www-900.ibm.com/developerWorks/cn/index.shtml

Microsoft公司 .CAB文件格式

_Inside Windows Cabinet Files_

Listing One
// =================================================================
// CAB FILE LAYOUT
// =================================================================
/*
(1) CAB_HEADER structure
(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE
(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)
(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)
(9) File data (offset = CAB_FOLDER.coffCabStart)
*/

// =================================================================
// MACROS
// =================================================================
#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))
#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) |
(SWAPWORD ((WORD) ((x) >> 16))))


// =================================================================
// CONSTANTS
// =================================================================
#define CAB_SIGNATURE SWAPDWORD ('MSCF')
#define CAB_VERSION 0x0103

#define CAB_FLAG_HASPREV 0x0001
#define CAB_FLAG_HASNEXT 0x0002
#define CAB_FLAG_RESERVE 0x0004

#define CAB_ATTRIB_READONLY 0x0001
#define CAB_ATTRIB_HIDDEN 0x0002
#define CAB_ATTRIB_SYSTEM 0x0004
#define CAB_ATTRIB_VOLUME 0x0008
#define CAB_ATTRIB_DIRECTORY 0x0010
#define CAB_ATTRIB_ARCHIVE 0x0020

#define CAB_FILE_FIRST 0x0000
#define CAB_FILE_NEXT 0x0001
#define CAB_FILE_SPLIT 0xFFFE
#define CAB_FILE_CONTINUED 0xFFFD

#define CAB_NOTIFY_OK 1
#define CAB_NOTIFY_ERROR 0
#define CAB_NOTIFY_SKIP 0
#define CAB_NOTIFY_ABORT (-1)

// =================================================================
// CABINET STRUCTURES
// =================================================================
typedef struct _CAB_HEADER
{
DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE)
DWORD csumHeader; // header checksum (0 if not used)
DWORD cbCabinet; // cabinet file size
DWORD csumFolders; // folders checksum (0 if not used)
DWORD coffFiles; // offset of first CAB_ENTRY
DWORD csumFiles; // files checksum (0 if not used)
WORD version; // cabinet version (CAB_VERSION)
WORD cFolders; // number of folders
WORD cFiles; // number of files
WORD flags; // cabinet flags (CAB_FLAG_*)
WORD setID; // cabinet set id
WORD iCabinet; // zero-based cabinet number
}
CAB_HEADER, *PCAB_HEADER;
#define CAB_HEADER_ sizeof (CAB_HEADER)

// -----------------------------------------------------------------
typedef struct _CAB_FOLDER
{
DWORD coffCabStart; // offset of folder data
WORD cCFData; // ???
WORD typeCompress; // compression type (tcomp* in FDI.h)

}
CAB_FOLDER, *PCAB_FOLDER;
#define CAB_FOLDER_ sizeof (CAB_FOLDER)

// -----------------------------------------------------------------
typedef struct _CAB_ENTRY
{
DWORD cbFile; // uncompressed file size
DWORD uoffFolderStart; // file offset after decompression
WORD iFolder; // file control id (CAB_FILE_*)
WORD date; // file date stamp, as used by DOS
WORD time; // file time stamp, as used by DOS
WORD attribs; // file attributes (CAB_ATTRIB_*)
}
CAB_ENTRY, *PCAB_ENTRY;
#define CAB_ENTRY_ sizeof (CAB_ENTRY)


Listing Two
// =================================================================
// FILE EXTRACTION CALLBACK
// =================================================================
int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint,
PFDINOTIFICATION pfdin)
{
FILETIME ft, lft;
BYTE abFile [MAX_PATH];
int hf, iResult;

switch (fdint)
{
case fdintCOPY_FILE:
if (lstrcmpi (pfdin->psz1,
((PEXTRACT_FILE) pfdin->pv)->pbEntry))
{
iResult = CAB_NOTIFY_SKIP;
}
else
{
hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile,
_O_RDWR | _O_CREAT | _O_TRUNC,
_S_IREAD | _S_IWRITE);
if (hf != -1)
{
iResult = hf;
}
else
{
printfMessage
(((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to create file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
iResult = CAB_NOTIFY_ABORT;

}
}
break;
case fdintNEXT_CABINET:
if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1)
< MAX_PATH)
{
lstrcpy (abFile, pfdin->psz3);
lstrcat (abFile, pfdin->psz1);
hf = FDIOpen (abFile, _O_RDONLY, 0);
}
else
{
hf = -1;
}
if (hf != -1)
{
FDIClose (hf);
iResult = CAB_NOTIFY_OK;
}
else
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to open file "%s%s"",
pfdin->psz3,
pfdin->psz1);
iResult = CAB_NOTIFY_ABORT;
}
break;
case fdintCLOSE_FILE_INFO:
DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft);
LocalFileTimeToFileTime (&lft, &ft);
SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);

if (FDIClose (pfdin->hf) == -1)
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to close file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
}
iResult = CAB_NOTIFY_OK;
break;
default:
iResult = CAB_NOTIFY_OK;
break;
}
return iResult;
}


Example 1:
HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc,
PFNFREE pfnfree,
PFNOPEN pfnopen,
PFNREAD pfnread,
PFNWRITE pfnwrite,
PFNCLOSE pfnclose,
PFNSEEK pfnseek,
int cpuType,
PERF perf);

Example 2:
BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi,
char FAR *pszCabinet,
char FAR *pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void FAR *pvUser);



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503223

Microsoft公司 .CAB文件格式

_Inside Windows Cabinet Files_

Listing One
// =================================================================
// CAB FILE LAYOUT
// =================================================================
/*
(1) CAB_HEADER structure
(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE
(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)
(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)
(9) File data (offset = CAB_FOLDER.coffCabStart)
*/

// =================================================================
// MACROS
// =================================================================
#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))
#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) |
(SWAPWORD ((WORD) ((x) >> 16))))


// =================================================================
// CONSTANTS
// =================================================================
#define CAB_SIGNATURE SWAPDWORD ('MSCF')
#define CAB_VERSION 0x0103

#define CAB_FLAG_HASPREV 0x0001
#define CAB_FLAG_HASNEXT 0x0002
#define CAB_FLAG_RESERVE 0x0004

#define CAB_ATTRIB_READONLY 0x0001
#define CAB_ATTRIB_HIDDEN 0x0002
#define CAB_ATTRIB_SYSTEM 0x0004
#define CAB_ATTRIB_VOLUME 0x0008
#define CAB_ATTRIB_DIRECTORY 0x0010
#define CAB_ATTRIB_ARCHIVE 0x0020

#define CAB_FILE_FIRST 0x0000
#define CAB_FILE_NEXT 0x0001
#define CAB_FILE_SPLIT 0xFFFE
#define CAB_FILE_CONTINUED 0xFFFD

#define CAB_NOTIFY_OK 1
#define CAB_NOTIFY_ERROR 0
#define CAB_NOTIFY_SKIP 0
#define CAB_NOTIFY_ABORT (-1)

// =================================================================
// CABINET STRUCTURES
// =================================================================
typedef struct _CAB_HEADER
{
DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE)
DWORD csumHeader; // header checksum (0 if not used)
DWORD cbCabinet; // cabinet file size
DWORD csumFolders; // folders checksum (0 if not used)
DWORD coffFiles; // offset of first CAB_ENTRY
DWORD csumFiles; // files checksum (0 if not used)
WORD version; // cabinet version (CAB_VERSION)
WORD cFolders; // number of folders
WORD cFiles; // number of files
WORD flags; // cabinet flags (CAB_FLAG_*)
WORD setID; // cabinet set id
WORD iCabinet; // zero-based cabinet number
}
CAB_HEADER, *PCAB_HEADER;
#define CAB_HEADER_ sizeof (CAB_HEADER)

// -----------------------------------------------------------------
typedef struct _CAB_FOLDER
{
DWORD coffCabStart; // offset of folder data
WORD cCFData; // ???
WORD typeCompress; // compression type (tcomp* in FDI.h)

}
CAB_FOLDER, *PCAB_FOLDER;
#define CAB_FOLDER_ sizeof (CAB_FOLDER)

// -----------------------------------------------------------------
typedef struct _CAB_ENTRY
{
DWORD cbFile; // uncompressed file size
DWORD uoffFolderStart; // file offset after decompression
WORD iFolder; // file control id (CAB_FILE_*)
WORD date; // file date stamp, as used by DOS
WORD time; // file time stamp, as used by DOS
WORD attribs; // file attributes (CAB_ATTRIB_*)
}
CAB_ENTRY, *PCAB_ENTRY;
#define CAB_ENTRY_ sizeof (CAB_ENTRY)


Listing Two
// =================================================================
// FILE EXTRACTION CALLBACK
// =================================================================
int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint,
PFDINOTIFICATION pfdin)
{
FILETIME ft, lft;
BYTE abFile [MAX_PATH];
int hf, iResult;

switch (fdint)
{
case fdintCOPY_FILE:
if (lstrcmpi (pfdin->psz1,
((PEXTRACT_FILE) pfdin->pv)->pbEntry))
{
iResult = CAB_NOTIFY_SKIP;
}
else
{
hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile,
_O_RDWR | _O_CREAT | _O_TRUNC,
_S_IREAD | _S_IWRITE);
if (hf != -1)
{
iResult = hf;
}
else
{
printfMessage
(((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to create file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
iResult = CAB_NOTIFY_ABORT;

}
}
break;
case fdintNEXT_CABINET:
if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1)
< MAX_PATH)
{
lstrcpy (abFile, pfdin->psz3);
lstrcat (abFile, pfdin->psz1);
hf = FDIOpen (abFile, _O_RDONLY, 0);
}
else
{
hf = -1;
}
if (hf != -1)
{
FDIClose (hf);
iResult = CAB_NOTIFY_OK;
}
else
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to open file "%s%s"",
pfdin->psz3,
pfdin->psz1);
iResult = CAB_NOTIFY_ABORT;
}
break;
case fdintCLOSE_FILE_INFO:
DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft);
LocalFileTimeToFileTime (&lft, &ft);
SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);

if (FDIClose (pfdin->hf) == -1)
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to close file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
}
iResult = CAB_NOTIFY_OK;
break;
default:
iResult = CAB_NOTIFY_OK;
break;
}
return iResult;
}


Example 1:
HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc,
PFNFREE pfnfree,
PFNOPEN pfnopen,
PFNREAD pfnread,
PFNWRITE pfnwrite,
PFNCLOSE pfnclose,
PFNSEEK pfnseek,
int cpuType,
PERF perf);

Example 2:
BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi,
char FAR *pszCabinet,
char FAR *pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void FAR *pvUser);



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503223

Microsoft公司 .CAB文件格式

_Inside Windows Cabinet Files_

Listing One
// =================================================================
// CAB FILE LAYOUT
// =================================================================
/*
(1) CAB_HEADER structure
(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE
(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)
(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)
(9) File data (offset = CAB_FOLDER.coffCabStart)
*/

// =================================================================
// MACROS
// =================================================================
#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))
#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) |
(SWAPWORD ((WORD) ((x) >> 16))))


// =================================================================
// CONSTANTS
// =================================================================
#define CAB_SIGNATURE SWAPDWORD ('MSCF')
#define CAB_VERSION 0x0103

#define CAB_FLAG_HASPREV 0x0001
#define CAB_FLAG_HASNEXT 0x0002
#define CAB_FLAG_RESERVE 0x0004

#define CAB_ATTRIB_READONLY 0x0001
#define CAB_ATTRIB_HIDDEN 0x0002
#define CAB_ATTRIB_SYSTEM 0x0004
#define CAB_ATTRIB_VOLUME 0x0008
#define CAB_ATTRIB_DIRECTORY 0x0010
#define CAB_ATTRIB_ARCHIVE 0x0020

#define CAB_FILE_FIRST 0x0000
#define CAB_FILE_NEXT 0x0001
#define CAB_FILE_SPLIT 0xFFFE
#define CAB_FILE_CONTINUED 0xFFFD

#define CAB_NOTIFY_OK 1
#define CAB_NOTIFY_ERROR 0
#define CAB_NOTIFY_SKIP 0
#define CAB_NOTIFY_ABORT (-1)

// =================================================================
// CABINET STRUCTURES
// =================================================================
typedef struct _CAB_HEADER
{
DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE)
DWORD csumHeader; // header checksum (0 if not used)
DWORD cbCabinet; // cabinet file size
DWORD csumFolders; // folders checksum (0 if not used)
DWORD coffFiles; // offset of first CAB_ENTRY
DWORD csumFiles; // files checksum (0 if not used)
WORD version; // cabinet version (CAB_VERSION)
WORD cFolders; // number of folders
WORD cFiles; // number of files
WORD flags; // cabinet flags (CAB_FLAG_*)
WORD setID; // cabinet set id
WORD iCabinet; // zero-based cabinet number
}
CAB_HEADER, *PCAB_HEADER;
#define CAB_HEADER_ sizeof (CAB_HEADER)

// -----------------------------------------------------------------
typedef struct _CAB_FOLDER
{
DWORD coffCabStart; // offset of folder data
WORD cCFData; // ???
WORD typeCompress; // compression type (tcomp* in FDI.h)

}
CAB_FOLDER, *PCAB_FOLDER;
#define CAB_FOLDER_ sizeof (CAB_FOLDER)

// -----------------------------------------------------------------
typedef struct _CAB_ENTRY
{
DWORD cbFile; // uncompressed file size
DWORD uoffFolderStart; // file offset after decompression
WORD iFolder; // file control id (CAB_FILE_*)
WORD date; // file date stamp, as used by DOS
WORD time; // file time stamp, as used by DOS
WORD attribs; // file attributes (CAB_ATTRIB_*)
}
CAB_ENTRY, *PCAB_ENTRY;
#define CAB_ENTRY_ sizeof (CAB_ENTRY)


Listing Two
// =================================================================
// FILE EXTRACTION CALLBACK
// =================================================================
int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint,
PFDINOTIFICATION pfdin)
{
FILETIME ft, lft;
BYTE abFile [MAX_PATH];
int hf, iResult;

switch (fdint)
{
case fdintCOPY_FILE:
if (lstrcmpi (pfdin->psz1,
((PEXTRACT_FILE) pfdin->pv)->pbEntry))
{
iResult = CAB_NOTIFY_SKIP;
}
else
{
hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile,
_O_RDWR | _O_CREAT | _O_TRUNC,
_S_IREAD | _S_IWRITE);
if (hf != -1)
{
iResult = hf;
}
else
{
printfMessage
(((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to create file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
iResult = CAB_NOTIFY_ABORT;

}
}
break;
case fdintNEXT_CABINET:
if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1)
< MAX_PATH)
{
lstrcpy (abFile, pfdin->psz3);
lstrcat (abFile, pfdin->psz1);
hf = FDIOpen (abFile, _O_RDONLY, 0);
}
else
{
hf = -1;
}
if (hf != -1)
{
FDIClose (hf);
iResult = CAB_NOTIFY_OK;
}
else
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to open file "%s%s"",
pfdin->psz3,
pfdin->psz1);
iResult = CAB_NOTIFY_ABORT;
}
break;
case fdintCLOSE_FILE_INFO:
DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft);
LocalFileTimeToFileTime (&lft, &ft);
SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);

if (FDIClose (pfdin->hf) == -1)
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to close file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
}
iResult = CAB_NOTIFY_OK;
break;
default:
iResult = CAB_NOTIFY_OK;
break;
}
return iResult;
}


Example 1:
HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc,
PFNFREE pfnfree,
PFNOPEN pfnopen,
PFNREAD pfnread,
PFNWRITE pfnwrite,
PFNCLOSE pfnclose,
PFNSEEK pfnseek,
int cpuType,
PERF perf);

Example 2:
BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi,
char FAR *pszCabinet,
char FAR *pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void FAR *pvUser);



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503223

Microsoft公司 .CAB文件格式

_Inside Windows Cabinet Files_

Listing One
// =================================================================
// CAB FILE LAYOUT
// =================================================================
/*
(1) CAB_HEADER structure
(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE
(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)
(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)
(9) File data (offset = CAB_FOLDER.coffCabStart)
*/

// =================================================================
// MACROS
// =================================================================
#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))
#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) |
(SWAPWORD ((WORD) ((x) >> 16))))


// =================================================================
// CONSTANTS
// =================================================================
#define CAB_SIGNATURE SWAPDWORD ('MSCF')
#define CAB_VERSION 0x0103

#define CAB_FLAG_HASPREV 0x0001
#define CAB_FLAG_HASNEXT 0x0002
#define CAB_FLAG_RESERVE 0x0004

#define CAB_ATTRIB_READONLY 0x0001
#define CAB_ATTRIB_HIDDEN 0x0002
#define CAB_ATTRIB_SYSTEM 0x0004
#define CAB_ATTRIB_VOLUME 0x0008
#define CAB_ATTRIB_DIRECTORY 0x0010
#define CAB_ATTRIB_ARCHIVE 0x0020

#define CAB_FILE_FIRST 0x0000
#define CAB_FILE_NEXT 0x0001
#define CAB_FILE_SPLIT 0xFFFE
#define CAB_FILE_CONTINUED 0xFFFD

#define CAB_NOTIFY_OK 1
#define CAB_NOTIFY_ERROR 0
#define CAB_NOTIFY_SKIP 0
#define CAB_NOTIFY_ABORT (-1)

// =================================================================
// CABINET STRUCTURES
// =================================================================
typedef struct _CAB_HEADER
{
DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE)
DWORD csumHeader; // header checksum (0 if not used)
DWORD cbCabinet; // cabinet file size
DWORD csumFolders; // folders checksum (0 if not used)
DWORD coffFiles; // offset of first CAB_ENTRY
DWORD csumFiles; // files checksum (0 if not used)
WORD version; // cabinet version (CAB_VERSION)
WORD cFolders; // number of folders
WORD cFiles; // number of files
WORD flags; // cabinet flags (CAB_FLAG_*)
WORD setID; // cabinet set id
WORD iCabinet; // zero-based cabinet number
}
CAB_HEADER, *PCAB_HEADER;
#define CAB_HEADER_ sizeof (CAB_HEADER)

// -----------------------------------------------------------------
typedef struct _CAB_FOLDER
{
DWORD coffCabStart; // offset of folder data
WORD cCFData; // ???
WORD typeCompress; // compression type (tcomp* in FDI.h)

}
CAB_FOLDER, *PCAB_FOLDER;
#define CAB_FOLDER_ sizeof (CAB_FOLDER)

// -----------------------------------------------------------------
typedef struct _CAB_ENTRY
{
DWORD cbFile; // uncompressed file size
DWORD uoffFolderStart; // file offset after decompression
WORD iFolder; // file control id (CAB_FILE_*)
WORD date; // file date stamp, as used by DOS
WORD time; // file time stamp, as used by DOS
WORD attribs; // file attributes (CAB_ATTRIB_*)
}
CAB_ENTRY, *PCAB_ENTRY;
#define CAB_ENTRY_ sizeof (CAB_ENTRY)


Listing Two
// =================================================================
// FILE EXTRACTION CALLBACK
// =================================================================
int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint,
PFDINOTIFICATION pfdin)
{
FILETIME ft, lft;
BYTE abFile [MAX_PATH];
int hf, iResult;

switch (fdint)
{
case fdintCOPY_FILE:
if (lstrcmpi (pfdin->psz1,
((PEXTRACT_FILE) pfdin->pv)->pbEntry))
{
iResult = CAB_NOTIFY_SKIP;
}
else
{
hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile,
_O_RDWR | _O_CREAT | _O_TRUNC,
_S_IREAD | _S_IWRITE);
if (hf != -1)
{
iResult = hf;
}
else
{
printfMessage
(((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to create file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
iResult = CAB_NOTIFY_ABORT;

}
}
break;
case fdintNEXT_CABINET:
if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1)
< MAX_PATH)
{
lstrcpy (abFile, pfdin->psz3);
lstrcat (abFile, pfdin->psz1);
hf = FDIOpen (abFile, _O_RDONLY, 0);
}
else
{
hf = -1;
}
if (hf != -1)
{
FDIClose (hf);
iResult = CAB_NOTIFY_OK;
}
else
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to open file "%s%s"",
pfdin->psz3,
pfdin->psz1);
iResult = CAB_NOTIFY_ABORT;
}
break;
case fdintCLOSE_FILE_INFO:
DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft);
LocalFileTimeToFileTime (&lft, &ft);
SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);

if (FDIClose (pfdin->hf) == -1)
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to close file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
}
iResult = CAB_NOTIFY_OK;
break;
default:
iResult = CAB_NOTIFY_OK;
break;
}
return iResult;
}


Example 1:
HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc,
PFNFREE pfnfree,
PFNOPEN pfnopen,
PFNREAD pfnread,
PFNWRITE pfnwrite,
PFNCLOSE pfnclose,
PFNSEEK pfnseek,
int cpuType,
PERF perf);

Example 2:
BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi,
char FAR *pszCabinet,
char FAR *pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void FAR *pvUser);



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503223

Microsoft公司 .CAB文件格式

_Inside Windows Cabinet Files_

Listing One
// =================================================================
// CAB FILE LAYOUT
// =================================================================
/*
(1) CAB_HEADER structure
(2) Reserved area, if CAB_HEADER.flags & CAB_FLAG_RESERVE
(3) Previous cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(4) Previous disk name, if CAB_HEADER.flags & CAB_FLAG_HASPREV
(5) Next cabinet name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(6) Next disk name, if CAB_HEADER.flags & CAB_FLAG_HASNEXT
(7) CAB_FOLDER structures (n = CAB_HEADER.cFolders)
(8) CAB_ENTRY structures / file names (n = CAB_HEADER.cFiles)
(9) File data (offset = CAB_FOLDER.coffCabStart)
*/

// =================================================================
// MACROS
// =================================================================
#define SWAPWORD(x) ((WORD) (((x) << 8) | ((x) >> 8)))
#define SWAPDWORD(x) ((SWAPWORD ((WORD) (x)) << 16) |
(SWAPWORD ((WORD) ((x) >> 16))))


// =================================================================
// CONSTANTS
// =================================================================
#define CAB_SIGNATURE SWAPDWORD ('MSCF')
#define CAB_VERSION 0x0103

#define CAB_FLAG_HASPREV 0x0001
#define CAB_FLAG_HASNEXT 0x0002
#define CAB_FLAG_RESERVE 0x0004

#define CAB_ATTRIB_READONLY 0x0001
#define CAB_ATTRIB_HIDDEN 0x0002
#define CAB_ATTRIB_SYSTEM 0x0004
#define CAB_ATTRIB_VOLUME 0x0008
#define CAB_ATTRIB_DIRECTORY 0x0010
#define CAB_ATTRIB_ARCHIVE 0x0020

#define CAB_FILE_FIRST 0x0000
#define CAB_FILE_NEXT 0x0001
#define CAB_FILE_SPLIT 0xFFFE
#define CAB_FILE_CONTINUED 0xFFFD

#define CAB_NOTIFY_OK 1
#define CAB_NOTIFY_ERROR 0
#define CAB_NOTIFY_SKIP 0
#define CAB_NOTIFY_ABORT (-1)

// =================================================================
// CABINET STRUCTURES
// =================================================================
typedef struct _CAB_HEADER
{
DWORD sig; // file signature 'MSCF' (CAB_SIGNATURE)
DWORD csumHeader; // header checksum (0 if not used)
DWORD cbCabinet; // cabinet file size
DWORD csumFolders; // folders checksum (0 if not used)
DWORD coffFiles; // offset of first CAB_ENTRY
DWORD csumFiles; // files checksum (0 if not used)
WORD version; // cabinet version (CAB_VERSION)
WORD cFolders; // number of folders
WORD cFiles; // number of files
WORD flags; // cabinet flags (CAB_FLAG_*)
WORD setID; // cabinet set id
WORD iCabinet; // zero-based cabinet number
}
CAB_HEADER, *PCAB_HEADER;
#define CAB_HEADER_ sizeof (CAB_HEADER)

// -----------------------------------------------------------------
typedef struct _CAB_FOLDER
{
DWORD coffCabStart; // offset of folder data
WORD cCFData; // ???
WORD typeCompress; // compression type (tcomp* in FDI.h)

}
CAB_FOLDER, *PCAB_FOLDER;
#define CAB_FOLDER_ sizeof (CAB_FOLDER)

// -----------------------------------------------------------------
typedef struct _CAB_ENTRY
{
DWORD cbFile; // uncompressed file size
DWORD uoffFolderStart; // file offset after decompression
WORD iFolder; // file control id (CAB_FILE_*)
WORD date; // file date stamp, as used by DOS
WORD time; // file time stamp, as used by DOS
WORD attribs; // file attributes (CAB_ATTRIB_*)
}
CAB_ENTRY, *PCAB_ENTRY;
#define CAB_ENTRY_ sizeof (CAB_ENTRY)


Listing Two
// =================================================================
// FILE EXTRACTION CALLBACK
// =================================================================
int DIAMONDAPI FDIExtract (FDINOTIFICATIONTYPE fdint,
PFDINOTIFICATION pfdin)
{
FILETIME ft, lft;
BYTE abFile [MAX_PATH];
int hf, iResult;

switch (fdint)
{
case fdintCOPY_FILE:
if (lstrcmpi (pfdin->psz1,
((PEXTRACT_FILE) pfdin->pv)->pbEntry))
{
iResult = CAB_NOTIFY_SKIP;
}
else
{
hf = FDIOpen (((PEXTRACT_FILE) pfdin->pv)->pbFile,
_O_RDWR | _O_CREAT | _O_TRUNC,
_S_IREAD | _S_IWRITE);
if (hf != -1)
{
iResult = hf;
}
else
{
printfMessage
(((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to create file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
iResult = CAB_NOTIFY_ABORT;

}
}
break;
case fdintNEXT_CABINET:
if (lstrlen (pfdin->psz3) + lstrlen (pfdin->psz1)
< MAX_PATH)
{
lstrcpy (abFile, pfdin->psz3);
lstrcat (abFile, pfdin->psz1);
hf = FDIOpen (abFile, _O_RDONLY, 0);
}
else
{
hf = -1;
}
if (hf != -1)
{
FDIClose (hf);
iResult = CAB_NOTIFY_OK;
}
else
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to open file "%s%s"",
pfdin->psz3,
pfdin->psz1);
iResult = CAB_NOTIFY_ABORT;
}
break;
case fdintCLOSE_FILE_INFO:
DosDateTimeToFileTime (pfdin->date, pfdin->time, &lft);
LocalFileTimeToFileTime (&lft, &ft);
SetFileTime ((HANDLE) pfdin->hf, &ft, &ft, &ft);

if (FDIClose (pfdin->hf) == -1)
{
printfMessage (((PEXTRACT_FILE) pfdin->pv)->hWnd,
MB_ICONERROR | MB_OK,
"CabLib Error",
"Unable to close file "%s"",
((PEXTRACT_FILE) pfdin->pv)->pbFile);
}
iResult = CAB_NOTIFY_OK;
break;
default:
iResult = CAB_NOTIFY_OK;
break;
}
return iResult;
}


Example 1:
HFDI FAR DIAMONDAPI FDICreate (PFNALLOC pfnalloc,
PFNFREE pfnfree,
PFNOPEN pfnopen,
PFNREAD pfnread,
PFNWRITE pfnwrite,
PFNCLOSE pfnclose,
PFNSEEK pfnseek,
int cpuType,
PERF perf);

Example 2:
BOOL FAR DIAMONDAPI FDICopy (HFDI hfdi,
char FAR *pszCabinet,
char FAR *pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void FAR *pvUser);



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503223

OLE2 File Format



We use DFVIEW.EXE to show OLE2 file structure.



w97waz-c.vot id dumped as an example, It contains several data folder and documents ,In OLE2 jargon, data folder is called ‘Data Storage’, document is called ‘Data Stream’ .

File header information





[0000H-0003H] OLE2 File signature
“D0 CF 11 E0” Look like “DOCFILE”

[0030H-0033H] Root Entry Cluster NO.#
Address = (NO.+1) * 200H = (21H+1) * 200H = 4400H
[Go to Root Entry Address]

[0038H-003BH] Use Small FAT system on data stream below this size
Check Size = 1000H Bytes

[003CH-003FH] Small FAT system FAT Table entry cluster NO.#
Address = (NO.+1) * 200H = (23H+1) * 200H = 4800H
[Go to Small FAT Table Address]

[0044H-0047H] Second Big FAT Index Table entry cluster
if first Big FAT Index Table is exhausted
¡Muse the second one (not use second Big FAT index Table in this example)

[004CH-01FFH] First Big FAT Index Table
4 bytes as a unit, from offset 004CH to 01FFH, there are 6DH units, each unit contains a entry cluster # , it pointer to a Big FAT Table .

[004CH-004FH] First Big FAT Table entry cluster NO.#
Address = (NO.+1) * 200H = (20H+1) * 200H = 4200H
[Go to First Big FAT Table Address]

BIG FAT Table




Example: FCB link

1. From File header information wegot FCB Root Entry cluster NO.=21H

  1. To find the cluster link list of FCB from Big FAT Table:
    Next link address = Big FAT Table Start Address + Offset
    Offset = NO.* 4

    F
    irst cluster NO. = 21H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    21H*4 =
    4284H) , [4284H] = 22H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    22H*4 =
    4288H) , [4288H] = 26H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    26H*4 = 4298H) , [4298] = 34H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    34H*4 = 42D0H) , [42D0] = NIL
    There are 4 clusters

  2. In Big FAT Table every link points to a 200H bytes Big Cluster

  3. Compute addresses of the clusters by {Big Cluster address = (NO.+1) * 200H }

  4. FCB size = 80H , Big Cluster size = 200H
    One cluster contains 4 FCB, numbered from 0 , In this example, we have at most 16 FCB, number from 0 to 0FH, the last cluster may have < 4 FCBs
    [Go to FCB NO.
    #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 #A #B #C #D]

By applying this rule, we can find the Cluster link list of FCB link or Data stream link from FAT Table if we know its Entry Cluster NO.#

Big FAT Table (For Small FAT example)




Small FAT Table




Example: Data stream [autoOpen]

  1. By FCB #8 we know data stream [autoOpen] of data stream total length = 0A24His less than 1000H bytes, so we have to use Small FAT system;

  2. In Small FAT Table every Link points to a 40H bytes sCluster (Small Cluster), So the original Big Cluster size = 200H bytes can contains 8 sCluster(size = 40H bytes)

  3. For convenient we call
    Big Cluster (Size 200H bytes) = bCluster
    Small Cluster (Size 40H bytes) = sCluster

  4. From offset 74H of Root Entry , we have Entry bCluster NO. of sCluster #0 = 24H
    Entry Address = (NO.+1) * 200H = (24H + 1) * 200H = 4A00H
    So the 200H bytes from offset 4A00H contains sCluster NO.#0 ~ #7
    [Go to Small Cluster NO.#0-#7]

  5. By Big FAT Table to find bCluster link lists starting from bCluster NO.#24H, each bCluter contains 8 sCluster
    Next link address = Big FAT Table Start Address + Offset
    Offset = NO.* 4

    First cluster NO. = 24H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    24H*4 = 4290H) , [4290H] = 25H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    25H*4 = 4294H) , [4294H] = 27H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    27H*4 = 429CH) , [429CH] = 28H
    :
    Next link cluster NO. = The contains of Next link address
    (4200H+
    33H*4 = 42CCH) , [42CCH] = 35H
    Next link cluster NO. = The contains of Next link address
    (4200H+
    35H*4 = 42D4) , [42D4H] = NIL
    There are 17 Big Cluster

  6. One bCluster contains 8 sCluster , numbered sCluster from 0, this number we called sCluster NO.

  7. By FCB #8 can know , data stream [autoOpen] of data entry Small Cluster NO.=10H
    Use
    Small FAT Table find out data stream [autoOpen] of small cluster link list
    Next link address = Small FAT Start Address + Offset
    Offset = NO.* 4

    First small cluster NO. = 10H
    Next link small cluster NO. = The contains of Next link address
    (4800H+10H*4 = 4840H) , [4840H] = 11H

    Next link small cluster NO. = The contains of Next link address
    (4800H+
    11H*4 = 4844H) , [4844H] = 12H
    Next link small cluster NO. = The contains of Next link address
    (4800H+
    12H*4 = 4848H) , [4848H] = 13H
    :
    Next link small cluster NO. = The contains of Next link address
    (4800H+
    37H*4 = 489CH) , [48DCH] = 38H
    Next link small cluster NO. = The contains of Next link address
    (4800H+
    38H*4 = 48E0H) , [48E0H] = NIL
    There are 41 Small Cluster

  8. Compute Small cluster NO. Owner of Big Cluster NO. (Reference step 4 , step 5 )

  9. Small cluster address
    = [(Owner Big_cluster_NO + 1)* 200H] + [(Small_cluster_NO. MOD 8) * 40H]
    = [(27H + 1)*200H] + [(10H MOD 8) * 40H] = 5000H


By applying this rule, we can find the Small Cluster link list of data stream if we know its Entry Small Cluster NO.#

FCB Directory link

OLE2 File have tree view directory structure Each FCB use Offset 44H,48H,4CH to do store Left Link, Right Link, Child Link, Use these information link all FCB together¡C

Example "w9cwaz-c.vot” Directory link diagram(click mouse button to get more information)

FCB #0 #1 #2




FCB #3 #4 #5





FCB #6 #7




FCB #8 #9 #0AH




FCB #0BH




FCB #0CH #0DH




Small Cluster NO.#0 - #7





NIL Pointer

FCB link NO. = FF FF FF FF , FCB link terminal

Data stream length

Data stream total bytes

Data stream entry cluster NO.#

Data stream entry address = (NO.+ 1) * 200H

FCB – Storage or Stream name length

OLE2 Storage or Stream Name support Unicode, so a character need 2 bytes

FCB – Data stream total length

If stream data total length more then 1000H bytes OLE2 use Big FAT else use Small FAT

FCB – Data stream entry cluster NO.#

If use Big FAT

Data stream entry address = (NO. + 1) * 200H

If use Small FAT

Reference Small FAT Table

 
PUMA螢光夜跑